40 public function run() {
41 $scope = RequestContext::importScopedSession( $this->params[
'session'] );
43 ScopedCallback::consume( $scope );
46 $logger = LoggerFactory::getInstance(
'upload' );
47 $context = RequestContext::getMain();
48 $user = $context->getUser();
50 if ( !$user->isRegistered() ) {
51 $this->
setLastError(
"Could not load the author user from session." );
57 $startingStatus = UploadBase::getSessionStatus( $user, $this->params[
'filekey'] );
60 ( $startingStatus[
'result'] ??
'' ) !==
'Poll' ||
61 ( $startingStatus[
'stage'] ??
'' ) !==
'queued'
63 $logger->warning(
"Tried to assemble upload that is in stage {stage}/{result}",
65 'stage' => $startingStatus[
'stage'] ??
'-',
66 'result' => $startingStatus[
'result'] ??
'-',
67 'status' => (
string)( $startingStatus[
'status'] ??
'-' ),
68 'filekey' => $this->params[
'filekey'],
69 'filename' => $this->params[
'filename'],
70 'user' => $user->getName(),
78 $startingStatus[
'stage'] ===
'assembling' &&
79 $startingStatus[
'result'] !==
'Failure'
81 $this->
setLastError( __METHOD__ .
" already in progress" );
85 UploadBase::setSessionStatus(
87 $this->params[
'filekey'],
88 [
'result' =>
'Poll',
'stage' =>
'assembling',
'status' => Status::newGood() ]
92 $upload->continueChunks(
93 $this->params[
'filename'],
94 $this->params[
'filekey'],
98 isset( $this->params[
'filesize'] ) &&
99 $this->params[
'filesize'] !== (
int)$upload->getOffset()
103 throw new UnexpectedValueException(
104 "UploadStash file size does not match job's. Potential mis-nested transaction?"
108 $status = $upload->concatenateChunks();
109 if ( !$status->isGood() ) {
110 UploadBase::setSessionStatus(
112 $this->params[
'filekey'],
113 [
'result' =>
'Failure',
'stage' =>
'assembling',
'status' => $status ]
115 $logger->info(
"Chunked upload assembly job failed for {filekey} because {status}",
117 'filekey' => $this->params[
'filekey'],
118 'filename' => $this->params[
'filename'],
119 'user' => $user->getName(),
120 'status' => (
string)$status
130 $status = Status::newGood();
132 'warnings' => UploadBase::makeWarningsSerializable(
143 $upload->stash->removeFileNoAuth( $this->params[
'filekey'] );
146 $apiUpload = ApiUpload::getDummyInstance();
147 $imageInfo = $apiUpload->getUploadImageInfo( $upload );
153 UploadBase::setSessionStatus(
155 $this->params[
'filekey'],
157 'result' =>
'Success',
158 'stage' =>
'assembling',
159 'filekey' => $newFileKey,
160 'imageinfo' => $imageInfo,
164 $logger->info(
"{filekey} successfully assembled into {newkey}",
166 'filekey' => $this->params[
'filekey'],
167 'newkey' => $newFileKey,
168 'filename' => $this->params[
'filename'],
169 'user' => $user->getName(),
170 'status' => (
string)$status
173 }
catch ( Exception $e ) {
174 UploadBase::setSessionStatus(
176 $this->params[
'filekey'],
178 'result' =>
'Failure',
179 'stage' =>
'assembling',
180 'status' => Status::newFatal(
'api-error-stashfailed' )
183 $this->
setLastError( get_class( $e ) .
": " . $e->getMessage() );
185 MWExceptionHandler::rollbackPrimaryChangesAndLog( $e );