]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/UpLoad.php
Allow uploading and displaying inline SVG images
[SourceForge/phpwiki.git] / lib / plugin / UpLoad.php
1 <?php // -*-php-*-
2 rcs_id('$Id$');
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
20  * along with PhpWiki; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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:   <?plugin 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     var $disallowed_extensions;
40     // TODO: use PagePerms instead
41     var $only_authenticated = true; // allow only authenticated users may upload.
42
43     function getName () {
44         return "UpLoad";
45     }
46
47     function getDescription () {
48         return _("Upload files to the local InterWiki Upload:<filename>");
49     }
50
51     function getVersion() {
52         return preg_replace("/[Revision: $]/", '',
53                             "\$Revision$");
54     }
55
56     function getDefaultArguments() {
57         return array('logfile'  => 'phpwiki-upload.log',
58                      // add a link of the fresh file automatically to the 
59                      // end of the page (or current page)
60                      'autolink' => true, 
61                      'page'     => '[pagename]',
62                      'size'     => 50,
63                      'mode'     => 'actionpage', // or edit
64                      );
65     }
66
67     function run($dbi, $argstr, &$request, $basepage) {
68         $this->allowed_extensions = explode("\n",
69 "7z
70 avi
71 bmp
72 bz2
73 c
74 cfg
75 diff
76 doc
77 docx
78 flv
79 gif
80 h
81 ics
82 ini
83 jpeg
84 jpg
85 kmz
86 mp3
87 odg
88 odp
89 ods
90 odt
91 ogg
92 patch
93 pdf
94 png
95 ppt
96 pptx
97 rar
98 svg
99 tar
100 tar.gz
101 txt
102 xls
103 xlsx
104 xml
105 xsd
106 zip");
107         $this->disallowed_extensions = explode("\n",
108 "ad[ep]
109 asd
110 ba[st]
111 chm
112 cmd
113 com
114 cgi
115 cpl
116 crt
117 dll
118 eml
119 exe
120 hlp
121 hta
122 in[fs]
123 isp
124 jse?
125 lnk
126 md[betw]
127 ms[cipt]
128 nws
129 ocx
130 ops
131 pcd
132 p[ir]f
133 php\d?
134 phtml
135 pl
136 py
137 reg
138 sc[frt]
139 sh[bsm]?
140 swf
141 url
142 vb[esx]?
143 vxd
144 ws[cfh]");
145         //removed "\{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\}"
146
147         $args = $this->getArgs($argstr, $request);
148         extract($args);
149
150         $file_dir = getUploadFilePath();
151         $file_dir .= "/";
152         $form = HTML::form(array('action'  => $request->getPostURL(),
153                                  'enctype' => 'multipart/form-data',
154                                  'method'  => 'post'));
155         $contents = HTML::div(array('class' => 'wikiaction'));
156         $contents->pushContent(HTML::input(array('type' => 'hidden',
157                                                  'name' => 'MAX_FILE_SIZE',
158                                                  'value'=> MAX_UPLOAD_SIZE)));
159         $contents->pushContent(HTML::input(array('name' => 'userfile',
160                                                  'type' => 'file',
161                                                  'size' => $size)));
162         if ($mode == 'edit') {
163             $contents->pushContent(HTML::input(array('name' => 'action',
164                                                      'type' => 'hidden',
165                                                      'value'=> 'edit')));
166             $contents->pushContent(HTML::raw(" "));
167             $contents->pushContent(HTML::input(array('value' => _("Upload"),
168                                                      'name'  => 'edit[upload]',
169                                                      'type'  => 'submit')));
170         } else {
171             $contents->pushContent(HTML::raw(" "));
172             $contents->pushContent(HTML::input(array('value' => _("Upload"),
173                                                      'type'  => 'submit')));
174         }
175         $form->pushContent($contents);
176
177         $message = HTML();
178         if ($request->isPost() and $this->only_authenticated) {
179             // Make sure that the user is logged in.
180             $user = $request->getUser();
181             if (!$user->isAuthenticated()) {
182                 if (defined('GFORGE') and GFORGE) {
183                     $message->pushContent(HTML::div(array('class' => 'error'),
184                                             HTML::p(_("You cannot upload files.")),
185                                             HTML::ul(
186                                               HTML::li(_("Check you are logged in.")),
187                                               HTML::li(_("Check you are in the right project.")),
188                                               HTML::li(_("Check you are a member of the current project."))
189                                             )
190                                          ));
191                 } else {
192                     $message->pushContent(HTML::div(array('class' => 'error'),
193                                             HTML::p(_("ACCESS DENIED: You must log in to upload files."))));
194                 }
195                 $result = HTML();
196                 $result->pushContent($form);
197                 $result->pushContent($message);
198                 return $result;
199             }
200         }
201         
202         $userfile = $request->getUploadedFile('userfile');
203         if ($userfile) {
204             $userfile_name = $userfile->getName();
205             $userfile_name = trim(basename($userfile_name));
206             if (UPLOAD_USERDIR) {
207                 $file_dir .= $request->_user->_userid;
208                 if (!file_exists($file_dir))
209                     mkdir($file_dir, 0775);
210                 $file_dir .= "/";
211                 $u_userfile = $request->_user->_userid . "/" . $userfile_name;
212             } else {
213                 $u_userfile = $userfile_name;
214             }
215             $u_userfile = preg_replace("/ /", "%20", $u_userfile);
216             $userfile_tmpname = $userfile->getTmpName();
217             $err_header = HTML::div(array('class' => 'error'),
218                                 HTML::p(fmt("ERROR uploading '%s'", $userfile_name)));
219             if (preg_match("/(\." . join("|\.", $this->disallowed_extensions) . ")(\.|\$)/i",
220                            $userfile_name))
221             {
222                 $message->pushContent($err_header);
223                 $message->pushContent(HTML::p(fmt("Files with extension %s are not allowed.",
224                                               join(", ", $this->disallowed_extensions))));
225             }
226             elseif (! DISABLE_UPLOAD_ONLY_ALLOWED_EXTENSIONS and 
227                     ! preg_match("/(\." . join("|\.", $this->allowed_extensions) . ")\$/i", 
228                                $userfile_name))
229             {
230                 $message->pushContent($err_header);
231                 $message->pushContent(HTML::p(fmt("Only files with the extension %s are allowed.",
232                                               join(", ", $this->allowed_extensions))));
233             }
234             elseif (preg_match("/[^._a-zA-Z0-9- ]/", strip_accents($userfile_name)))
235             {
236                 $message->pushContent($err_header);
237                 $message->pushContent(HTML::p(_("Invalid filename. File names may only contain alphanumeric characters and dot, underscore, space or dash.")));
238             }
239             elseif (file_exists($file_dir . $userfile_name)) {
240                 $message->pushContent($err_header);
241                 $message->pushContent(HTML::p(fmt("There is already a file with name %s uploaded.",
242                                                   $u_userfile)));
243             }
244             elseif ($userfile->getSize() > (MAX_UPLOAD_SIZE)) {
245                 $message->pushContent($err_header);
246                 $message->pushContent(HTML::p(_("Sorry but this file is too big.")));
247             }
248             elseif (move_uploaded_file($userfile_tmpname, $file_dir . $userfile_name) or
249                     (IsWindows() and rename($userfile_tmpname, $file_dir . $userfile_name))
250                     )
251             {
252                 $interwiki = new PageType_interwikimap();
253                 $link = $interwiki->link("Upload:$u_userfile");
254                 $message->pushContent(HTML::div(array('class' => 'feedback'),
255                                                 HTML::p(_("File successfully uploaded.")),
256                                                 HTML::p($link)));
257
258                 // the upload was a success and we need to mark this event in the "upload log"
259                 if ($logfile) { 
260                     $upload_log = $file_dir . basename($logfile);
261                     $this->log($userfile, $upload_log, $message);
262                 }
263                 if ($autolink) {
264                     require_once("lib/loadsave.php");
265                     $pagehandle = $dbi->getPage($page);
266                     if ($pagehandle->exists()) {// don't replace default contents
267                         $current = $pagehandle->getCurrentRevision();
268                         $version = $current->getVersion();
269                         $text = $current->getPackedContent();
270                         $newtext = $text . "\n* Upload:$u_userfile"; // don't inline images
271                         $meta = $current->_data;
272                         $meta['summary'] = sprintf(_("uploaded %s"),$u_userfile);
273                         $pagehandle->save($newtext, $version + 1, $meta);
274                     }
275                 }
276             } else {
277                 $message->pushContent($err_header);
278                 $message->pushContent(HTML::br(),_("Uploading failed."),HTML::br());
279             }
280         }
281         else {
282             $message->pushContent(HTML::br(),_("No file selected. Please select one."),HTML::br());
283         }
284
285         //$result = HTML::div( array( 'class' => 'wikiaction' ) );
286         $result = HTML();
287         $result->pushContent($form);
288         $result->pushContent($message);
289         return $result;
290     }
291
292     function log ($userfile, $upload_log, &$message) {
293         global $WikiTheme;
294         $user = $GLOBALS['request']->_user;
295         if (file_exists($upload_log) and (!is_writable($upload_log))) {
296             trigger_error(_("The upload logfile exists but is not writable."), E_USER_WARNING);
297         }
298         elseif (!$log_handle = fopen ($upload_log, "a")) {
299             trigger_error(_("Can't open the upload logfile."), E_USER_WARNING);
300         }
301         else {        // file size in KB; precision of 0.1
302             $file_size = round(($userfile->getSize())/1024, 1);
303             if ($file_size <= 0) {
304                 $file_size = "&lt; 0.1";
305             }
306             $userfile_name = $userfile->getName();
307             fwrite($log_handle,
308                    "\n"
309                    . "<tr><td><a href=\"$userfile_name\">$userfile_name</a></td>"
310                    . "<td align=\"right\">$file_size kB</td>"
311                    . "<td>&nbsp;&nbsp;" . $WikiTheme->formatDate(time()) . "</td>"
312                    . "<td>&nbsp;&nbsp;<em>" . $user->getId() . "</em></td></tr>");
313             fclose($log_handle);
314         }
315         return;
316     }
317
318 }
319
320 // (c-file-style: "gnu")
321 // Local Variables:
322 // mode: php
323 // tab-width: 8
324 // c-basic-offset: 4
325 // c-hanging-comment-ender-p: nil
326 // indent-tabs-mode: nil
327 // End:
328 ?>