r104564 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r104563‎ | r104564 | r104565 >
Date:14:45, 29 November 2011
Author:cneubauer
Status:deferred (Comments)
Tags:
Comment:
Committing version 1.1.0 (2008-02-09) of this extension by Edward Z. Yang. See http://www.mediawiki.org/wiki/Extension:SpecialUploadLocal.
Modified paths:
  • /trunk/extensions/SpecialUploadLocal (added) (history)
  • /trunk/extensions/SpecialUploadLocal/SpecialUploadLocal.php (added) (history)
  • /trunk/extensions/SpecialUploadLocal/UploadLocalDirectory.php (added) (history)
  • /trunk/extensions/SpecialUploadLocal/UploadLocalForm.php (added) (history)
  • /trunk/extensions/SpecialUploadLocal/data (added) (history)
  • /trunk/extensions/SpecialUploadLocal/data/.htaccess (added) (history)

Diff [purge]

Index: trunk/extensions/SpecialUploadLocal/SpecialUploadLocal.php
@@ -0,0 +1,91 @@
 2+<?php
 3+
 4+if (!defined('MEDIAWIKI')) die();
 5+
 6+/*
 7+
 8+TODO:
 9+ * Considered more advanced file scanning regexps/recursive searching
 10+ * Allow unzipping without ssh'ing (need a tar library or shell)
 11+ * Migrate repository to Mercurial so we can easily push changes
 12+
 13+BUGS:
 14+ * Figure out how to get image overwrites to work properly or fail gracefully
 15+ * Warn when filename contains ampersand. (Apache doesn't like that)
 16+
 17+ENHANCEMENTS:
 18+ * Mute extra output from the new page function.
 19+ * Remove debugging info.
 20+ * Dry run capability.
 21+
 22+*/
 23+
 24+$wgExtensionFunctions[] = "wfSetupUploadLocal";
 25+$wgExtensionCredits['specialpage'][] = array(
 26+ 'name' => 'UploadLocal',
 27+ 'description' => 'allows users to link in files already on the server'
 28+);
 29+
 30+$wgUploadLocalDirectory = $IP . '/extensions/SpecialUploadLocal/data';
 31+
 32+$wgAvailableRights[] = 'uploadlocal';
 33+$wgGroupPermissions['uploader']['uploadlocal'] = true;
 34+$wgGroupPermissions['sysop'] ['uploadlocal'] = true;
 35+
 36+function wfSetupUploadLocal() {
 37+ require_once( 'SpecialPage.php' );
 38+
 39+ global $wgMessageCache;
 40+
 41+ $messages = array(
 42+ 'uploadlocal' => 'Upload local files'
 43+ ,'uploadlocal_directory_readonly' => 'The local upload directory ($1) is'.
 44+ ' not writeable by the webserver.'
 45+ ,'uploadlocaltext' => 'Use this form to mass upload files already on the'.
 46+ ' server in the upload local directory. You can find out more'.
 47+ ' general information at [[Special:Upload|the regular upload file'.
 48+ ' page]].'
 49+ ,'uploadlocalbtn' => 'Upload local files'
 50+ ,'nolocalfiles' => 'There are no files in the local upload folder. Try'.
 51+ ' placing some files in "<code>$1</code>."'
 52+ ,'uploadednolocalfiles' => 'You did not upload any files.'
 53+ ,'allfilessuccessful' => 'All files uploaded successfully'
 54+ ,'uploadlocalerrors' => 'Some files had errors'
 55+ ,'allfilessuccessfultext' => 'All files uploaded successfully. Return to'.
 56+ ' [[Main Page]].'
 57+ ,'uploadlocal_descriptions_append' => 'Append to description: '
 58+ ,'uploadlocal_descriptions_prepend' => 'Prepend to description: '
 59+ ,'uploadlocal_dest_file_append' => 'Append to dest. filename: '
 60+ ,'uploadlocal_dest_file_prepend' => 'Prepend to dest. filename: '
 61+ ,'uploadlocal_file_list' => 'Files ready for upload'
 62+ ,'uploadlocal_file_list_explanation' => '\'\'\'X\'\'\' indicates'.
 63+ ' whether or not you want the file to be uploaded (uncheck to'.
 64+ ' prevent a file from being processed). \'\'\'W\'\'\' indicates'.
 65+ ' whether you want the file added to your watchlist.'
 66+ ,'uploadlocal_global_params' => 'Global parameters'
 67+ ,'uploadlocal_global_params_explanation' => 'What is entered here will'.
 68+ ' automatically get added to the entries listed above. This helps'.
 69+ ' remove repetitive text such as categories and metadata. To \'\'\''.
 70+ 'append\'\'\' is to add to the end of text, while to \'\'\'prepend'.
 71+ '\'\'\' means to add to the beginning of text. Especially for'.
 72+ ' descriptions, make sure you give a few linebreaks before/after'.
 73+ ' the text.'
 74+ );
 75+ $wgMessageCache->addMessages($messages);
 76+ SpecialPage::addPage( new SpecialPage( 'UploadLocal', 'uploadlocal',
 77+ /*listed*/ true, /*function*/ false, /*file*/ false ) );
 78+
 79+}
 80+
 81+function wfSpecialUploadLocal() {
 82+ global $wgRequest, $wgUploadLocalDirectory, $wgMessageCache;
 83+
 84+ $prefix = 'extensions/SpecialUploadLocal/';
 85+ require($prefix . 'UploadLocalDirectory.php');
 86+ require($prefix . 'UploadLocalForm.php');
 87+
 88+ $directory =& new UploadLocalDirectory($wgRequest, $wgUploadLocalDirectory);
 89+ $directory->execute();
 90+}
 91+
 92+?>
\ No newline at end of file
Property changes on: trunk/extensions/SpecialUploadLocal/SpecialUploadLocal.php
___________________________________________________________________
Added: svn:eol-style
193 + native
Index: trunk/extensions/SpecialUploadLocal/UploadLocalForm.php
@@ -0,0 +1,59 @@
 2+<?php
 3+
 4+require_once('SpecialUpload.php');
 5+
 6+class UploadLocalForm extends UploadForm
 7+{
 8+
 9+ var $_error = '';
 10+ var $_filename;
 11+
 12+ /**
 13+ * With our parameters, simulate a request
 14+ */
 15+ function UploadLocalForm($filename, $description, $watch, $dest) {
 16+ global $wgUploadLocalDirectory;
 17+
 18+ // Prepare our directory
 19+ $dir = $wgUploadLocalDirectory;
 20+ if ($dir[strlen($dir)-1] !== '/') $dir .= '/';
 21+
 22+ // Create faux request object with basic parameters.
 23+ $request = new FauxRequest(array(
 24+ 'wpDestFile' => $dest,
 25+ 'wpIgnoreWarning' => true,
 26+ 'wpUploadDescription' => $description,
 27+ 'wpUpload' => true,
 28+ 'wpWatchthis' => $this->watch,
 29+ ), true);
 30+
 31+ // Instantiate private variables with those values, also note
 32+ // initializeFromUpload() call will fail, but we don't have any
 33+ // way of overriding that, and the failure is silent.
 34+ parent::UploadForm($request);
 35+
 36+ // initializeFromLocalFile() style functionality
 37+ $this->mTempPath = $dir . $filename;
 38+ $this->mFileSize = filesize($dir . $filename);
 39+ $this->mSrcName = $dir . $filename;
 40+ $this->mCurlError = false;
 41+ $this->mSessionKey = false;
 42+ $this->mStashed = false;
 43+ // Our files are not under PHP's jurisdiction, so we need to remove
 44+ // it ourselves.
 45+ $this->mRemoveTempFile = true;
 46+
 47+ }
 48+
 49+ function getFilename() {return $this->_filename;}
 50+ function getUploadSaveName() {return $this->mDesiredDestName;}
 51+
 52+ function mainUploadForm($error) {$this->_error = $error;}
 53+ function uploadError($error) {$this->_error = $error;}
 54+ function showSuccess() {}
 55+
 56+ function getError() {return $this->_error;}
 57+
 58+}
 59+
 60+?>
\ No newline at end of file
Property changes on: trunk/extensions/SpecialUploadLocal/UploadLocalForm.php
___________________________________________________________________
Added: svn:eol-style
161 + native
Index: trunk/extensions/SpecialUploadLocal/data/.htaccess
@@ -0,0 +1 @@
 2+Deny from all
Property changes on: trunk/extensions/SpecialUploadLocal/data/.htaccess
___________________________________________________________________
Added: svn:eol-style
13 + native
Index: trunk/extensions/SpecialUploadLocal/UploadLocalDirectory.php
@@ -0,0 +1,236 @@
 2+<?php
 3+
 4+class UploadLocalDirectory
 5+{
 6+
 7+ var $_directory;
 8+ var $_was_posted;
 9+ var $_available_files;
 10+
 11+ function UploadLocalDirectory($request, $directory) {
 12+ $this->_directory = $directory;
 13+ $this->_was_posted = $request->wasPosted();
 14+ $this->_available_files = $this->getFilenamesOfFilesInDirectory($directory);
 15+ }
 16+
 17+ function execute() {
 18+ global $wgOut, $wgRequest, $wgUser, $wgEnableUploads,
 19+ $wgUploadDirectory;
 20+
 21+ // a bit of this is stolen from the SpecialUpload code, duplication
 22+ // is bad but there was no way to meaningfully integrate it into
 23+ // this code.
 24+
 25+ if( ! $wgEnableUploads ) {
 26+ $wgOut->addWikiText( wfMsg( 'uploaddisabled' ) );
 27+ return;
 28+ }
 29+
 30+ // uses extension specific permission "uploadlocal"
 31+ if (!$wgUser->isAllowed( 'uploadlocal' ) || $wgUser->isBlocked() ) {
 32+ $wgOut->errorpage( 'uploadnologin', 'uploadnologintext' );
 33+ return;
 34+ }
 35+
 36+ if( wfReadOnly() ) {
 37+ $wgOut->readOnlyPage();
 38+ return;
 39+ }
 40+
 41+ // check if both relevant directories are writeable
 42+ if ( !is_writeable( $wgUploadDirectory ) ) {
 43+ $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) );
 44+ return;
 45+ }
 46+ if ( !is_writeable($this->_directory) ) {
 47+ $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $this->_directory ) );
 48+ return;
 49+ }
 50+
 51+ // check if there are any files to upload
 52+ if (empty($this->_available_files)) {
 53+ $wgOut->addWikitext( wfMsg( 'uploadlocaltext' ) );
 54+ $wgOut->addWikitext( wfMsg( 'nolocalfiles', htmlentities($this->_directory) ) );
 55+ return;
 56+ }
 57+
 58+ if ($this->_was_posted) {
 59+ $this->processUploads($wgRequest);
 60+ } else {
 61+ $this->showForm();
 62+ }
 63+
 64+ }
 65+
 66+ function showForm() {
 67+ global $wgOut;
 68+
 69+ $wgOut->addWikitext( wfMsg( 'uploadlocaltext' ) );
 70+
 71+ $titleObj = Title::makeTitle( NS_SPECIAL, 'UploadLocal' );
 72+ $action = $titleObj->escapeLocalURL();
 73+
 74+ $wgOut->addHTML('<form id="uploadlocal" method="post"'.
 75+ ' enctype="multipart/form-data" action="'.$action.'">');
 76+
 77+ $wgOut->addWikitext('==' . wfMsg('uploadlocal_file_list') . '==');
 78+ $wgOut->addWikitext(wfMsg('uploadlocal_file_list_explanation'));
 79+
 80+ $html = '';
 81+
 82+ $html .= '<table border="0" cellspacing="0" style="width:100%;">';
 83+ $html .= '<theader>'.
 84+ '<tr><th style="width:1em;">X</th>'.
 85+ '<th style="width:1em;">W</th>'.
 86+ '<th style="width:10em;text-align:left;">'.wfMsg('sourcefilename').'</th>'.
 87+ '<th style="width:10em;text-align:left;">'.wfMsg('destfilename').'</th>'.
 88+ '<th style="text-align:left;">'.wfMsg('filedesc').'</th></tr></theader>';
 89+ $html .= '<tbody>';
 90+ $i = 1;
 91+ foreach ($this->_available_files as $file) {
 92+ $html_file = htmlentities($file);
 93+ $html .= '<tr' .
 94+ ($i % 2 ? ' style="background-color:#EEE;"' : '') .
 95+ '>'.
 96+ '<td><input type="checkbox" checked="checked"'.
 97+ ' name="wpUploadFiles['.$i.']" value="'.$html_file.'" /></td>'.
 98+ '<td><input type="checkbox" checked="checked"'.
 99+ ' name="wpWatchThese['.$i.']" value="'.$html_file.'" /></td>'.
 100+ '<td>'.$html_file.'</td>'.
 101+ '<td><input type="text" name="wpDestFiles['.$i.']"'.
 102+ ' value="'.$html_file.'" /></td>'.
 103+ '<td style="width:50%;">'.
 104+ '<textarea name="wpUploadDescriptions['.$i.']" cols="60" '.
 105+ 'rows="2" style="width:100%;"></textarea></td>'.
 106+ '</tr>';
 107+ $i++;
 108+ }
 109+ $html .= '</tbody></table>';
 110+
 111+ $wgOut->addHTML($html);
 112+ $wgOut->addWikitext('==' . wfMsg('uploadlocal_global_params') . '==');
 113+ $wgOut->addWikitext(wfMsg('uploadlocal_global_params_explanation'));
 114+ $html = '';
 115+
 116+ $html .= '<table border="0" style="width:100%;">';
 117+ $html .= '<tbody>'.
 118+ '<tr><th style="text-align:right;width:25%;">'.wfMsg('uploadlocal_descriptions_prepend').'</th>'.
 119+ '<td><textarea cols="70" rows="3" style="width:100%;" name="wpUploadDescriptionsPrepend"></textarea></td></tr>'.
 120+
 121+ '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_descriptions_append').'</th>'.
 122+ '<td><textarea cols="70" rows="3" style="width:100%;" name="wpUploadDescriptionsAppend"></textarea></td></tr>'.
 123+
 124+ '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_dest_file_prepend').'</th>'.
 125+ '<td><input type="text" style="width:100%;" name="wpDestFilesPrepend" /></td></tr>'.
 126+
 127+ '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_dest_file_append').'</th>'.
 128+ '<td><input type="text" style="width:100%;" name="wpDestFilesAppend" /></td></tr>'.
 129+
 130+ '</tbody>';
 131+ $html .= '</table>';
 132+
 133+ $html .= '<input type="submit" name="wpUploadLocal" value="'.wfMsg('uploadlocalbtn').'" /></form>';
 134+
 135+ $wgOut->addHTML($html);
 136+ }
 137+
 138+ function getFilenamesOfFilesInDirectory($directory) {
 139+ if (!is_dir($directory)) return array();
 140+ if ($directory[strlen($directory)-1] !== '/') $directory .= '/';
 141+ $dh = opendir($directory);
 142+ $filenames = array();
 143+ while (($file = readdir($dh)) !== false) {
 144+ if ($file == '.' || $file == '..') continue;
 145+ // check if it's a directory
 146+ if (is_dir($directory . $file)) continue;
 147+ // check if it's a hidden file - regexp: /\.[^.]+/
 148+ if ($file[0] == '.' && strpos($file,'.',1) === false) {
 149+ continue;
 150+ }
 151+ $filenames[] = $file;
 152+ }
 153+ closedir($dh);
 154+ return $filenames;
 155+ }
 156+
 157+ function processUploads($request) {
 158+
 159+ global $wgOut, $wgContLang;
 160+
 161+ $r_files = $request->getArray('wpUploadFiles', array());
 162+ $r_descriptions = $request->getArray('wpUploadDescriptions', array());
 163+ $r_watch_these = $request->getArray('wpWatchThese', array());
 164+ $r_dest_files = $request->getArray('wpDestFiles', array());
 165+
 166+ $r_descriptions_prepend = $request->getVal('wpUploadDescriptionsPrepend' , '');
 167+ $r_descriptions_append = $request->getVal('wpUploadDescriptionsAppend', '');
 168+ $r_dest_files_prepend = $request->getVal('wpDestFilesPrepend', '');
 169+ $r_dest_files_append = $request->getVal('wpDestFilesAppend', '');
 170+
 171+ $files_to_process = array();
 172+ $forms = array();
 173+
 174+ foreach ($r_files as $i => $file) {
 175+ if (!in_array($file, $this->_available_files)) continue;
 176+ // Build destination filename
 177+ $r_dest_file = $r_dest_files_prepend . (isset($r_dest_files[$i]) ?
 178+ $r_dest_files[$i] : $file);
 179+ $p = strrpos($r_dest_file, '.');
 180+ if ($p !== false) {
 181+ $r_dest_file = substr($r_dest_file, 0, $p) . $r_dest_files_append
 182+ . substr($r_dest_file, $p);
 183+ } else {
 184+ $r_dest_file = $r_dest_file . $r_dest_files_append;
 185+ }
 186+ $forms[] =& new UploadLocalForm(
 187+ $file,
 188+ $r_descriptions_prepend . ($r_descriptions_prepend ? "\n" : '') .
 189+ (isset($r_descriptions[$i]) ? $r_descriptions[$i] : '') .
 190+ ($r_descriptions_append ? "\n" : '') . $r_descriptions_append,
 191+ in_array($file, $r_watch_these),
 192+ $r_dest_file
 193+ );
 194+
 195+ }
 196+
 197+ if (empty($forms)) {
 198+ $wgOut->addWikitext( wfMsg( 'uploadednolocalfiles' ) );
 199+ return;
 200+ }
 201+ $no_error = true;
 202+ $errors = array();
 203+
 204+ foreach($forms as $key => $value) {
 205+ $forms[$key]->processUpload();
 206+ if ($forms[$key]->getError()) {
 207+ $errors[$forms[$key]->getFilename()] = $forms[$key]->getError();
 208+ unset($forms[$key]);
 209+ }
 210+ }
 211+ //ugly hack to stop the thing from redirecting. Really annoying.
 212+ $wgOut->redirect('');
 213+
 214+ if (empty($errors)) {
 215+ $wgOut->setPageTitle(wfMsg('allfilessuccessful'));
 216+ $wgOut->addWikitext(wfMsg('allfilessuccessfultext'));
 217+ } else {
 218+ $wgOut->setPageTitle(wfMsg('uploadlocalerrors'));
 219+ $wgOut->addHTML('<ul>');
 220+ foreach ($errors as $name => $error) {
 221+ $wgOut->addHTML('<li>'.$name.' - '.$error.'</li>');
 222+ }
 223+ $wgOut->addHTML('</ul>');
 224+ }
 225+
 226+ $links_to_images = '';
 227+ foreach($forms as $key => $form) {
 228+ // language-neutral namespacing thanks to Eric Lemoine
 229+ $links_to_images .= '* [[:'.$wgContLang->getNsText( NS_IMAGE ).':'.$forms[$key]->getUploadSaveName().']]'."\n";
 230+ }
 231+ $wgOut->addWikitext($links_to_images);
 232+
 233+ }
 234+
 235+}
 236+
 237+?>
\ No newline at end of file
Property changes on: trunk/extensions/SpecialUploadLocal/UploadLocalDirectory.php
___________________________________________________________________
Added: svn:eol-style
1238 + native

Comments

#Comment by Reedy (talk | contribs)   15:10, 29 November 2011

There looks to be quite a lot of things wrong with this extension

You're still using old PHP4 style constructors

Messages shouldn't be loaded in manually like that

All of those random requires shouldn't be needed if you Autoload the classes properly

#Comment by Cneubauer (talk | contribs)   15:37, 29 November 2011

Yeah I just loaded the original extension as it existed in the wild. I tried to modernize it in r104568. Thanks for the comments.

#Comment by Raymond (talk | contribs)   16:01, 29 November 2011

I suggest to rename the extension to "UploadLocal" to be more consistent (reminder: Use "svn move..." to keep the history)

#Comment by Cneubauer (talk | contribs)   14:38, 30 November 2011

Thanks for the suggestion. Yeah I'll probably do that at some point.

#Comment by Cneubauer (talk | contribs)   19:10, 12 December 2011

Done in r105915

Status & tagging log