49 public function run() {
50 $scope = RequestContext::importScopedSession( $this->params[
'session'] );
52 ScopedCallback::consume( $scope );
55 $logger = LoggerFactory::getInstance(
'upload' );
56 $context = RequestContext::getMain();
57 $user = $context->getUser();
59 if ( !$user->isRegistered() ) {
60 $this->
setLastError(
"Could not load the author user from session." );
66 $startingStatus = UploadBase::getSessionStatus( $user, $this->params[
'filekey'] );
69 ( $startingStatus[
'result'] ??
'' ) !==
'Poll' ||
70 ( $startingStatus[
'stage'] ??
'' ) !==
'queued'
72 $logger->warning(
"Tried to assemble upload that is in stage {stage}/{result}",
74 'stage' => $startingStatus[
'stage'] ??
'-',
75 'result' => $startingStatus[
'result'] ??
'-',
76 'status' => (
string)( $startingStatus[
'status'] ??
'-' ),
77 'filekey' => $this->params[
'filekey'],
78 'filename' => $this->params[
'filename'],
79 'user' => $user->getName(),
87 $startingStatus[
'stage'] ===
'assembling' &&
88 $startingStatus[
'result'] !==
'Failure'
90 $this->
setLastError( __METHOD__ .
" already in progress" );
94 UploadBase::setSessionStatus(
96 $this->params[
'filekey'],
97 [
'result' =>
'Poll',
'stage' =>
'assembling',
'status' => Status::newGood() ]
101 $upload->continueChunks(
102 $this->params[
'filename'],
103 $this->params[
'filekey'],
107 isset( $this->params[
'filesize'] ) &&
108 $this->params[
'filesize'] !== (
int)$upload->getOffset()
112 throw new UnexpectedValueException(
113 "UploadStash file size does not match job's. Potential mis-nested transaction?"
117 $status = $upload->concatenateChunks();
118 if ( !$status->isGood() ) {
119 UploadBase::setSessionStatus(
121 $this->params[
'filekey'],
122 [
'result' =>
'Failure',
'stage' =>
'assembling',
'status' => $status ]
124 $logger->info(
"Chunked upload assembly job failed for {filekey} because {status}",
126 'filekey' => $this->params[
'filekey'],
127 'filename' => $this->params[
'filename'],
128 'user' => $user->getName(),
129 'status' => (
string)$status
139 $status = Status::newGood();
141 'warnings' => UploadBase::makeWarningsSerializable(
152 $upload->stash->removeFileNoAuth( $this->params[
'filekey'] );
155 $apiUpload = ApiUpload::getDummyInstance();
156 $imageInfo = $apiUpload->getUploadImageInfo( $upload );
162 UploadBase::setSessionStatus(
164 $this->params[
'filekey'],
166 'result' =>
'Success',
167 'stage' =>
'assembling',
168 'filekey' => $newFileKey,
169 'imageinfo' => $imageInfo,
173 $logger->info(
"{filekey} successfully assembled into {newkey}",
175 'filekey' => $this->params[
'filekey'],
176 'newkey' => $newFileKey,
177 'filename' => $this->params[
'filename'],
178 'user' => $user->getName(),
179 'status' => (
string)$status
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 );