function transform($params, $flags = 0) { if (!$this->canRender()) { // show icon return parent::transform($params, $flags); } $thumbUrl = $this->repo->getThumbUrlFromCache($this->getName(), isset($params['width']) ? $params['width'] : -1, isset($params['height']) ? $params['height'] : -1); return $this->handler->getTransform($this, 'bogus', $thumbUrl, $params); }
/** * @param File $image * @param int $size * @return bool|\MediaTransformOutput */ public static function getThumbnail($image, $size = self::SHARING_THUMBNAIL_WIDTH) { if ($image) { $thumb = $image->transform(array('width' => $size)); if ($thumb && $thumb->getUrl()) { return $thumb; } } return false; }
/** * Creates an thumbnail of specified size and returns an HTML link to it * @param array $params Scaler parameters * @param $width int * @param $height int * @return string */ private function makeSizeLink($params, $width, $height) { $params['width'] = $width; $params['height'] = $height; $thumbnail = $this->displayImg->transform($params); if ($thumbnail && !$thumbnail->isError()) { return Html::rawElement('a', array('href' => $thumbnail->getUrl(), 'class' => 'mw-thumbnail-link'), wfMessage('show-big-image-size')->numParams($thumbnail->getWidth(), $thumbnail->getHeight())->parse()); } else { return ''; } }
function transform($params, $flags = 0) { if (!$this->canRender()) { // show icon return parent::transform($params, $flags); } // Note, the this->canRender() check above implies // that we have a handler, and it can do makeParamString. $otherParams = $this->handler->makeParamString($params); $thumbUrl = $this->repo->getThumbUrlFromCache($this->getName(), isset($params['width']) ? $params['width'] : -1, isset($params['height']) ? $params['height'] : -1, $otherParams); return $this->handler->getTransform($this, 'bogus', $thumbUrl, $params); }
/** * Process responsive images: add 1.5x and 2x subimages to the thumbnail, where * applicable. * * @param File $file * @param MediaTransformOutput $thumb * @param array $hp Image parameters */ public static function processResponsiveImages($file, $thumb, $hp) { global $wgResponsiveImages; if ($wgResponsiveImages && $thumb && !$thumb->isError()) { $hp15 = $hp; $hp15['width'] = round($hp['width'] * 1.5); $hp20 = $hp; $hp20['width'] = $hp['width'] * 2; if (isset($hp['height'])) { $hp15['height'] = round($hp['height'] * 1.5); $hp20['height'] = $hp['height'] * 2; } $thumb15 = $file->transform($hp15); $thumb20 = $file->transform($hp20); if ($thumb15 && !$thumb15->isError() && $thumb15->getUrl() !== $thumb->getUrl()) { $thumb->responsiveUrls['1.5'] = $thumb15->getUrl(); } if ($thumb20 && !$thumb20->isError() && $thumb20->getUrl() !== $thumb->getUrl()) { $thumb->responsiveUrls['2'] = $thumb20->getUrl(); } } }
/** * @param array $params * @param int $flags * @return bool|MediaTransformOutput */ function transform($params, $flags = 0) { if (!$this->canRender()) { // show icon return parent::transform($params, $flags); } // Note, the this->canRender() check above implies // that we have a handler, and it can do makeParamString. $otherParams = $this->handler->makeParamString($params); $width = isset($params['width']) ? $params['width'] : -1; $height = isset($params['height']) ? $params['height'] : -1; $thumbUrl = $this->repo->getThumbUrlFromCache($this->getName(), $width, $height, $otherParams); if ($thumbUrl === false) { global $wgLang; return $this->repo->getThumbError($this->getName(), $width, $height, $otherParams, $wgLang->getCode()); } return $this->handler->getTransform($this, 'bogus', $thumbUrl, $params); }
/** * @param File $file * @return string */ protected function getThumbForLine($file) { $lang = $this->getLanguage(); $user = $this->getUser(); if ($file->allowInlineDisplay() && $file->userCan(File::DELETED_FILE, $user) && !$file->isDeleted(File::DELETED_FILE)) { $params = ['width' => '120', 'height' => '120']; $timestamp = wfTimestamp(TS_MW, $file->getTimestamp()); $thumbnail = $file->transform($params); $options = ['alt' => $this->msg('filehist-thumbtext', $lang->userTimeAndDate($timestamp, $user), $lang->userDate($timestamp, $user), $lang->userTime($timestamp, $user))->text(), 'file-link' => true]; if (!$thumbnail) { return $this->msg('filehist-nothumb')->escaped(); } return $thumbnail->toHtml($options); } else { return $this->msg('filehist-nothumb')->escaped(); } }
/** * Scale a file (probably with a locally installed imagemagick, or similar) * and output it to STDOUT. * @param File $file * @param array $params Scaling parameters ( e.g. array( width => '50' ) ); * @param int $flags Scaling flags ( see File:: constants ) * @throws MWException|UploadStashFileNotFoundException * @return bool Success */ private function outputLocallyScaledThumb($file, $params, $flags) { // n.b. this is stupid, we insist on re-transforming the file every time we are invoked. We rely // on HTTP caching to ensure this doesn't happen. $flags |= File::RENDER_NOW; $thumbnailImage = $file->transform($params, $flags); if (!$thumbnailImage) { throw new MWException('Could not obtain thumbnail'); } // we should have just generated it locally if (!$thumbnailImage->getStoragePath()) { throw new UploadStashFileNotFoundException("no local path for scaled item"); } // now we should construct a File, so we can get MIME and other such info in a standard way // n.b. MIME type may be different from original (ogx original -> jpeg thumb) $thumbFile = new UnregisteredLocalFile(false, $this->stash->repo, $thumbnailImage->getStoragePath(), false); if (!$thumbFile) { throw new UploadStashFileNotFoundException("couldn't create local file object for thumbnail"); } return $this->outputLocalFile($thumbFile); }
/** * * @param File $img * @param Title $nt * @param String $text * @param String $alt * @param Title $titleLink * @param type $descQuery * @return String */ private function photoToHTML($img, $nt, $text = '', $alt = '', $titleLink = null, $descQuery = '') { $params = array('width' => $this->mPhotoWidth, 'height' => $this->mPhotoHeight); if (!$img) { $html = '<div class="CarError" style="height: ' . $params['height'] . 'px; width: ' . $params['width'] . 'px;">' . htmlspecialchars($nt->getText()) . '</div>'; } else { if ($this->mHideBadImages && wfIsBadImage($nt->getDBkey(), $this->getContextTitle())) { $html = '<div class="CarError" style="height: ' . $params['height'] . 'px; width: ' . $params['width'] . 'px;">' . Linker::link($nt, htmlspecialchars($nt->getText()), array(), array(), array('known', 'noclasses')) . '</div>'; } else { if (!($thumb = $img->transform($params))) { # Error generating thumbnail. $html = '<div class="CarError" style="height: ' . $params['height'] . 'px; width: ' . $params['width'] . 'px;">' . htmlspecialchars($img->getLastError()) . '</div>'; } else { $imageParameters = array('desc-link' => true, 'desc-query' => $descQuery, 'alt' => $alt, 'custom-title-link' => $titleLink); # In the absence of both alt text and caption, fall back on providing screen readers with the filename as alt text if ($alt == '') { $imageParameters['alt'] = $nt->getText(); } $html = $thumb->toHtml($imageParameters); // Call parser transform hook if ($this->mParser && $img->getHandler()) { $img->getHandler()->parserTransformHook($this->mParser, $img); } } } } $html .= Html::rawElement('figcaption', array(), $text); $html = Html::rawElement('figure', array(), $html); return $html; }
/** * Actually try to generate a new thumbnail * * @param File $file * @param array $params * @param string $thumbName * @param string $thumbPath * @return array (MediaTransformOutput|bool, string|bool error message HTML) */ function wfGenerateThumbnail(File $file, array $params, $thumbName, $thumbPath) { global $wgMemc, $wgAttemptFailureEpoch; $key = wfMemcKey('attempt-failures', $wgAttemptFailureEpoch, $file->getRepo()->getName(), $file->getSha1(), md5($thumbName)); // Check if this file keeps failing to render if ($wgMemc->get($key) >= 4) { return array(false, wfMessage('thumbnail_image-failure-limit', 4)); } $done = false; // Record failures on PHP fatals in addition to caching exceptions register_shutdown_function(function () use(&$done, $key) { if (!$done) { // transform() gave a fatal global $wgMemc; // Randomize TTL to reduce stampedes $wgMemc->incrWithInit($key, 3600 + mt_rand(0, 300)); } }); $thumb = false; $errorHtml = false; // guard thumbnail rendering with PoolCounter to avoid stampedes // expensive files use a separate PoolCounter config so it is possible // to set up a global limit on them if ($file->isExpensiveToThumbnail()) { $poolCounterType = 'FileRenderExpensive'; } else { $poolCounterType = 'FileRender'; } // Thumbnail isn't already there, so create the new thumbnail... try { $work = new PoolCounterWorkViaCallback($poolCounterType, sha1($file->getName()), array('doWork' => function () use($file, $params) { return $file->transform($params, File::RENDER_NOW); }, 'getCachedWork' => function () use($file, $params, $thumbPath) { // If the worker that finished made this thumbnail then use it. // Otherwise, it probably made a different thumbnail for this file. return $file->getRepo()->fileExists($thumbPath) ? $file->transform($params, File::RENDER_NOW) : false; // retry once more in exclusive mode }, 'fallback' => function () { return wfMessage('generic-pool-error')->parse(); }, 'error' => function (Status $status) { return $status->getHTML(); })); $result = $work->execute(); if ($result instanceof MediaTransformOutput) { $thumb = $result; } elseif (is_string($result)) { // error $errorHtml = $result; } } catch (Exception $e) { // Tried to select a page on a non-paged file? } /** @noinspection PhpUnusedLocalVariableInspection */ $done = true; // no PHP fatal occured if (!$thumb || $thumb->isError()) { // Randomize TTL to reduce stampedes $wgMemc->incrWithInit($key, 3600 + mt_rand(0, 300)); } return array($thumb, $errorHtml); }
/** * Process responsive images: add 1.5x and 2x subimages to the thumbnail, where * applicable. * * @param File $file * @param MediaOutput $thumb * @param array $hp image parameters */ protected static function processResponsiveImages($file, $thumb, $hp) { global $wgResponsiveImages; if ($wgResponsiveImages) { $hp15 = $hp; $hp15['width'] = round($hp['width'] * 1.5); $hp20 = $hp; $hp20['width'] = $hp['width'] * 2; if (isset($hp['height'])) { $hp15['height'] = round($hp['height'] * 1.5); $hp20['height'] = $hp['height'] * 2; } $thumb15 = $file->transform($hp15); $thumb20 = $file->transform($hp20); if ($thumb15->url !== $thumb->url) { $thumb->responsiveUrls['1.5'] = $thumb15->url; } if ($thumb20->url !== $thumb->url) { $thumb->responsiveUrls['2'] = $thumb20->url; } } }
public static function onThumbnailVideoHTML($options, $linkAttribs, $imageAttribs, File $file, &$html) { global $wgRTEParserEnabled; if (!empty($wgRTEParserEnabled)) { return true; } if (is_null(self::$isWikiaMobile)) { self::init(); } if (self::$isWikiaMobile) { wfProfileIn(__METHOD__); /** * WikiaMobile: lazy loading images in a SEO-friendly manner * @author Federico "Lox" Lucignano <federico@wikia-inc.com * @author Artur Klajnerok <*****@*****.**> */ $origImg = Xml::element('img', $imageAttribs, '', true); if (empty($imageAttribs['alt'])) { unset($imageAttribs['alt']); } //Not all 'files' have getProviderName defined if (is_callable([$file, 'getProviderName'])) { $provider = $file->getProviderName(); } else { $provider = ''; } $imageParams = array('type' => 'video', 'provider' => $provider, 'full' => $imageAttribs['src']); if (!empty($imageAttribs['data-video-key'])) { $imageParams['name'] = htmlspecialchars($imageAttribs['data-video-key']); } if (!empty($options['caption'])) { $imageParams['capt'] = 1; } // TODO: this resizes every video thumbnail with a width over 64px regardless of where it appears. // We may want to add the ability to allow custom image widths (like on the file page history table for example) $size = WikiaMobileMediaService::calculateMediaSize($file->getWidth(), $file->getHeight()); $thumb = $file->transform($size); $imageAttribs['src'] = wfReplaceImageServer($thumb->getUrl(), $file->getTimestamp()); $imageAttribs['width'] = $size['width']; $imageAttribs['height'] = $size['height']; $data = ['attributes' => $imageAttribs, 'parameters' => [$imageParams], 'anchorAttributes' => $linkAttribs, 'noscript' => $origImg, 'isSmall' => WikiaMobileMediaService::isSmallImage($imageAttribs['width'], $imageAttribs['height'])]; $title = $file->getTitle()->getDBKey(); $titleText = $file->getTitle()->getText(); $views = MediaQueryService::getTotalVideoViewsByTitle($title); $data['content'] = Xml::element('span', ['class' => 'videoInfo'], "{$titleText} (" . $file->getHandler()->getFormattedDuration() . ", " . wfMessage('wikiamobile-video-views-counter', $views)->inContentLanguage()->text() . ')'); $html = F::app()->sendRequest('WikiaMobileMediaService', 'renderImageTag', $data, true)->toString(); wfProfileOut(__METHOD__); } return true; }
public function onThumbnailVideoHTML($options, $linkAttribs, $imageAttribs, File $file, &$html) { $this->wf->profileIn(__METHOD__); if (self::$isWikiaMobile) { /** * WikiaMobile: lazy loading images in a SEO-friendly manner * @author Federico "Lox" Lucignano <federico@wikia-inc.com * @author Artur Klajnerok <*****@*****.**> */ $origImg = Xml::element('img', $imageAttribs, '', true); if (empty($imageAttribs['alt'])) { unset($imageAttribs['alt']); } $imageParams = array('type' => 'video', 'full' => $imageAttribs['src']); if (!empty($linkAttribs['data-video-name'])) { $imageParams['name'] = $linkAttribs['data-video-name']; } if (!empty($options['caption'])) { $imageParams['capt'] = true; } if ($file instanceof File) { $size = WikiaMobileMediaService::calculateMediaSize($file->getWidth(), $file->getHeight()); $thumb = $file->transform($size); $imageAttribs['src'] = wfReplaceImageServer($thumb->getUrl(), $file->getTimestamp()); $imageAttribs['width'] = $size['width']; $imageAttribs['height'] = $size['height']; } $data = array('attributes' => $imageAttribs, 'parameters' => array($imageParams), 'anchorAttributes' => $linkAttribs, 'noscript' => $origImg); if ($file instanceof File) { $title = $file->getTitle()->getDBKey(); $titleText = $file->getTitle()->getText(); $data['content'] = Xml::element('span', array('class' => 'videoInfo'), "{$titleText} (" . $file->getHandler()->getFormattedDuration() . ", " . $this->wf->MsgForContent('wikiamobile-video-views-counter', MediaQueryService::getTotalVideoViewsByTitle($title)) . ')'); } $html = $this->app->sendRequest('WikiaMobileMediaService', 'renderImageTag', $data, true)->toString(); } $this->wf->profileOut(__METHOD__); return true; }