re: r65152
[lhc/web/wiklou.git] / includes / upload / UploadFromUrl.php
index f9a7a3d..0fb7f4b 100644 (file)
@@ -1,15 +1,22 @@
 <?php
-
+/**
+ * @file
+ * @ingroup upload
+ *
+ * Implements uploading from a HTTP resource.
+ *
+ * @author Bryan Tong Minh
+ * @author Michael Dale
+ */
 class UploadFromUrl extends UploadBase {
        protected $mTempDownloadPath;
-
-       // by default do a SYNC_DOWNLOAD 
-       protected $dl_mode = null;
+       protected $comment, $watchList;
 
        /**
-        * Checks if the user is allowed to use the upload-by-URL feature
+        * Checks if the user is allowed to use the upload-by-URL feature. If the
+        * user is allowed, pass on permissions checking to the parent.
         */
-       static function isAllowed( $user ) {
+       public static function isAllowed( $user ) {
                if( !$user->isAllowed( 'upload_by_url' ) )
                        return 'upload_by_url';
                return parent::isAllowed( $user );
@@ -17,92 +24,148 @@ class UploadFromUrl extends UploadBase {
 
        /**
         * Checks if the upload from URL feature is enabled
+        * @return bool
         */
-       static function isEnabled() {
+       public static function isEnabled() {
                global $wgAllowCopyUploads;
                return $wgAllowCopyUploads && parent::isEnabled();
        }
 
-       /* entry point for API upload:: ASYNC_DOWNLOAD (if possible) */
-       function initialize( $name, $url, $asyncdownload = false ) {
-               global $wgTmpDirectory, $wgPhpCliPath;
-
-               // check for $asyncdownload request: 
-               if( $asyncdownload !== false){
-                       if( $wgPhpCliPath && wfShellExecEnabled() ){
-                               $this->dl_mode = Http::ASYNC_DOWNLOAD;
-                       } else {
-                               $this->dl_mode = Http::SYNC_DOWNLOAD;
-                       }
-               }
-
-               $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
-               parent::initialize( $name, $local_file, 0, true );
+       /**
+        * Entry point for API upload
+        * @return bool true on success
+        */
+       public function initialize( $name, $url, $comment, $watchlist ) {
+               global $wgUser;
 
-               $this->mUrl = trim( $url );
+               if( !Http::isValidURI( $url ) ) {
+                       return Status::newFatal( 'http-invalid-url' );
+               }
+               $params = array(
+                       "userName" => $wgUser->getName(),
+                       "userID" => $wgUser->getID(),
+                       "url" => trim( $url ),
+                       "timestamp" => wfTimestampNow(),
+                       "comment" => $comment,
+                       "watchlist" => $watchlist);
+
+               $title = Title::newFromText( $name );
+               /* // Check whether the user has the appropriate permissions to upload anyway */
+               /* $permission = $this->isAllowed( $wgUser ); */
+
+               /* if ( $permission !== true ) { */
+               /*      if ( !$wgUser->isLoggedIn() ) { */
+               /*              return Status::newFatal( 'uploadnologintext' ); */
+               /*      } else { */
+               /*              return Status::newFatal( 'badaccess-groups' ); */
+               /*      } */
+               /* } */
+
+               /* $permErrors = $this->verifyPermissions( $wgUser ); */
+               /* if ( $permErrors !== true ) { */
+               /*      return Status::newFatal( 'badaccess-groups' ); */
+               /* } */
+
+
+               $job = new UploadFromUrlJob( $title, $params );
+               return $job->insert();
        }
 
-       public function isAsync(){
-               return $this->dl_mode == Http::ASYNC_DOWNLOAD;
+       /**
+        * Initialize a queued download
+        * @param $job Job
+        */
+       public function initializeFromJob( $job ) {
+               $this->mUrl = $job->params['url'];
+               $this->mTempPath = tempnam( $wgTmpDirectory, 'COPYUPLOAD' );
+               $this->mDesiredDestName = $job->title;
+               $this->comment = $job->params['comment'];
+               $this->watchList = $job->params['watchlist'];
+               $this->getTitle();
        }
 
        /**
-        * Entry point for SpecialUpload no ASYNC_DOWNLOAD possible
+        * Entry point for SpecialUpload
         * @param $request Object: WebRequest object
         */
-       function initializeFromRequest( &$request ) {
-
-               // set dl mode if not set:
-               if( !$this->dl_mode )
-                       $this->dl_mode = Http::SYNC_DOWNLOAD;   
-
+       public function initializeFromRequest( &$request ) {
                $desiredDestName = $request->getText( 'wpDestFile' );
                if( !$desiredDestName )
-                       $desiredDestName = $request->getText( 'wpUploadFile' );
+                       $desiredDestName = $request->getText( 'wpUploadFileURL' );
                return $this->initialize(
                        $desiredDestName,
-                       $request->getVal( 'wpUploadFileURL' )
+                       $request->getVal( 'wpUploadFileURL' ),
+                       false
                );
        }
 
-       /**
-        * Do the real fetching stuff
-        */
-       function fetchFile() {
-               // entry point for SpecialUplaod 
-               if( self::isValidURI( $this->mUrl ) === false ) {
-                       return Status::newFatal( 'upload-proto-error' );
-               }
-
-               // now do the actual download to the target file:
-               $status = Http::doDownload( $this->mUrl, $this->mTempPath, $this->dl_mode );
-
-               // update the local filesize var: 
-               $this->mFileSize = filesize( $this->mTempPath );
-
-               return $status;
-       }
-
        /**
         * @param $request Object: WebRequest object
         */
-       static function isValidRequest( $request ){
+       public static function isValidRequest( $request ){
                if( !$request->getVal( 'wpUploadFileURL' ) )
                        return false;
                // check that is a valid url:
-               return self::isValidURI( $request->getVal( 'wpUploadFileURL' ) );
+               return Http::isValidURI( $request->getVal( 'wpUploadFileURL' ) );
        }
 
-       /**
-        * Checks that the given URI is a valid one
-        * @param $uri Mixed: URI to check for validity
-        */
-       static function isValidURI( $uri ){
-               return preg_match(
-                       '/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/',
-                       $uri,
-                       $matches
-               );
+       private function saveTempFile( $req ) {
+               $filename = tempnam( wfTempDir(), 'URL' );
+               if ( $filename === false ) {
+                       return Status::newFatal( 'tmp-create-error' );
+               }
+               if ( file_put_contents( $filename, $req->getContent() ) === false ) {
+                       return Status::newFatal( 'tmp-write-error' );
+               }
+
+               $this->mTempPath = $filename;
+               $this->mFileSize = filesize( $filename );
+
+               return Status::newGood();
        }
 
-}
\ No newline at end of file
+       public function doUpload() {
+               global $wgUser;
+
+               $req = HttpRequest::factory($this->mUrl);
+               $status = $req->execute();
+
+               if( !$status->isOk() ) {
+                       return $status;
+               }
+
+               $status = $this->saveTempFile( $req );
+               $this->mRemoveTempFile = true;
+
+               if( !$status->isOk() ) {
+                       return $status;
+               }
+
+               $v = $this->verifyUpload();
+               if( $v['status'] !== UploadBase::OK ) {
+                       return $this->convertVerifyErrorToStatus( $v['status'], $v['details'] );
+               }
+
+               // This has to come from API
+               /* $warnings = $this->checkForWarnings(); */
+               /* if( isset($warnings) ) return $warnings; */
+
+               // Use comment as initial page text by default
+               if ( is_null( $this->mParams['text'] ) ) {
+                       $this->mParams['text'] = $this->mParams['comment'];
+               }
+
+               $file = $this->getLocalFile();
+               // This comes from ApiBase
+               /* $watch = $this->getWatchlistValue( $this->mParams['watchlist'], $file->getTitle() ); */
+
+               if ( !$status->isGood() ) {
+                       return $status;
+               }
+
+               $status = $this->getLocalFile()->upload( $this->mTempPath, $this->comment,
+                       $this->pageText, File::DELETE_SOURCE, $this->mFileProps, false, $wgUser );
+
+               return $status;
+       }
+}