37 public function run() {
38 $scope = RequestContext::importScopedSession( $this->params[
'session'] );
40 ScopedCallback::consume( $scope );
43 $logger = LoggerFactory::getInstance(
'upload' );
44 $context = RequestContext::getMain();
45 $user = $context->getUser();
47 if ( !$user->isRegistered() ) {
48 $this->
setLastError(
"Could not load the author user from session." );
54 $startingStatus = UploadBase::getSessionStatus( $user, $this->params[
'filekey'] );
57 ( $startingStatus[
'result'] ??
'' ) !==
'Poll' ||
58 ( $startingStatus[
'stage'] ??
'' ) !==
'queued'
60 $logger->warning(
"Tried to assemble upload that is in stage {stage}/{result}",
62 'stage' => $startingStatus[
'stage'] ??
'-',
63 'result' => $startingStatus[
'result'] ??
'-',
64 'status' => (
string)( $startingStatus[
'status'] ??
'-' ),
65 'filekey' => $this->params[
'filekey'],
66 'filename' => $this->params[
'filename'],
67 'user' => $user->getName(),
75 $startingStatus[
'stage'] ===
'assembling' &&
76 $startingStatus[
'result'] !==
'Failure'
78 $this->
setLastError( __METHOD__ .
" already in progress" );
82 UploadBase::setSessionStatus(
84 $this->params[
'filekey'],
85 [
'result' =>
'Poll',
'stage' =>
'assembling',
'status' => Status::newGood() ]
89 $upload->continueChunks(
90 $this->params[
'filename'],
91 $this->params[
'filekey'],
95 isset( $this->params[
'filesize'] ) &&
96 $this->params[
'filesize'] !== (
int)$upload->getOffset()
100 throw new UnexpectedValueException(
101 "UploadStash file size does not match job's. Potential mis-nested transaction?"
105 $status = $upload->concatenateChunks();
106 if ( !$status->isGood() ) {
107 UploadBase::setSessionStatus(
109 $this->params[
'filekey'],
110 [
'result' =>
'Failure',
'stage' =>
'assembling',
'status' => $status ]
112 $logger->info(
"Chunked upload assembly job failed for {filekey} because {status}",
114 'filekey' => $this->params[
'filekey'],
115 'filename' => $this->params[
'filename'],
116 'user' => $user->getName(),
117 'status' => (
string)$status
127 $status = Status::newGood();
129 'warnings' => UploadBase::makeWarningsSerializable(
140 $upload->stash->removeFileNoAuth( $this->params[
'filekey'] );
143 $apiUpload = ApiUpload::getDummyInstance();
144 $imageInfo = $apiUpload->getUploadImageInfo( $upload );
150 UploadBase::setSessionStatus(
152 $this->params[
'filekey'],
154 'result' =>
'Success',
155 'stage' =>
'assembling',
156 'filekey' => $newFileKey,
157 'imageinfo' => $imageInfo,
161 $logger->info(
"{filekey} successfully assembled into {newkey}",
163 'filekey' => $this->params[
'filekey'],
164 'newkey' => $newFileKey,
165 'filename' => $this->params[
'filename'],
166 'user' => $user->getName(),
167 'status' => (
string)$status
171 UploadBase::setSessionStatus(
173 $this->params[
'filekey'],
175 'result' =>
'Failure',
176 'stage' =>
'assembling',
180 $this->
setLastError( get_class( $e ) .
": " . $e->getMessage() );
182 }
catch ( Exception $e ) {
183 UploadBase::setSessionStatus(
185 $this->params[
'filekey'],
187 'result' =>
'Failure',
188 'stage' =>
'assembling',
189 'status' => Status::newFatal(
'api-error-stashfailed' )
192 $this->
setLastError( get_class( $e ) .
": " . $e->getMessage() );
194 MWExceptionHandler::rollbackPrimaryChangesAndLog( $e );