MediaWiki  master
PublishStashedFileJob.php
Go to the documentation of this file.
1 <?php
21 use Wikimedia\ScopedCallback;
22 
29 class PublishStashedFileJob extends Job {
30  public function __construct( Title $title, array $params ) {
31  parent::__construct( 'PublishStashedFile', $title, $params );
32  $this->removeDuplicates = true;
33  }
34 
35  public function run() {
36  $scope = RequestContext::importScopedSession( $this->params['session'] );
37  $this->addTeardownCallback( static function () use ( &$scope ) {
38  ScopedCallback::consume( $scope ); // T126450
39  } );
40 
41  $context = RequestContext::getMain();
42  $user = $context->getUser();
43  try {
44  if ( !$user->isRegistered() ) {
45  $this->setLastError( "Could not load the author user from session." );
46 
47  return false;
48  }
49 
51  $user,
52  $this->params['filekey'],
53  [ 'result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood() ]
54  );
55 
56  $upload = new UploadFromStash( $user );
57  // @todo initialize() causes a GET, ideally we could frontload the antivirus
58  // checks and anything else to the stash stage (which includes concatenation and
59  // the local file is thus already there). That way, instead of GET+PUT, there could
60  // just be a COPY operation from the stash to the public zone.
61  $upload->initialize( $this->params['filekey'], $this->params['filename'] );
62 
63  // Check if the local file checks out (this is generally a no-op)
64  $verification = $upload->verifyUpload();
65  if ( $verification['status'] !== UploadBase::OK ) {
66  $status = Status::newFatal( 'verification-error' );
67  $status->value = [ 'verification' => $verification ];
69  $user,
70  $this->params['filekey'],
71  [ 'result' => 'Failure', 'stage' => 'publish', 'status' => $status ]
72  );
73  $this->setLastError( "Could not verify upload." );
74 
75  return false;
76  }
77 
78  // Upload the stashed file to a permanent location
79  $status = $upload->performUpload(
80  $this->params['comment'],
81  $this->params['text'],
82  $this->params['watch'],
83  $user,
84  $this->params['tags'] ?? [],
85  $this->params['watchlistexpiry'] ?? null
86  );
87  if ( !$status->isGood() ) {
89  $user,
90  $this->params['filekey'],
91  [ 'result' => 'Failure', 'stage' => 'publish', 'status' => $status ]
92  );
93  $this->setLastError( $status->getWikiText( false, false, 'en' ) );
94 
95  return false;
96  }
97 
98  // Build the image info array while we have the local reference handy
99  $apiMain = new ApiMain(); // dummy object (XXX)
100  $imageInfo = $upload->getImageInfo( $apiMain->getResult() );
101 
102  // Cleanup any temporary local file
103  $upload->cleanupTempFile();
104 
105  // Cache the info so the user doesn't have to wait forever to get the final info
107  $user,
108  $this->params['filekey'],
109  [
110  'result' => 'Success',
111  'stage' => 'publish',
112  'filename' => $upload->getLocalFile()->getName(),
113  'imageinfo' => $imageInfo,
114  'status' => Status::newGood()
115  ]
116  );
117  } catch ( Exception $e ) {
119  $user,
120  $this->params['filekey'],
121  [
122  'result' => 'Failure',
123  'stage' => 'publish',
124  'status' => Status::newFatal( 'api-error-publishfailed' )
125  ]
126  );
127  $this->setLastError( get_class( $e ) . ": " . $e->getMessage() );
128  // To prevent potential database referential integrity issues.
129  // See T34551.
131 
132  return false;
133  }
134 
135  return true;
136  }
137 
138  public function getDeduplicationInfo() {
139  $info = parent::getDeduplicationInfo();
140  if ( is_array( $info['params'] ) ) {
141  $info['params'] = [ 'filekey' => $info['params']['filekey'] ];
142  }
143 
144  return $info;
145  }
146 
147  public function allowRetries() {
148  return false;
149  }
150 }
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:55
Class to both describe a background job and handle jobs.
Definition: Job.php:39
Title $title
Definition: Job.php:50
setLastError( $error)
Definition: Job.php:469
addTeardownCallback( $callback)
Definition: Job.php:395
array $params
Array of job parameters.
Definition: Job.php:44
static rollbackPrimaryChangesAndLog(Throwable $e, $catcher=self::CAUGHT_BY_OTHER)
Roll back any open database transactions and log the stack trace of the throwable.
Upload a file from the upload stash into the local file repo.
allowRetries()
bool Whether this job can be retried on failure by job runners 1.21Stability: stableto override
getDeduplicationInfo()
Subclasses may need to override this to make duplication detection work.
__construct(Title $title, array $params)
static importScopedSession(array $params)
Import an client IP address, HTTP headers, user ID, and session ID.
static getMain()
Get the RequestContext object associated with the main request.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:73
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:85
Represents a title within MediaWiki.
Definition: Title.php:52
static setSessionStatus(UserIdentity $user, $statusKey, $value)
Set the current status of a chunked upload (used for polling)
Implements uploading from previously stored file.