4 Copyright 2003,2004,2007 $ThePhpWikiProgrammingTeam
5 Copyright 2008-2009 Marc-Etienne Vargenau, Alcatel-Lucent
7 This file is part of PhpWiki.
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.
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.
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
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
36 class WikiPlugin_UpLoad
39 var $disallowed_extensions;
40 // TODO: use PagePerms instead
41 var $only_authenticated = true; // allow only authenticated users may upload.
47 function getDescription () {
48 return _("Upload files to the local InterWiki Upload:<filename>");
51 function getVersion() {
52 return preg_replace("/[Revision: $]/", '',
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)
61 'page' => '[pagename]',
63 'mode' => 'actionpage', // or edit
67 function run($dbi, $argstr, &$request, $basepage) {
68 $this->allowed_extensions = explode("\n",
103 $this->disallowed_extensions = explode("\n",
141 //removed "\{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\}"
143 $args = $this->getArgs($argstr, $request);
146 $file_dir = getUploadFilePath();
148 $form = HTML::form(array('action' => $request->getPostURL(),
149 'enctype' => 'multipart/form-data',
150 'method' => 'post'));
151 $contents = HTML::div(array('class' => 'wikiaction'));
152 $contents->pushContent(HTML::input(array('type' => 'hidden',
153 'name' => 'MAX_FILE_SIZE',
154 'value'=> MAX_UPLOAD_SIZE)));
155 $contents->pushContent(HTML::input(array('name' => 'userfile',
158 if ($mode == 'edit') {
159 $contents->pushContent(HTML::input(array('name' => 'action',
162 $contents->pushContent(HTML::raw(" "));
163 $contents->pushContent(HTML::input(array('value' => _("Upload"),
164 'name' => 'edit[upload]',
165 'type' => 'submit')));
167 $contents->pushContent(HTML::raw(" "));
168 $contents->pushContent(HTML::input(array('value' => _("Upload"),
169 'type' => 'submit')));
171 $form->pushContent($contents);
174 if ($request->isPost() and $this->only_authenticated) {
175 // Make sure that the user is logged in.
176 $user = $request->getUser();
177 if (!$user->isAuthenticated()) {
179 if (isa($WikiTheme, 'WikiTheme_gforge')) {
180 $message->pushContent(HTML::div(array('class' => 'error'),
181 HTML::p(_("You cannot upload files.")),
183 HTML::li(_("Check you are logged in.")),
184 HTML::li(_("Check you are in the right project.")),
185 HTML::li(_("Check you are a member of the current project."))
189 $message->pushContent(HTML::div(array('class' => 'error'),
190 HTML::p(_("ACCESS DENIED: You must log in to upload files."))));
193 $result->pushContent($form);
194 $result->pushContent($message);
199 $userfile = $request->getUploadedFile('userfile');
201 $userfile_name = $userfile->getName();
202 $userfile_name = trim(basename($userfile_name));
203 if (UPLOAD_USERDIR) {
204 $file_dir .= $request->_user->_userid;
205 if (!file_exists($file_dir))
206 mkdir($file_dir, 0775);
208 $u_userfile = $request->_user->_userid . "/" . $userfile_name;
210 $u_userfile = $userfile_name;
212 $u_userfile = preg_replace("/ /", "%20", $u_userfile);
213 $userfile_tmpname = $userfile->getTmpName();
214 $err_header = HTML::div(array('class' => 'error'),
215 HTML::p(fmt("ERROR uploading '%s'", $userfile_name)));
216 if (preg_match("/(\." . join("|\.", $this->disallowed_extensions) . ")(\.|\$)/i",
219 $message->pushContent($err_header);
220 $message->pushContent(HTML::p(fmt("Files with extension %s are not allowed.",
221 join(", ", $this->disallowed_extensions))));
223 elseif (! DISABLE_UPLOAD_ONLY_ALLOWED_EXTENSIONS and
224 ! preg_match("/(\." . join("|\.", $this->allowed_extensions) . ")\$/i",
227 $message->pushContent($err_header);
228 $message->pushContent(HTML::p(fmt("Only files with the extension %s are allowed.",
229 join(", ", $this->allowed_extensions))));
231 elseif (preg_match("/[^._a-zA-Z0-9- ]/", strip_accents($userfile_name)))
233 $message->pushContent($err_header);
234 $message->pushContent(HTML::p(_("Invalid filename. File names may only contain alphanumeric characters and dot, underscore, space or dash.")));
236 elseif (file_exists($file_dir . $userfile_name)) {
237 $message->pushContent($err_header);
238 $message->pushContent(HTML::p(fmt("There is already a file with name %s uploaded.",
241 elseif ($userfile->getSize() > (MAX_UPLOAD_SIZE)) {
242 $message->pushContent($err_header);
243 $message->pushContent(HTML::p(_("Sorry but this file is too big.")));
245 elseif (move_uploaded_file($userfile_tmpname, $file_dir . $userfile_name) or
246 (IsWindows() and rename($userfile_tmpname, $file_dir . $userfile_name))
249 $interwiki = new PageType_interwikimap();
250 $link = $interwiki->link("Upload:$u_userfile");
251 $message->pushContent(HTML::div(array('class' => 'feedback'),
252 HTML::p(_("File successfully uploaded.")),
255 // the upload was a success and we need to mark this event in the "upload log"
257 $upload_log = $file_dir . basename($logfile);
258 $this->log($userfile, $upload_log, $message);
261 require_once("lib/loadsave.php");
262 $pagehandle = $dbi->getPage($page);
263 if ($pagehandle->exists()) {// don't replace default contents
264 $current = $pagehandle->getCurrentRevision();
265 $version = $current->getVersion();
266 $text = $current->getPackedContent();
267 $newtext = $text . "\n* Upload:$u_userfile"; // don't inline images
268 $meta = $current->_data;
269 $meta['summary'] = sprintf(_("uploaded %s"),$u_userfile);
270 $pagehandle->save($newtext, $version + 1, $meta);
274 $message->pushContent($err_header);
275 $message->pushContent(HTML::br(),_("Uploading failed."),HTML::br());
279 $message->pushContent(HTML::br(),_("No file selected. Please select one."),HTML::br());
282 //$result = HTML::div( array( 'class' => 'wikiaction' ) );
284 $result->pushContent($form);
285 $result->pushContent($message);
289 function log ($userfile, $upload_log, &$message) {
291 $user = $GLOBALS['request']->_user;
292 if (file_exists($upload_log) and (!is_writable($upload_log))) {
293 trigger_error(_("The upload logfile exists but is not writable."), E_USER_WARNING);
295 elseif (!$log_handle = fopen ($upload_log, "a")) {
296 trigger_error(_("Can't open the upload logfile."), E_USER_WARNING);
298 else { // file size in KB; precision of 0.1
299 $file_size = round(($userfile->getSize())/1024, 1);
300 if ($file_size <= 0) {
301 $file_size = "< 0.1";
303 $userfile_name = $userfile->getName();
306 . "<tr><td><a href=\"$userfile_name\">$userfile_name</a></td>"
307 . "<td align=\"right\">$file_size kB</td>"
308 . "<td> " . $WikiTheme->formatDate(time()) . "</td>"
309 . "<td> <em>" . $user->getId() . "</em></td></tr>");
317 // (c-file-style: "gnu")
322 // c-hanging-comment-ender-p: nil
323 // indent-tabs-mode: nil