allwiki首页  
天下维客 你可以修改的网络知识库
首页最近更改优秀条目专题展示电脑科技词典软件学习网络知识电脑安全明星时尚天下百科
 

MediaWiki扩展:使用服务器的本地图片

天下维客,你可以修改的网络知识库

Jump to: navigation, search

本文取自元维基,欢迎共同翻译、整理与大家共享,促进中文wiki发展^_^

Template:If
Type: Special Page
Maturity: Alpha
MediaWiki: 1.5.6
Version: 1.0alpha
Last Update: 2006-03-23
Description: Hooks in files residing on the server, streamlining mass uploading and upload of large files.
MediaWiki extensions

Special:UploadLocal is a special page written by User:Ambush Commander that allows the "hooking in" of files residing on the server into MediaWiki. This has numerous practical applications, notably the streamlining of the upload of large files, renaming of image files, and the upload of many files (aka. mass upload).

目录

Installation

There are two files, both confusingly named
SpecialUploadLocal.php
. The one that has the comment
//Special:Uploadlocal specific config
goes inside your
extension/
directory, while the other goes in your
includes/

directory.

Create a folder called
uploadlocal
in your extensions folder, and

chmod it 777.

Then, in LocalSettings, add these lines:

require_once( "extensions/SpecialUploadLocal.php" );

It should be installed. There are a few more settings:

$wgUploadLocalDirectory
sets the absolute path for the directory where

uploaded files reside, so you can set it to whatever you want. The default is:

$wgUploadLocalDirectory = $IP . '/extensions/uploadlocal';
Also, the extension adds a new right called
uploadlocal
and a new user

group, uploader, along with sysop, are allowed to use this extension. You can change this however you want, although remember, in order for the extension to be useful, the user must also have FTP access.

Using it

Upload files into the directory specified by
$wgUploadLocalDirectory

(default is the new directory you created during the installation). Then surf to Special:UploadLocal and you should see the files you uploaded listed there. Follow the instructions.

Known bugs

The result page will randomnly spit out stuff you inserted in the summary. This is largely unavoidable due to the nature of the extension (aka: it is a hack).

Also, files with single quotes in their names will not be renamed or given summaries unless magic_quotes is off or the patch is applied. Patching stuff is as easy as executing the command:

patch -p0 < Magic_quotes_2.patch

from the directory where MediaWiki is installed (but you need shell). I haven't made a drop-dead easy installation script yet.

License

Special:UploadLocal, a special page for MediaWiki
Copyright (C) 2006 Edward Z. Yang

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Code

I will make a tarball available soon. Make sure you verify that no one has been twiddling with the code before you copy and paste.

extension/SpecialUploadLocal.php

<?php

if (!defined('MEDIAWIKI')) die();

//Special:Uploadlocal specific config

$wgExtensionFunctions[] = "wfExtensionSpecialUploadLocal";
function wfExtensionSpecialUploadLocal() {
    global $wgMessageCache;
	// I'd like to try adding these messages on demand, and only have the
	// essentials here
	$messages = array(
	    'uploadlocal' => 'Upload local files'
	   ,'uploadlocal_directory_readonly' => 'The local upload directory ($1) is'.
	       ' not writeable by the webserver.'
	   ,'uploadlocaltext' => 'Use this form to mass upload files already on the'.
	       ' server in the upload local directory. You can find out more'.
	       ' general information at [[Special:Upload|the regular upload file'.
	       ' page]].'
	   ,'uploadlocalbtn' => 'Upload local files'
	   ,'nolocalfiles' => 'There are no files in the local upload folder. Try'.
	       ' placing some files in "<code>$1</code>."'
	   ,'uploadednolocalfiles' => 'You did not upload any files.'
	   ,'allfilessuccessful' => 'All files uploaded successfully'
	   ,'uploadlocalerrors' => 'Some files had errors'
	   ,'allfilessuccessfultext' => 'All files uploaded successfully. Return to'.
	       ' [[Main Page]].'
	   ,'uploadlocal_descriptions_append' => 'Append to description: '
	   ,'uploadlocal_descriptions_prepend' => 'Prepend to description: '
	   ,'uploadlocal_dest_file_append' => 'Append to dest. filename: '
	   ,'uploadlocal_dest_file_prepend' => 'Prepend to dest. filename: '
	   ,'uploadlocal_file_list' => 'Files ready for upload'
	   ,'uploadlocal_file_list_explanation' => '\'\'\'X\'\'\' indicates'.
	       ' whether or not you want the file to be uploaded (uncheck to'.
	       ' prevent a file from being processed). \'\'\'W\'\'\' indicates'.
	       ' whether you want the file added to your watchlist.'
	   ,'uploadlocal_global_params' => 'Global parameters'
	   ,'uploadlocal_global_params_explanation' => 'What is entered here will'.
	       ' automatically get added to the entries listed above. This helps'.
	       ' remove repetitive text such as categories and metadata. To \'\'\''.
	       'append\'\'\' is to add to the end of text, while to \'\'\'prepend'.
	       '\'\'\' means to add to the beginning of text. Especially for'.
	       ' descriptions, make sure you give a few linebreaks before/after'.
	       ' the text.'
	    );
	$wgMessageCache->addMessages($messages);
    SpecialPage::addPage( new SpecialPage( 'UploadLocal', 'uploadlocal' ) );
}

$wgUploadLocalDirectory = $IP . '/extensions/uploadlocal';

$wgAvailableRights[] = 'uploadlocal';
$wgGroupPermissions['uploader']['uploadlocal'] = true;
$wgGroupPermissions['sysop']   ['uploadlocal'] = true;

?>

includes/SpecialUploadLocal.php

<?php

require_once('SpecialUpload.php');

/*

TODO:
 * Considered more advanced file scanning regexps/recursive searching
 * Allow unzipping without telnetting

BUGS:
 * Figure out how to get image overwrites to work properly or fail gracefully
 * Extra output from the new page function... need a wgOut decorator to mute it
 * & is accepted, but MediaWiki doesn't seem to like it
 * Really easy to make mistake with description appends: force a newline
 * Filename append is useless, add it right before the period
 * Rewrite form so that all array keys are integers

WARNINGS:
 * Files with single quotes in them will lose information when magic_quotes
   is on, as per bug 4381. There is a patch available to fix this, but beware!

*/

function wfSpecialUploadLocal() {
	global $wgRequest, $wgUploadLocalDirectory, $wgMessageCache;
	
	$directory =& new UploadLocalDirectory($wgRequest, $wgUploadLocalDirectory);
	$directory->execute();
}

class UploadLocalDirectory
{
    
    var $_directory;
    var $_was_posted;
    var $_available_files;
    
    function UploadLocalDirectory($request, $directory) {
        $this->_directory = $directory;
        $this->_was_posted = $request->wasPosted();
        $this->_available_files = $this->getFilenamesOfFilesInDirectory($directory);
    }
    
    function execute() {
        global $wgOut, $wgRequest, $wgUser, $wgEnableUploads,
          $wgUploadDirectory;
        
        // a bit of this is stolen from the SpecialUpload code, duplication
        // is bad but there was no way to meaningfully integrate it into
        // this code.
        
        if(! $wgEnableUploads ) {
			$wgOut->addWikiText( wfMsg( 'uploaddisabled' ) );
			return;
		}
        
        // uses extension specific permission "uploadlocal"
        if (!$wgUser->isAllowed( 'uploadlocal' ) || $wgUser->isBlocked() ) {
            $wgOut->errorpage( 'uploadnologin', 'uploadnologintext' );
            return;
        }
        
        if( wfReadOnly() ) {
			$wgOut->readOnlyPage();
			return;
		}
		
		// check if both relevant directories are writeable
		if (!is_writeable( $wgUploadDirectory ) ) {
			$wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) );
			return;
		}
		if (!is_writeable($this->_directory) ) {
		    $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $this->_directory ) );
			return;
		}
		
		// check if there are any files to upload
        if (empty($this->_available_files)) {
            $wgOut->addWikitext( wfMsg( 'uploadlocaltext' ) );
            $wgOut->addWikitext( wfMsg( 'nolocalfiles', htmlentities($this->_directory) ) );
            return;
        }
        
        if ($this->_was_posted) {
            $this->processUploads($wgRequest);
        } else {
            $this->showForm();
        }
        
    }
    
    function showForm() {
        global $wgOut;
        
        $wgOut->addWikitext( wfMsg( 'uploadlocaltext' ) );
        
        $titleObj = Title::makeTitle( NS_SPECIAL, 'UploadLocal' );
		$action = $titleObj->escapeLocalURL();
        
        $wgOut->addHTML('<form id="uploadlocal" method="post"'.
            ' enctype="multipart/form-data" action="'.$action.'">');
        
        $wgOut->addWikitext('==' . wfMsg('uploadlocal_file_list') . '==');
        $wgOut->addWikitext(wfMsg('uploadlocal_file_list_explanation'));
        
        $html = '';
        
        $html .= '<table border="0" cellspacing="0" style="width:100%;">';
        $html .= '<theader>'.
            '<tr><th style="width:1em;">X</th>'.
            '<th style="width:1em;">W</th>'.
            '<th style="width:10em;text-align:left;">'.wfMsg('sourcefilename').'</th>'.
            '<th style="width:10em;text-align:left;">'.wfMsg('destfilename').'</th>'.
            '<th style="text-align:left;">'.wfMsg('filedesc').'</th></tr></theader>';
        $html .= '<tbody>';
        $i = 1;
        foreach ($this->_available_files as $file) {
            $html_file = htmlentities($file);
            $html .= '<tr' .
                ($i % 2? ' style="background-color:#EEE;"': '') .
                '>'.
                '<td><input type="checkbox" checked="checked"'.
                ' name="wpUploadFiles[]" value="'.$html_file.'" /></td>'.
                '<td><input type="checkbox" checked="checked"'.
                ' name="wpWatchThese[]" value="'.$html_file.'" /></td>'.
                '<td>'.$html_file.'</td>'.
                '<td><input type="text" name="wpDestFiles['.$html_file.']"'.
                ' value="'.$html_file.'" /></td>'.
                '<td style="width:50%;"><textarea name="wpUploadDescriptions['.
                $html_file.
                ']" cols="60" rows="2" style="width:100%;"></textarea></td>'.
                '</tr>';
            $i++;
        }
        $html .= '</tbody></table>';
        
        $wgOut->addHTML($html);
        $wgOut->addWikitext('==' . wfMsg('uploadlocal_global_params') . '==');
        $wgOut->addWikitext(wfMsg('uploadlocal_global_params_explanation'));
        $html = '';
        
        $html .= '<table border="0" style="width:100%;">';
        $html .= '<tbody>'.
            '<tr><th style="text-align:right;width:25%;">'.wfMsg('uploadlocal_descriptions_prepend').'</th>'.
            '<td><textarea cols="70" rows="3" style="width:100%;" name="wpUploadDescriptionsPrepend"></textarea></td></tr>'.
            
            '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_descriptions_append').'</th>'.
            '<td><textarea cols="70" rows="3" style="width:100%;" name="wpUploadDescriptionsAppend"></textarea></td></tr>'.
            
            '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_dest_file_prepend').'</th>'.
            '<td><input type="text" style="width:100%;" name="wpDestFilesPrepend" /></td></tr>'.
            
            '<tr><th style="text-align:right;">'.wfMsg('uploadlocal_dest_file_append').'</th>'.
            '<td><input type="text" style="width:100%;" name="wpDestFilesAppend" /></td></tr>'.
            
            '</tbody>';
        $html .= '</table>';
        
        $html .= '<input type="submit" name="wpUploadLocal" value="'.wfMsg('uploadlocalbtn').'" /></form>';
        
        $wgOut->addHTML($html);
    }
    
    function getFilenamesOfFilesInDirectory($directory) {
        if (!is_dir($directory)) return array();
        if ($directory[strlen($directory)-1]!== '/') $directory .= '/';
        $dh = opendir($directory);
        $filenames = array();
        while (($file = readdir($dh))!== false) {
            if ($file == '.' || $file == '..') continue;
            // check if it's a directory
            if (is_dir($directory . $file)) continue;
            // check if it's a hidden file - regexp: /\.[^.]+/
            if ($file[0] == '.' && strpos($file,'.',1) === false) {
                continue;
            }
            $filenames[] = $file;
        }
        closedir($dh);
        return $filenames;
    }
    
    function processUploads($request) {
        
        global $wgOut, $wgContLang;
        
        $r_files        = $request->getArray('wpUploadFiles', array());
        $r_descriptions = $request->getArray('wpUploadDescriptions', array());
        $r_watch_these  = $request->getArray('wpWatchThese', array());
        $r_dest_files   = $request->getArray('wpDestFiles', array());
        
        $r_descriptions_prepend = $request->getVal('wpUploadDescriptionsPrepend' , '');
        $r_descriptions_append  = $request->getVal('wpUploadDescriptionsAppend', '');
        $r_dest_files_prepend   = $request->getVal('wpDestFilesPrepend', '');
        $r_dest_files_append    = $request->getVal('wpDestFilesAppend', '');
        
        $files_to_process = array();
        $forms = array();
        
        foreach ($r_files as $file) {
            if (!in_array($file, $this->_available_files)) continue;
            // this is really convoluted
            // also, we'd like the appending for filenames to be smart and
            // come before the period, otherwise it's pretty useless
            $forms[] =& new UploadLocalForm(
               $file,
               $r_descriptions_prepend . (isset($r_descriptions[$file])? $r_descriptions[$file]: '') . $r_descriptions_append,
               in_array($file, $r_watch_these),
               $r_dest_files_prepend . (isset($r_dest_files[$file])? $r_dest_files[$file]: $file) . $r_dest_files_append
            );
            
        }
        
        if (empty($forms)) {
            $wgOut->addWikitext( wfMsg( 'uploadednolocalfiles' ) );
            return;
        }
        $no_error = true;
        $errors = array();
        
        foreach($forms as $key => $value) {
            $forms[$key]->processUpload();
            if ($forms[$key]->getError()) {
                $errors[$forms[$key]->getFilename()] = $forms[$key]->getError();
                unset($forms[$key]);
            }
        }
        //ugly hack to stop the thing from redirecting. Really annoying.
        $wgOut->redirect('');
        
        if (empty($errors)) {
            $wgOut->setPageTitle(wfMsg('allfilessuccessful'));
            $wgOut->addWikitext(wfMsg('allfilessuccessfultext'));
        } else {
            $wgOut->setPageTitle(wfMsg('uploadlocalerrors'));
            $wgOut->addHTML('<ul>');
            foreach ($errors as $name => $error) {
                $wgOut->addHTML('<li>'.$name.' - '.$error.'</li>');
            }
            $wgOut->addHTML('</ul>');
        }
        
        $links_to_images = '';
        foreach($forms as $key => $form) {
            // language-neutral namespacing thanks to Eric Lemoine
            $links_to_images .= '* [[:'.$wgContLang->getNsText( NS_IMAGE ).':'.$forms[$key]->getUploadSaveName().']]'."\n";
        }
        $wgOut->addWikitext($links_to_images);
        
    }
    
}

class UploadLocalForm extends UploadForm
{
    
    var $_error = '';
    var $_filename;
    
    //overload form initialization: we're not dealing with any http uploads
    function UploadLocalForm($filename, $description, $watch, $dest) {
        global $wgUploadLocalDirectory;
        $this->_filename = $filename;
        $directory = $wgUploadLocalDirectory;
        if ($directory[strlen($directory)-1]!== '/') $directory .= '/';
        $this->mUploadTempName = $directory . $filename;
        // there is no "real" old name, as it's already on the server
        $this->mOname = $directory . $filename;
        $this->mUploadSize = filesize($this->mUploadTempName);
        $this->mDestFile = $dest;
        // should check every time, since there are no fresh/stale uploads
        $this->mStashed = false;
        $this->mIgnoreWarning = true; //ignore warnings... don't wanna deal with 'em
                                      //however, this attitude means that it's
                                      //extremely easy to accidently overwrite
                                      //files. Solution?
        $this->mSessionKey = true; //makes it think that it is locally stored
        $this->mUploadDescription = $description;
        $this->mUploadCopyStatus = ''; //not supported yet
        $this->mUploadSource = ''; //not supported yet
        $this->mWatchthis = $watch;
    }
    
    function getFilename() {return $this->_filename;}
    function getUploadSaveName() {return $this->mUploadSaveName;}
        
    function mainUploadForm($error) {$this->_error = $error;}
    function uploadError($error) {$this->_error = $error;}
    function showSuccess() {}
    
    function getError() {return $this->_error;}
    
}

?>

Magic_quotes_2.patch

--- C:/Documents and Settings/Edward/My Documents/My Webs/jpsband/mediawiki/t/includes/WebRequest.php	(revision 454)
+++ includes/WebRequest.php	(revision 526)
@@ -48,9 +48,15 @@
 	/**
 	 * Recursively strips slashes from the given array;
 	 * used for undoing the evil that is magic_quotes_gpc.
+	 * 
+	 * Abandoned in favor of more accurate fix_magic_quotes_4 and 5, which
+	 * were based largely on comments in
+	 * http://us3.php.net/manual/en/function.get-magic-quotes-gpc.php
+	 * 
 	 * @param array &$arr will be modified
 	 * @return array the original array
 	 * @private
+	 * @deprecated
 	 */
 	function &fix_magic_quotes( &$arr ) {
 		foreach( $arr as $key => $val ) {
@@ -63,6 +69,35 @@
 		return $arr;
 	}
 	
+	function fix_magic_quotes_4($array, $is_top = true) {
+		$return = array();
+		foreach ($array as $key => $value) {
+			$clean_key =!$is_top? stripslashes($key): $key;
+			if (is_array($value)) {
+				$clean_value = $this->fix_magic_quotes_4($value, false);
+			} else {
+				$clean_value = stripslashes($value);
+			}
+			$return[$clean_key] = $clean_value;
+		}
+		return $return;
+	}
+	
+	function fix_magic_quotes_5($array, $is_top = true) {
+		$return = array();
+		foreach ($array as $key => $value) {
+			if (is_array($value)) {
+				$clean_key   =!$is_top? stripslashes($key): $key;
+				$clean_value = $this->fix_magic_quotes_5($value, false);
+			} else {
+				$clean_key   = stripslashes($key);
+				$clean_value = stripslashes($value);
+			}
+			$return[$clean_key] = $clean_value;
+		}
+		return $return;
+	}
+	
 	/**
 	 * If magic_quotes_gpc option is on, run the global arrays
 	 * through fix_magic_quotes to strip out the stupid slashes.
@@ -72,12 +107,27 @@
 	 */
 	function checkMagicQuotes() {
 		if ( get_magic_quotes_gpc() ) {
-			$this->fix_magic_quotes( $_COOKIE );
-			$this->fix_magic_quotes( $_ENV );
-			$this->fix_magic_quotes( $_GET );
-			$this->fix_magic_quotes( $_POST );
-			$this->fix_magic_quotes( $_REQUEST );
-			$this->fix_magic_quotes( $_SERVER );
+			//I would rather do it this way, but supposedly, version_compare
+			//is more accurate:
+			//$php_version = substr(PHP_VERSION,0,strpos(PHP_VERSION,'.'));
+			if (version_compare(PHP_VERSION, '4', '>=') && version_compare(PHP_VERSION, '5', '<')) {
+				//it is PHP4
+				$_COOKIE  = $this->fix_magic_quotes_4( $_COOKIE );
+				$_ENV     = $this->fix_magic_quotes_4( $_ENV );
+				$_GET     = $this->fix_magic_quotes_4( $_GET );
+				$_POST    = $this->fix_magic_quotes_4( $_POST );
+				$_REQUEST = $this->fix_magic_quotes_4( $_REQUEST );
+				$_SERVER  = $this->fix_magic_quotes_4( $_SERVER );
+			} elseif (version_compare(PHP_VERSION, '5', '>=') && version_compare(PHP_VERSION, '6', '<')) {
+				//it is PHP5
+				$_COOKIE  = $this->fix_magic_quotes_5( $_COOKIE );
+				$_ENV     = $this->fix_magic_quotes_5( $_ENV );
+				$_GET     = $this->fix_magic_quotes_5( $_GET );
+				$_POST    = $this->fix_magic_quotes_5( $_POST );
+				$_REQUEST = $this->fix_magic_quotes_5( $_REQUEST );
+				$_SERVER  = $this->fix_magic_quotes_5( $_SERVER );
+			}
+			//behavior for PHP3 and PHP6 is undefined, so don't do any fixing
 		}
 	}
 	

原文参见: SpecialUploadLocal

Personal tools
工具
金银币拍卖 金币拍卖预展  金银币网店 熊猫金银币 生肖金银币