]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/UpLoad.php
No %20 in file name
[SourceForge/phpwiki.git] / lib / plugin / UpLoad.php
1 <?php
2
3 /*
4  * Copyright 2003,2004,2007 $ThePhpWikiProgrammingTeam
5  * Copyright 2008-2009 Marc-Etienne Vargenau, Alcatel-Lucent
6  *
7  * This file is part of PhpWiki.
8  *
9  * PhpWiki is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * PhpWiki is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23  */
24
25 /**
26  * UpLoad:  Allow Administrator to upload files to a special directory,
27  *          which should preferably be added to the InterWikiMap
28  * Usage:   <<UpLoad >>
29  * Author:  NathanGass <gass@iogram.ch>
30  * Changes: ReiniUrban <rurban@x-ray.at>,
31  *          qubit <rtryon@dartmouth.edu>
32  *          Marc-Etienne Vargenau, Alcatel-Lucent
33  * Note:    See also Jochen Kalmbach's plugin/UserFileManagement.php
34  */
35
36 class WikiPlugin_UpLoad
37     extends WikiPlugin
38 {
39     public $disallowed_extensions;
40     // TODO: use PagePerms instead
41     public $only_authenticated = true; // allow only authenticated users may upload.
42
43     function getDescription()
44     {
45         return _("Upload files to the local InterWiki Upload:<filename>");
46     }
47
48     function getDefaultArguments()
49     {
50         return array('logfile' => 'phpwiki-upload.log',
51             // add a link of the fresh file automatically to the
52             // end of the page (or current page)
53             'autolink' => true,
54             'page' => '[pagename]',
55             'size' => 50,
56             'mode' => 'actionpage', // or edit
57         );
58     }
59
60     function run($dbi, $argstr, &$request, $basepage)
61     {
62         $this->allowed_extensions = explode("\n",
63             "7z
64 avi
65 bmp
66 bz2
67 c
68 cfg
69 diff
70 doc
71 docx
72 flv
73 gif
74 h
75 ics
76 ini
77 jpeg
78 jpg
79 kmz
80 mp3
81 odg
82 odp
83 ods
84 odt
85 ogg
86 patch
87 pdf
88 png
89 ppt
90 pptx
91 rar
92 svg
93 tar
94 tar.gz
95 txt
96 xls
97 xlsx
98 xml
99 xsd
100 zip");
101         $this->disallowed_extensions = explode("\n",
102             "ad[ep]
103 asd
104 ba[st]
105 chm
106 cmd
107 com
108 cgi
109 cpl
110 crt
111 dll
112 eml
113 exe
114 hlp
115 hta
116 in[fs]
117 isp
118 jse?
119 lnk
120 md[betw]
121 ms[cipt]
122 nws
123 ocx
124 ops
125 pcd
126 p[ir]f
127 php\d?
128 phtml
129 pl
130 py
131 reg
132 sc[frt]
133 sh[bsm]?
134 url
135 vb[esx]?
136 vxd
137 ws[cfh]");
138         //removed "\{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\}"
139
140         $args = $this->getArgs($argstr, $request);
141         extract($args);
142
143         $file_dir = getUploadFilePath();
144         $file_dir .= "/";
145         $form = HTML::form(array('action' => $request->getPostURL(),
146             'enctype' => 'multipart/form-data',
147             'method' => 'post'));
148         $contents = HTML::div(array('class' => 'wikiaction'));
149         $contents->pushContent(HTML::input(array('type' => 'hidden',
150             'name' => 'MAX_FILE_SIZE',
151             'value' => MAX_UPLOAD_SIZE)));
152         $contents->pushContent(HTML::input(array('name' => 'userfile',
153             'type' => 'file',
154             'size' => $size)));
155         if ($mode == 'edit') {
156             $contents->pushContent(HTML::input(array('name' => 'action',
157                 'type' => 'hidden',
158                 'value' => 'edit')));
159             $contents->pushContent(HTML::raw(" "));
160             $contents->pushContent(HTML::input(array('value' => _("Upload"),
161                 'name' => 'edit[upload]',
162                 'type' => 'submit')));
163         } else {
164             $contents->pushContent(HTML::raw(" "));
165             $contents->pushContent(HTML::input(array('value' => _("Upload"),
166                 'type' => 'submit')));
167         }
168         $form->pushContent($contents);
169
170         $message = HTML();
171         if ($request->isPost() and $this->only_authenticated) {
172             // Make sure that the user is logged in.
173             $user = $request->getUser();
174             if (!$user->isAuthenticated()) {
175                 if (defined('FUSIONFORGE') and FUSIONFORGE) {
176                     $message->pushContent(HTML::div(array('class' => 'error'),
177                         HTML::p(_("You cannot upload files.")),
178                         HTML::ul(
179                             HTML::li(_("Check you are logged in.")),
180                             HTML::li(_("Check you are in the right project.")),
181                             HTML::li(_("Check you are a member of the current project."))
182                         )
183                     ));
184                 } else {
185                     $message->pushContent(HTML::div(array('class' => 'error'),
186                         HTML::p(_("ACCESS DENIED: You must log in to upload files."))));
187                 }
188                 $result = HTML();
189                 $result->pushContent($form);
190                 $result->pushContent($message);
191                 return $result;
192             }
193         }
194
195         $userfile = $request->getUploadedFile('userfile');
196         if ($userfile) {
197             $userfile_name = $userfile->getName();
198             $userfile_name = trim(basename($userfile_name));
199             if (UPLOAD_USERDIR) {
200                 $file_dir .= $request->_user->_userid;
201                 if (!file_exists($file_dir))
202                     mkdir($file_dir, 0775);
203                 $file_dir .= "/";
204                 $u_userfile = $request->_user->_userid . "/" . $userfile_name;
205             } else {
206                 $u_userfile = $userfile_name;
207             }
208             $u_userfile = preg_replace("/ /", "%20", $u_userfile);
209             $userfile_tmpname = $userfile->getTmpName();
210             $err_header = HTML::div(array('class' => 'error'),
211                 HTML::p(fmt("Error uploading ā€œ%sā€", $userfile_name)));
212             if (preg_match("/(\." . join("|\.", $this->disallowed_extensions) . ")(\.|\$)/i",
213                 $userfile_name)
214             ) {
215                 $err_header->pushContent(HTML::p(fmt("Files with extension %s are not allowed.",
216                     join(", ", $this->disallowed_extensions))));
217                 $message->pushContent($err_header);
218             } elseif (!DISABLE_UPLOAD_ONLY_ALLOWED_EXTENSIONS and
219                 !preg_match("/(\." . join("|\.", $this->allowed_extensions) . ")\$/i",
220                     $userfile_name)
221             ) {
222                 $err_header->pushContent(HTML::p(fmt("Only files with the extension %s are allowed.",
223                     join(", ", $this->allowed_extensions))));
224                 $message->pushContent($err_header);
225             } elseif (preg_match("/[^._a-zA-Z0-9- ]/", strip_accents($userfile_name))) {
226                 $err_header->pushContent(HTML::p(_("Invalid filename. File names may only contain alphanumeric characters and dot, underscore, space or dash.")));
227                 $message->pushContent($err_header);
228             } elseif (file_exists($file_dir . $userfile_name)) {
229                 $err_header->pushContent(HTML::p(fmt("There is already a file with name ā€œ%sā€ uploaded.", $userfile_name)));
230                 $message->pushContent($err_header);
231             } elseif ($userfile->getSize() > (MAX_UPLOAD_SIZE)) {
232                 $err_header->pushContent(HTML::p(_("Sorry but this file is too big.")));
233                 $message->pushContent($err_header);
234             } elseif (move_uploaded_file($userfile_tmpname, $file_dir . $userfile_name) or
235                 (IsWindows() and rename($userfile_tmpname, $file_dir . $userfile_name))
236             ) {
237                 $interwiki = new PageType_interwikimap();
238                 $link = $interwiki->link("Upload:$u_userfile");
239                 $message->pushContent(HTML::div(array('class' => 'feedback'),
240                     HTML::p(_("File successfully uploaded.")),
241                     HTML::p($link)));
242
243                 // the upload was a success and we need to mark this event in the "upload log"
244                 if ($logfile) {
245                     $upload_log = $file_dir . basename($logfile);
246                     $this->log($userfile, $upload_log, $message);
247                 }
248                 if ($autolink) {
249                     require_once 'lib/loadsave.php';
250                     $pagehandle = $dbi->getPage($page);
251                     if ($pagehandle->exists()) { // don't replace default contents
252                         $current = $pagehandle->getCurrentRevision();
253                         $version = $current->getVersion();
254                         $text = $current->getPackedContent();
255                         $newtext = $text . "\n* Upload:$u_userfile"; // don't inline images
256                         $meta = $current->_data;
257                         $meta['summary'] = sprintf(_("uploaded %s"), $u_userfile);
258                         $pagehandle->save($newtext, $version + 1, $meta);
259                     }
260                 }
261             } else {
262                 $err_header->pushContent(HTML::p(_("Uploading failed.")));
263                 $message->pushContent($err_header);
264             }
265         } else {
266             $message->pushContent(HTML::br(), _("No file selected. Please select one."), HTML::br());
267         }
268
269         //$result = HTML::div( array( 'class' => 'wikiaction' ) );
270         $result = HTML();
271         $result->pushContent($form);
272         $result->pushContent($message);
273         return $result;
274     }
275
276     function log($userfile, $upload_log, &$message)
277     {
278         global $WikiTheme;
279         $user = $GLOBALS['request']->_user;
280         if (file_exists($upload_log) and (!is_writable($upload_log))) {
281             trigger_error(_("The upload logfile exists but is not writable."), E_USER_WARNING);
282         } elseif (!$log_handle = fopen($upload_log, "a")) {
283             trigger_error(_("Can't open the upload logfile."), E_USER_WARNING);
284         } else { // file size in KB; precision of 0.1
285             $file_size = round(($userfile->getSize()) / 1024, 1);
286             if ($file_size <= 0) {
287                 $file_size = "&lt; 0.1";
288             }
289             $userfile_name = $userfile->getName();
290             fwrite($log_handle,
291                 "\n"
292                     . "<tr><td><a href=\"$userfile_name\">$userfile_name</a></td>"
293                     . "<td class=\"align-right\">$file_size kB</td>"
294                     . "<td>&nbsp;&nbsp;" . $WikiTheme->formatDate(time()) . "</td>"
295                     . "<td>&nbsp;&nbsp;<em>" . $user->getId() . "</em></td></tr>");
296             fclose($log_handle);
297         }
298         return;
299     }
300 }
301
302 // Local Variables:
303 // mode: php
304 // tab-width: 8
305 // c-basic-offset: 4
306 // c-hanging-comment-ender-p: nil
307 // indent-tabs-mode: nil
308 // End: