Don't duplicate code, use wfAppendQuery
[lhc/web/wiklou.git] / includes / UploadBase.php
index 58f78cc..219ab4e 100644 (file)
@@ -24,38 +24,95 @@ class UploadBase {
        
        const SESSION_VERSION = 2;
        
+       /**
+        * Returns true if uploads are enabled.
+        * Can be overriden by subclasses.
+        */
        static function isEnabled() {
                global $wgEnableUploads;
                return $wgEnableUploads;
        }
-       static function isAllowed( User $user ) {
+       /**
+        * Returns true if the user can use this upload module or else a string 
+        * identifying the missing permission.
+        * Can be overriden by subclasses.
+        */
+       static function isAllowed( $user ) {
                if( !$user->isAllowed( 'upload' ) )
                        return 'upload';
                return true;
        }
        
-       function __construct( $name ) {
-               $this->mDesiredDestName = $name;
+       // Upload handlers. Should probably just be a global
+       static $uploadHandlers = array( 'Stash', 'Upload', 'Url' );
+       /**
+        * Create a form of UploadBase depending on wpSourceType and initializes it
+        */
+       static function createFromRequest( &$request, $type = null ) {
+               $type = $type ? $type : $request->getVal( 'wpSourceType' );
+               if( !$type ) 
+                       return null;
+               $type = ucfirst($type);
+               $className = 'UploadFrom'.$type;
+               if( !in_array( $type, self::$uploadHandlers ) )
+                       return null;
+               if( !call_user_func( array( $className, 'isEnabled' ) ) )
+                       return null;
+               if( !call_user_func( array( $className, 'isValidRequest' ), $request ) )
+                       return null;
+               
+               $handler = new $className;
+               $handler->initializeFromRequest( $request );
+               return $handler;
+       }
+       
+       /**
+        * Check whether a request if valid for this handler
+        */
+       static function isValidRequest( $request ) {
+               return false;
        }
        
+       function __construct() {}
        
-       function verifyUpload( &$resultDetails ) {
+       /**
+        * Do the real variable initialization
+        */
+       function initialize( $name, $tempPath, $fileSize, $removeTempFile = false ) {
+               $this->mDesiredDestName = $name;
+               $this->mTempPath = $tempPath;
+               $this->mFileSize = $fileSize;
+               $this->mRemoveTempFile = $removeTempFile;
+       }
+
+       /**
+        * Fetch the file. Usually a no-op
+        */
+       function fetchFile() {
+               return self::OK;
+       }
+
+       /**
+        * Verify whether the upload is sane. 
+        * Returns self::OK or else an array with error information
+        */
+       function verifyUpload() {
                global $wgUser;
                
                /**
                 * If there was no filename or a zero size given, give up quick.
                 */
-               if( empty( $this->mFileSize ) ) {
-                       return self::EMPTY_FILE;
-               }
+               if( empty( $this->mFileSize ) ) 
+                       return array( 'status' => self::EMPTY_FILE );
 
                $nt = $this->getTitle();
                if( is_null( $nt ) ) {
+                       $result = array( 'status' => $this->mTitleError );
                        if( $this->mTitleError == self::ILLEGAL_FILENAME )
-                               $resultDetails = array( 'filtered' => $this->mFilteredName );
+                               $resul['filtered'] = $this->mFilteredName;
                        if ( $this->mTitleError == self::FILETYPE_BADTYPE )
-                               $resultDetails = array( 'finalExt' => $this->mFinalExtension );
-                       return $this->mTitleError;
+                               $result['finalExt'] = $this->mFinalExtension;
+                       return $result;
                }
                $this->mLocalFile = wfLocalFile( $nt );
                $this->mDestName = $this->mLocalFile->getName();
@@ -64,30 +121,27 @@ class UploadBase {
                 * In some cases we may forbid overwriting of existing files.
                 */
                $overwrite = $this->checkOverwrite( $this->mDestName );
-               if( $overwrite !== true ) {
-                       $resultDetails = array( 'overwrite' => $overwrite );
-                       return self::OVERWRITE_EXISTING_FILE;
-               }
+               if( $overwrite !== true )
+                       return array( 'status' => self::OVERWRITE_EXISTING_FILE, 'overwrite' => $overwrite );
                
                /**
                 * 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.
                 */
-               $veri = $this->verifyFile( $this->mTempPath );
+               $verification = $this->verifyFile( $this->mTempPath );
 
-               if( $veri !== true ) {
-                       if( !is_array( $veri ) ) 
-                               $veri = array( $veri );
-                       $resultDetails = array( 'veri' => $veri );
-                       return self::VERIFICATION_ERROR;
+               if( $verification !== true ) {
+                       if( !is_array( $verification ) ) 
+                               $verification = array( $verification );
+                       $verification['status'] = self::VERIFICATION_ERROR;
+                       return $verification;
                }
                
                $error = '';
                if( !wfRunHooks( 'UploadVerification',
                                array( $this->mDestName, $this->mTempPath, &$error ) ) ) {
-                       $resultDetails = array( 'error' => $error );
-                       return self::UPLOAD_VERIFICATION_ERROR;
+                       return array( 'status' => self::UPLOAD_VERIFICATION_ERROR, 'error' => $error );
                }
                
                return self::OK;
@@ -97,8 +151,7 @@ class UploadBase {
         * Verifies that it's ok to include the uploaded file
         *
         * @param string $tmpfile the full path of the temporary file to verify
-        * @param string $extension The filename extension that the file is to be served with
-        * @return mixed true of the file is verified, a WikiError object otherwise.
+        * @return mixed true of the file is verified, a string or array otherwise.
         */
        protected function verifyFile( $tmpfile ) {
                $this->mFileProps = File::getPropsFromPath( $this->mTempPath, 
@@ -144,6 +197,9 @@ class UploadBase {
                return true;
        }
        
+       /**
+        * Check whether the user can edit, upload and create the image
+        */
        function verifyPermissions( $user ) {
                /**
                 * If the image is protected, non-sysop users won't be able
@@ -163,6 +219,9 @@ class UploadBase {
                return true;
        }       
        
+       /**
+        * Check for non fatal problems with the file
+        */
        function checkWarnings() {
                $warning = array();
 
@@ -170,11 +229,11 @@ class UploadBase {
                $n = strrpos( $filename, '.' );         
                $partname = $n ? substr( $filename, 0, $n ) : $filename;
 
-               global $wgCapitalLinks;
+               // Check whether the resulting filename is different from the desired one
                if( $this->mDesiredDestName != $filename )
-                       // Use mFilteredName so that we don't have to bother about spaces
                        $warning['badfilename'] = $filename;
 
+               // Check whether the file extension is on the unwanted list
                global $wgCheckFileExtensions, $wgFileExtensions;
                if ( $wgCheckFileExtensions ) {
                        if ( !$this->checkFileExtension( $this->mFinalExtension, $wgFileExtensions ) )
@@ -192,7 +251,7 @@ class UploadBase {
                if( $exists !== false )
                        $warning['exists'] = $exists;
                
-               
+               // Check whether this may be a thumbnail
                if( $exists !== false && $exists[0] != 'thumb' 
                                && self::isThumbName( $this->mLocalFile->getName() ) )
                        $warning['file-thumbnail-no'] = substr( $filename , 0, 
@@ -219,6 +278,9 @@ class UploadBase {
                return $warning;
        }
 
+       /**
+        * Really perform the upload.
+        */
        function performUpload( $comment, $pageText, $watch, $user ) {
                $status = $this->mLocalFile->upload( $this->mTempPath, $comment, $pageText,
                        File::DELETE_SOURCE, $this->mFileProps, false, $user );
@@ -319,12 +381,7 @@ class UploadBase {
                global $wgOut;
                $repo = RepoGroup::singleton()->getLocalRepo();
                $status = $repo->storeTemp( $saveName, $tempName );
-               if ( !$status->isGood() ) {
-                       $this->showError( $status->getWikiText() );
-                       return false;
-               } else {
-                       return $status->value;
-               }
+               return $status;
        }
        
        /**
@@ -337,22 +394,19 @@ class UploadBase {
         * @access private
         */
        function stashSession() {
-               $stash = $this->saveTempUploadedFile( $this->mDestName, $this->mTempPath );
+               $status = $this->saveTempUploadedFile( $this->mDestName, $this->mTempPath );
 
-               if( !$stash ) {
+               if( !$status->isGood() ) {
                        # Couldn't save the file.
                        return false;
                }
 
-               $key = mt_rand( 0, 0x7fffffff );
-               $_SESSION['wsUploadData'][$key] = array(
-                       'mTempPath'       => $stash,
+               return array(
+                       'mTempPath'       => $status->value,
                        'mFileSize'       => $this->mFileSize,
-                       'mSrcName'        => $this->mSrcName,
                        'mFileProps'      => $this->mFileProps,
                        'version'         => self::SESSION_VERSION,
                );
-               return $key;
        }
        
        /**