MediaWiki  master
ThumbnailRenderJob.php
Go to the documentation of this file.
1 <?php
23 
29 class ThumbnailRenderJob extends Job {
30  public function __construct( Title $title, array $params ) {
31  parent::__construct( 'ThumbnailRender', $title, $params );
32  }
33 
34  public function run() {
35  $uploadThumbnailRenderMethod = MediaWikiServices::getInstance()
36  ->getMainConfig()->get( MainConfigNames::UploadThumbnailRenderMethod );
37 
38  $transformParams = $this->params['transformParams'];
39 
40  $file = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
41  ->newFile( $this->title );
42  $file->load( File::READ_LATEST );
43 
44  if ( $file && $file->exists() ) {
45  if ( $uploadThumbnailRenderMethod === 'jobqueue' ) {
46  $thumb = $file->transform( $transformParams, File::RENDER_NOW );
47 
48  if ( !$thumb || $thumb->isError() ) {
49  if ( $thumb instanceof MediaTransformError ) {
50  $this->setLastError( __METHOD__ . ': thumbnail couln\'t be generated:' .
51  $thumb->toText() );
52  } else {
53  $this->setLastError( __METHOD__ . ': thumbnail couln\'t be generated' );
54  }
55  return false;
56  }
57  return true;
58  } elseif ( $uploadThumbnailRenderMethod === 'http' ) {
59  return $this->hitThumbUrl( $file, $transformParams );
60  } else {
61  $this->setLastError( __METHOD__ . ': unknown thumbnail render method ' .
62  $uploadThumbnailRenderMethod );
63  return false;
64  }
65  } else {
66  $this->setLastError( __METHOD__ . ': file doesn\'t exist' );
67  return false;
68  }
69  }
70 
76  protected function hitThumbUrl( LocalFile $file, $transformParams ) {
77  $config = MediaWikiServices::getInstance()->getMainConfig();
78  $uploadThumbnailRenderHttpCustomHost =
79  $config->get( MainConfigNames::UploadThumbnailRenderHttpCustomHost );
80  $uploadThumbnailRenderHttpCustomDomain =
81  $config->get( MainConfigNames::UploadThumbnailRenderHttpCustomDomain );
82  $handler = $file->getHandler();
83  if ( !$handler ) {
84  $this->setLastError( __METHOD__ . ': could not get handler' );
85  return false;
86  } elseif ( !$handler->normaliseParams( $file, $transformParams ) ) {
87  $this->setLastError( __METHOD__ . ': failed to normalize' );
88  return false;
89  }
90  $thumbName = $file->thumbName( $transformParams );
91  $thumbUrl = $file->getThumbUrl( $thumbName );
92 
93  if ( $thumbUrl === null ) {
94  $this->setLastError( __METHOD__ . ': could not get thumb URL' );
95  return false;
96  }
97 
98  if ( $uploadThumbnailRenderHttpCustomDomain ) {
99  $parsedUrl = wfParseUrl( $thumbUrl );
100 
101  if ( !isset( $parsedUrl['path'] ) || $parsedUrl['path'] === '' ) {
102  $this->setLastError( __METHOD__ . ": invalid thumb URL: $thumbUrl" );
103  return false;
104  }
105 
106  $thumbUrl = '//' . $uploadThumbnailRenderHttpCustomDomain . $parsedUrl['path'];
107  }
108 
109  wfDebug( __METHOD__ . ": hitting url {$thumbUrl}" );
110 
111  // T203135 We don't wait for the request to complete, as this is mostly fire & forget.
112  // Looking at the HTTP status of requests that take less than 1s is a double check.
113  $request = MediaWikiServices::getInstance()->getHttpRequestFactory()->create(
114  $thumbUrl,
115  [ 'method' => 'HEAD', 'followRedirects' => true, 'timeout' => 1 ],
116  __METHOD__
117  );
118 
119  if ( $uploadThumbnailRenderHttpCustomHost ) {
120  $request->setHeader( 'Host', $uploadThumbnailRenderHttpCustomHost );
121  }
122 
123  $status = $request->execute();
124  $statusCode = $request->getStatus();
125  wfDebug( __METHOD__ . ": received status {$statusCode}" );
126 
127  // 400 happens when requesting a size greater or equal than the original
128  // TODO use proper error signaling. 400 could mean a number of other things.
129  if ( $statusCode === 200 || $statusCode === 301 || $statusCode === 302 || $statusCode === 400 ) {
130  return true;
131  } elseif ( $statusCode ) {
132  $this->setLastError( __METHOD__ . ": incorrect HTTP status $statusCode when hitting $thumbUrl" );
133  } elseif ( $status->hasMessage( 'http-timed-out' ) ) {
134  // T203135 we ignore timeouts, as it would be inefficient for this job to wait for
135  // minutes for the slower thumbnails to complete.
136  return true;
137  } else {
138  $this->setLastError( __METHOD__ . ': HTTP request failure: '
139  . Status::wrap( $status )->getWikiText( false, false, 'en' ) );
140  }
141  return false;
142  }
143 
148  public function allowRetries() {
149  // ThumbnailRenderJob is a warmup for the thumbnails cache,
150  // so loosing it is not a problem. Most times the job fails
151  // for non-renderable or missing images which will not be fixed
152  // by a retry, but will create additional load on the renderer.
153  return false;
154  }
155 }
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
const RENDER_NOW
Force rendering in the current process.
Definition: File.php:77
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
array $params
Array of job parameters.
Definition: Job.php:44
Local file in the wiki's own database.
Definition: LocalFile.php:59
Basic media transform error class.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:63
Job for asynchronous rendering of thumbnails, e.g.
__construct(Title $title, array $params)
hitThumbUrl(LocalFile $file, $transformParams)
allowRetries()
Whether to retry the job.
Represents a title within MediaWiki.
Definition: Title.php:52
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42