X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fupload%2FUploadFromStash.php;h=a2f9be59c6b6126b559c0af7e444183b7103d502;hb=53f3c48a954ce36c892f85b3f92e03afeaa4c1ae;hp=50974c329ca8b741ffd282dbf5ab6825ad07f928;hpb=baf83f74b8ec77a4a7a9ccb5195f80ec2243a7d7;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/upload/UploadFromStash.php b/includes/upload/UploadFromStash.php index 50974c329c..a2f9be59c6 100644 --- a/includes/upload/UploadFromStash.php +++ b/includes/upload/UploadFromStash.php @@ -8,16 +8,37 @@ */ class UploadFromStash extends UploadBase { + protected $mFileKey, $mVirtualTempPath, $mFileProps, $mSourceType; + + // an instance of UploadStash + private $stash; + + //LocalFile repo + private $repo; + + public function __construct( $user = false, $stash = false, $repo = false ) { + // user object. sometimes this won't exist, as when running from cron. + $this->user = $user; - protected $initializePathInfo, $mSessionKey, $mVirtualTempPath, - $mFileProps, $mSourceType; + if( $repo ) { + $this->repo = $repo; + } else { + $this->repo = RepoGroup::singleton()->getLocalRepo(); + } - public static function isValidSessionKey( $key, $sessionData ) { - return !empty( $key ) && - is_array( $sessionData ) && - isset( $sessionData[$key] ) && - isset( $sessionData[$key]['version'] ) && - $sessionData[$key]['version'] == UploadBase::SESSION_VERSION; + if( $stash ) { + $this->stash = $stash; + } else { + wfDebug( __METHOD__ . " creating new UploadStash instance for " . $user->getId() . "\n" ); + $this->stash = new UploadStash( $this->repo, $this->user ); + } + + return true; + } + + public static function isValidKey( $key ) { + // this is checked in more detail in UploadStash + return preg_match( UploadStash::KEY_FORMAT_REGEX, $key ) ? true : false; } /** @@ -26,45 +47,43 @@ class UploadFromStash extends UploadBase { * @return Boolean */ public static function isValidRequest( $request ) { - $sessionData = $request->getSessionData( UploadBase::SESSION_KEYNAME ); - return self::isValidSessionKey( - $request->getText( 'wpSessionKey' ), - $sessionData - ); + // this passes wpSessionKey to getText() as a default when wpFileKey isn't set. + // wpSessionKey has no default which guarantees failure if both are missing + // (though that should have been caught earlier) + return self::isValidKey( $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) ) ); } - public function initialize( $name, $sessionKey, $sessionData ) { + public function initialize( $key, $name = 'upload_file' ) { /** * 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. - */ - + */ + $metadata = $this->stash->getMetadata( $key ); $this->initializePathInfo( $name, - $this->getRealPath ( $sessionData['mTempPath'] ), - $sessionData['mFileSize'], + $this->getRealPath ( $metadata['us_path'] ), + $metadata['us_size'], false ); - $this->mSessionKey = $sessionKey; - $this->mVirtualTempPath = $sessionData['mTempPath']; - $this->mFileProps = $sessionData['mFileProps']; - $this->mSourceType = isset( $sessionData['mSourceType'] ) ? - $sessionData['mSourceType'] : null; + $this->mFileKey = $key; + $this->mVirtualTempPath = $metadata['us_path']; + $this->mFileProps = $this->stash->getFileProps( $key ); + $this->mSourceType = $metadata['us_source_type']; } /** * @param $request WebRequest */ public function initializeFromRequest( &$request ) { - $sessionKey = $request->getText( 'wpSessionKey' ); - $sessionData = $request->getSessionData( UploadBase::SESSION_KEYNAME ); + // sends wpSessionKey as a default when wpFileKey is missing + $fileKey = $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) ); + + // chooses one of wpDestFile, wpUploadFile, filename in that order. + $desiredDestName = $request->getText( 'wpDestFile', $request->getText( 'wpUploadFile', $request->getText( 'filename' ) ) ); - $desiredDestName = $request->getText( 'wpDestFile' ); - if( !$desiredDestName ) - $desiredDestName = $request->getText( 'wpUploadFile' ); - return $this->initialize( $desiredDestName, $sessionKey, $sessionData[$sessionKey] ); + return $this->initialize( $fileKey, $desiredDestName ); } public function getSourceType() { @@ -73,6 +92,8 @@ class UploadFromStash extends UploadBase { /** * File has been previously verified so no need to do so again. + * + * @return bool */ protected function verifyFile() { return true; @@ -81,10 +102,18 @@ class UploadFromStash extends UploadBase { /** * There is no need to stash the image twice */ - public function stashSession( $key = null ) { - if ( !empty( $this->mSessionKey ) ) - return $this->mSessionKey; - return parent::stashSession(); + public function stashFile() { + if ( $this->mLocalFile ) { + return $this->mLocalFile; + } + return parent::stashFile(); + } + + /** + * Alias for stashFile + */ + public function stashSession() { + return $this->stashFile(); } /** @@ -92,9 +121,48 @@ class UploadFromStash extends UploadBase { * @return success */ public function unsaveUploadedFile() { - $repo = RepoGroup::singleton()->getLocalRepo(); - $success = $repo->freeTemp( $this->mVirtualTempPath ); - return $success; + return $this->stash->removeFile( $this->mFileKey ); } -} \ No newline at end of file + /** + * Perform the upload, then remove the database record afterward. + */ + public function performUpload( $comment, $pageText, $watch, $user ) { + $rv = parent::performUpload( $comment, $pageText, $watch, $user ); + $this->unsaveUploadedFile(); + return $rv; + } + + /** + * Append a chunk to the temporary file. + * + * @return void + */ + public function appendChunk($chunk, $chunkSize, $offset) { + //to use $this->getFileSize() here, db needs to be updated + //in appendToUploadFile for that + $fileSize = $this->stash->getFile( $this->mFileKey )->getSize(); + if ( $fileSize + $chunkSize > $this->getMaxUploadSize()) { + $status = Status::newFatal( 'file-too-large' ); + } else { + //append chunk + if ( $fileSize == $offset ) { + $status = $this->appendToUploadFile( $chunk, + $this->mVirtualTempPath ); + } else { + $status = Status::newFatal( 'invalid-chunk-offset' ); + } + } + return $status; + } + + /** + * Append the final chunk and ready file for parent::performUpload() + * @return void + */ + public function finalizeFile() { + $this->appendFinish ( $this->mVirtualTempPath ); + $this->cleanupTempFile(); + $this->mTempPath = $this->getRealPath( $this->mVirtualTempPath ); + } +}