3 * Implements uploading from previously stored file.
7 * @author Bryan Tong Minh
10 class UploadFromStash
extends UploadBase
{
11 protected $mFileKey, $mVirtualTempPath, $mFileProps, $mSourceType;
13 // an instance of UploadStash
21 * @param $stash UploadStash
22 * @param $repo FileRepo
24 public function __construct( $user = false, $stash = false, $repo = false ) {
25 // user object. sometimes this won't exist, as when running from cron.
31 $this->repo
= RepoGroup
::singleton()->getLocalRepo();
35 $this->stash
= $stash;
38 wfDebug( __METHOD__
. " creating new UploadStash instance for " . $user->getId() . "\n" );
40 wfDebug( __METHOD__
. " creating new UploadStash instance with no user\n" );
43 $this->stash
= new UploadStash( $this->repo
, $this->user
);
53 public static function isValidKey( $key ) {
54 // this is checked in more detail in UploadStash
55 return (bool)preg_match( UploadStash
::KEY_FORMAT_REGEX
, $key );
59 * @param $request WebRequest
63 public static function isValidRequest( $request ) {
64 // this passes wpSessionKey to getText() as a default when wpFileKey isn't set.
65 // wpSessionKey has no default which guarantees failure if both are missing
66 // (though that should have been caught earlier)
67 return self
::isValidKey( $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) ) );
74 public function initialize( $key, $name = 'upload_file' ) {
76 * Confirming a temporarily stashed upload.
77 * We don't want path names to be forged, so we keep
78 * them in the session on the server and just give
79 * an opaque key to the user agent.
81 $metadata = $this->stash
->getMetadata( $key );
82 $this->initializePathInfo( $name,
83 $this->getRealPath ( $metadata['us_path'] ),
88 $this->mFileKey
= $key;
89 $this->mVirtualTempPath
= $metadata['us_path'];
90 $this->mFileProps
= $this->stash
->getFileProps( $key );
91 $this->mSourceType
= $metadata['us_source_type'];
95 * @param $request WebRequest
97 public function initializeFromRequest( &$request ) {
98 // sends wpSessionKey as a default when wpFileKey is missing
99 $fileKey = $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) );
101 // chooses one of wpDestFile, wpUploadFile, filename in that order.
102 $desiredDestName = $request->getText( 'wpDestFile', $request->getText( 'wpUploadFile', $request->getText( 'filename' ) ) );
104 return $this->initialize( $fileKey, $desiredDestName );
110 public function getSourceType() {
111 return $this->mSourceType
;
115 * File has been previously verified so no need to do so again.
119 protected function verifyFile() {
126 * @return UploadStashFile
128 public function stashFile() {
129 // replace mLocalFile with an instance of UploadStashFile, which adds some methods
130 // that are useful for stashed files.
131 $this->mLocalFile
= parent
::stashFile();
132 return $this->mLocalFile
;
136 * This should return the key instead of the UploadStashFile instance, for backward compatibility.
139 public function stashSession() {
140 return $this->stashFile()->getFileKey();
144 * Remove a temporarily kept file stashed by saveTempUploadedFile().
147 public function unsaveUploadedFile() {
148 return $this->stash
->removeFile( $this->mFileKey
);
152 * Perform the upload, then remove the database record afterward.
153 * @param $comment string
154 * @param $pageText string
159 public function performUpload( $comment, $pageText, $watch, $user ) {
160 $rv = parent
::performUpload( $comment, $pageText, $watch, $user );
161 $this->unsaveUploadedFile();
166 * Append a chunk to the temporary file.
173 public function appendChunk( $chunk, $chunkSize, $offset ) {
174 //to use $this->getFileSize() here, db needs to be updated
175 //in appendToUploadFile for that
176 $fileSize = $this->stash
->getFile( $this->mFileKey
)->getSize();
177 if ( $fileSize +
$chunkSize > $this->getMaxUploadSize()) {
178 $status = Status
::newFatal( 'file-too-large' );
181 if ( $fileSize == $offset ) {
182 $status = $this->appendToUploadFile( $chunk,
183 $this->mVirtualTempPath
);
185 $status = Status
::newFatal( 'invalid-chunk-offset' );
192 * Append the final chunk and ready file for parent::performUpload()
195 public function finalizeFile() {
196 $this->appendFinish ( $this->mVirtualTempPath
);
197 $this->cleanupTempFile();
198 $this->mTempPath
= $this->getRealPath( $this->mVirtualTempPath
);