specialupload.php

来自「php 开发的内容管理系统」· PHP 代码 · 共 1,110 行 · 第 1/3 页

PHP
1,110
字号
<?php/** * * @package MediaWiki * @subpackage SpecialPage *//** * */require_once 'Image.php';/** * Entry point */function wfSpecialUpload() {	global $wgRequest;	$form = new UploadForm( $wgRequest );	$form->execute();}/** * * @package MediaWiki * @subpackage SpecialPage */class UploadForm {	/**#@+	 * @access private	 */	var $mUploadFile, $mUploadDescription, $mLicense ,$mIgnoreWarning, $mUploadError;	var $mUploadSaveName, $mUploadTempName, $mUploadSize, $mUploadOldVersion;	var $mUploadCopyStatus, $mUploadSource, $mReUpload, $mAction, $mUpload;	var $mOname, $mSessionKey, $mStashed, $mDestFile, $mRemoveTempFile;	/**#@-*/	/**	 * Constructor : initialise object	 * Get data POSTed through the form and assign them to the object	 * @param $request Data posted.	 */	function UploadForm( &$request ) {		$this->mDestFile          = $request->getText( 'wpDestFile' );		if( !$request->wasPosted() ) {			# GET requests just give the main form; no data except wpDestfile.			return;		}		$this->mIgnoreWarning     = $request->getCheck( 'wpIgnoreWarning' );		$this->mReUpload          = $request->getCheck( 'wpReUpload' );		$this->mUpload            = $request->getCheck( 'wpUpload' );		$this->mUploadDescription = $request->getText( 'wpUploadDescription' );		$this->mLicense           = $request->getText( 'wpLicense' );		$this->mUploadCopyStatus  = $request->getText( 'wpUploadCopyStatus' );		$this->mUploadSource      = $request->getText( 'wpUploadSource' );		$this->mWatchthis         = $request->getBool( 'wpWatchthis' );		wfDebug( "UploadForm: watchthis is: '$this->mWatchthis'\n" );		$this->mAction            = $request->getVal( 'action' );		$this->mSessionKey        = $request->getInt( 'wpSessionKey' );		if( !empty( $this->mSessionKey ) &&			isset( $_SESSION['wsUploadData'][$this->mSessionKey] ) ) {			/**			 * Confirming a temporarily stashed upload.			 * We don't want path names to be forged, so we keep			 * them in the session on the server and just give			 * an opaque key to the user agent.			 */			$data = $_SESSION['wsUploadData'][$this->mSessionKey];			$this->mUploadTempName   = $data['mUploadTempName'];			$this->mUploadSize       = $data['mUploadSize'];			$this->mOname            = $data['mOname'];			$this->mUploadError      = 0/*UPLOAD_ERR_OK*/;			$this->mStashed          = true;			$this->mRemoveTempFile   = false;		} else {			/**			 *Check for a newly uploaded file.			 */			$this->mUploadTempName = $request->getFileTempName( 'wpUploadFile' );			$this->mUploadSize     = $request->getFileSize( 'wpUploadFile' );			$this->mOname          = $request->getFileName( 'wpUploadFile' );			$this->mUploadError    = $request->getUploadError( 'wpUploadFile' );			$this->mSessionKey     = false;			$this->mStashed        = false;			$this->mRemoveTempFile = false; // PHP will handle this		}	}	/**	 * Start doing stuff	 * @access public	 */	function execute() {		global $wgUser, $wgOut;		global $wgEnableUploads, $wgUploadDirectory;		# Check uploading enabled		if( !$wgEnableUploads ) {			$wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext' );			return;		}		# Check permissions		if( $wgUser->isLoggedIn() ) {			if( !$wgUser->isAllowed( 'upload' ) ) {				$wgOut->permissionRequired( 'upload' );				return;			}		} else {			$wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );			return;		}		# Check blocks		if( $wgUser->isBlocked() ) {			$wgOut->blockedPage();			return;		}		if( wfReadOnly() ) {			$wgOut->readOnlyPage();			return;		}		/** Check if the image directory is writeable, this is a common mistake */		if ( !is_writeable( $wgUploadDirectory ) ) {			$wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) );			return;		}		if( $this->mReUpload ) {			if ( !$this->unsaveUploadedFile() ) {				return;			}			$this->mainUploadForm();		} else if ( 'submit' == $this->mAction || $this->mUpload ) {			$this->processUpload();		} else {			$this->mainUploadForm();		}		$this->cleanupTempFile();	}	/* -------------------------------------------------------------- */	/**	 * Really do the upload	 * Checks are made in SpecialUpload::execute()	 * @access private	 */	function processUpload() {		global $wgUser, $wgOut;		/* Check for PHP error if any, requires php 4.2 or newer */		if ( $this->mUploadError == 1/*UPLOAD_ERR_INI_SIZE*/ ) {			$this->mainUploadForm( wfMsgHtml( 'largefileserver' ) );			return;		}		/**		 * If there was no filename or a zero size given, give up quick.		 */		if( trim( $this->mOname ) == '' || empty( $this->mUploadSize ) ) {			$this->mainUploadForm( wfMsgHtml( 'emptyfile' ) );			return;		}		# Chop off any directories in the given filename		if ( $this->mDestFile ) {			$basename = wfBaseName( $this->mDestFile );		} else {			$basename = wfBaseName( $this->mOname );		}		/**		 * We'll want to blacklist against *any* 'extension', and use		 * only the final one for the whitelist.		 */		list( $partname, $ext ) = $this->splitExtensions( $basename );				if( count( $ext ) ) {			$finalExt = $ext[count( $ext ) - 1];		} else {			$finalExt = '';		}		$fullExt = implode( '.', $ext );		# If there was more than one "extension", reassemble the base		# filename to prevent bogus complaints about length		if( count( $ext ) > 1 ) {			for( $i = 0; $i < count( $ext ) - 1; $i++ )				$partname .= '.' . $ext[$i];		}		if ( strlen( $partname ) < 3 ) {			$this->mainUploadForm( wfMsgHtml( 'minlength' ) );			return;		}		/**		 * Filter out illegal characters, and try to make a legible name		 * out of it. We'll strip some silently that Title would die on.		 */		$filtered = preg_replace ( "/[^".Title::legalChars()."]|:/", '-', $basename );		$nt = Title::newFromText( $filtered );		if( is_null( $nt ) ) {			$this->uploadError( wfMsgWikiHtml( 'illegalfilename', htmlspecialchars( $filtered ) ) );			return;		}		$nt =& Title::makeTitle( NS_IMAGE, $nt->getDBkey() );		$this->mUploadSaveName = $nt->getDBkey();		/**		 * If the image is protected, non-sysop users won't be able		 * to modify it by uploading a new revision.		 */		if( !$nt->userCanEdit() ) {			return $this->uploadError( wfMsgWikiHtml( 'protectedpage' ) );		}		/**		 * In some cases we may forbid overwriting of existing files.		 */		$overwrite = $this->checkOverwrite( $this->mUploadSaveName );		if( WikiError::isError( $overwrite ) ) {			return $this->uploadError( $overwrite->toString() );		}		/* Don't allow users to override the blacklist (check file extension) */		global $wgStrictFileExtensions;		global $wgFileExtensions, $wgFileBlacklist;		if( $this->checkFileExtensionList( $ext, $wgFileBlacklist ) ||			($wgStrictFileExtensions &&				!$this->checkFileExtension( $finalExt, $wgFileExtensions ) ) ) {			return $this->uploadError( wfMsgHtml( 'badfiletype', htmlspecialchars( $fullExt ) ) );		}		/**		 * Look at the contents of the file; if we can recognize the		 * type but it's corrupt or data of the wrong type, we should		 * probably not accept it.		 */		if( !$this->mStashed ) {			$this->checkMacBinary();			$veri = $this->verify( $this->mUploadTempName, $finalExt );			if( $veri !== true ) { //it's a wiki error...				return $this->uploadError( $veri->toString() );			}		}		/**		 * Provide an opportunity for extensions to add futher checks		 */		$error = '';		if( !wfRunHooks( 'UploadVerification',				array( $this->mUploadSaveName, $this->mUploadTempName, &$error ) ) ) {			return $this->uploadError( $error );		}		/**		 * Check for non-fatal conditions		 */		if ( ! $this->mIgnoreWarning ) {			$warning = '';			global $wgCapitalLinks;			if( $wgCapitalLinks ) {				$filtered = ucfirst( $filtered );			}			if( $this->mUploadSaveName != $filtered ) {				$warning .=  '<li>'.wfMsgHtml( 'badfilename', htmlspecialchars( $this->mUploadSaveName ) ).'</li>';			}			global $wgCheckFileExtensions;			if ( $wgCheckFileExtensions ) {				if ( ! $this->checkFileExtension( $finalExt, $wgFileExtensions ) ) {					$warning .= '<li>'.wfMsgHtml( 'badfiletype', htmlspecialchars( $fullExt ) ).'</li>';				}			}			global $wgUploadSizeWarning;			if ( $wgUploadSizeWarning && ( $this->mUploadSize > $wgUploadSizeWarning ) ) {				# TODO: Format $wgUploadSizeWarning to something that looks better than the raw byte				# value, perhaps add GB,MB and KB suffixes?				$warning .= '<li>'.wfMsgHtml( 'largefile', $wgUploadSizeWarning, $this->mUploadSize ).'</li>';			}			if ( $this->mUploadSize == 0 ) {				$warning .= '<li>'.wfMsgHtml( 'emptyfile' ).'</li>';			}			if( $nt->getArticleID() ) {				global $wgUser;				$sk = $wgUser->getSkin();				$dlink = $sk->makeKnownLinkObj( $nt );				$warning .= '<li>'.wfMsgHtml( 'fileexists', $dlink ).'</li>';			} else {				# If the file existed before and was deleted, warn the user of this				# Don't bother doing so if the image exists now, however				$image = new Image( $nt );				if( $image->wasDeleted() ) {					$skin = $wgUser->getSkin();					$ltitle = Title::makeTitle( NS_SPECIAL, 'Log' );					$llink = $skin->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ), 'type=delete&page=' . $nt->getPrefixedUrl() );					$warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) . wfCloseElement( 'li' );				}			}			if( $warning != '' ) {				/**				 * Stash the file in a temporary location; the user can choose				 * to let it through and we'll complete the upload then.				 */				return $this->uploadWarning( $warning );			}		}		/**		 * Try actually saving the thing...		 * It will show an error form on failure.		 */		$hasBeenMunged = !empty( $this->mSessionKey ) || $this->mRemoveTempFile;		if( $this->saveUploadedFile( $this->mUploadSaveName,		                             $this->mUploadTempName,		                             $hasBeenMunged ) ) {			/**			 * Update the upload log and create the description page			 * if it's a new file.			 */			$img = Image::newFromName( $this->mUploadSaveName );			$success = $img->recordUpload( $this->mUploadOldVersion,			                                $this->mUploadDescription,			                                $this->mLicense,			                                $this->mUploadCopyStatus,			                                $this->mUploadSource,			                                $this->mWatchthis );			if ( $success ) {				$this->showSuccess();				wfRunHooks( 'UploadComplete', array( &$img ) );			} else {				// Image::recordUpload() fails if the image went missing, which is				// unlikely, hence the lack of a specialised message				$wgOut->showFileNotFoundError( $this->mUploadSaveName );			}		}	}	/**	 * Move the uploaded file from its temporary location to the final	 * destination. If a previous version of the file exists, move	 * it into the archive subdirectory.	 *	 * @todo If the later save fails, we may have disappeared the original file.	 *	 * @param string $saveName	 * @param string $tempName full path to the temporary file	 * @param bool $useRename if true, doesn't check that the source file	 *                        is a PHP-managed upload temporary	 */	function saveUploadedFile( $saveName, $tempName, $useRename = false ) {		global $wgOut;		$fname= "SpecialUpload::saveUploadedFile";		$dest = wfImageDir( $saveName );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?