/** * Return a HTML representation of the image gallery * * The new gallery disables the old perrow control, and automatically fit the gallery to the available space in the browser. */ private function renderGallery() { wfProfileIn(__METHOD__); // do not render empty gallery if (empty($this->mFiles)) { wfProfileOut(__METHOD__); return ''; } // Route to the mobile gallery or the new MediaGallery if (F::app()->checkSkin('wikiamobile')) { $html = $this->renderWikiaMobileMediaGroup(); wfProfileOut(__METHOD__); return $html; } elseif ($this->canRenderMediaGallery()) { $html = $this->renderMediaGallery(); // remove spaces from html produced by mustache template $html = trim(preg_replace('/\\n+/', ' ', $html)); wfProfileOut(__METHOD__); return $html; } /** @var Skin|Linker $skin The skin object falls back to Linker methods via __call */ $skin = RequestContext::getMain()->getSkin(); $thumbSize = $this->mWidths; $orientation = $this->getParam('orientation'); $ratio = WikiaPhotoGalleryHelper::getRatioFromOption($orientation); $crop = $this->mCrop; //calculate height of the biggest image $maxHeight = 0; $fileObjectsCache = array(); $heights = array(); $widths = array(); $thumbParams = array(); // loop through the images and get height of the tallest one foreach ($this->mFiles as $imageData) { $img = $this->getImage($imageData[0]); $fileObjectsCache[] = $img; if (!empty($img)) { // get thumbnail limited only by given width if ($img->width > $thumbSize) { $imageHeight = round($img->height * ($thumbSize / $img->width)); $imageWidth = $thumbSize; } else { $imageHeight = $img->height; $imageWidth = $img->width; } $heights[] = $imageHeight; $widths[] = $imageWidth; if ($imageHeight > $maxHeight) { $maxHeight = $imageHeight; } } } // calculate height based on gallery width $height = round($thumbSize / $ratio); if ($orientation == 'none') { $this->enableCropping($crop = false); // use the biggest height found if ($maxHeight > 0) { $height = $maxHeight; } // limit height (RT #59355) $height = min($height, $thumbSize); // recalculate dimensions (RT #59355) foreach ($this->mFiles as $index => $image) { if (!empty($heights[$index]) && !empty($widths[$index])) { //fix #59355, min() added to let borders wrap images with smaller width //fix #63886, round ( $tmpFloat ) != floor ( $tmpFloat ) added to check if thumbnail will be generated from proper width $tmpFloat = $widths[$index] * $height / $heights[$index]; $widths[$index] = min($widths[$index], floor($tmpFloat)); $heights[$index] = min($height, $heights[$index]); if (round($tmpFloat) != floor($tmpFloat)) { $heights[$index]--; } } else { $widths[$index] = $thumbSize; $heights[$index] = $height; } } } $useBuckets = $this->getParam('buckets'); $useRowDivider = $this->getParam('rowdivider'); $captionColor = $this->getParam('captiontextcolor'); $borderColor = $this->getParam('bordercolor'); $perRow = $this->mPerRow > 0 ? $this->mPerRow : 'dynamic'; $position = $this->getParam('position'); $captionsPosition = $this->getParam('captionposition', 'below'); $captionsAlign = $this->getParam('captionalign'); $captionsSize = $this->getParam('captionsize'); $captionsColor = !empty($captionColor) ? $captionColor : null; $spacing = $this->getParam('spacing'); $borderSize = $this->getParam('bordersize'); $borderColor = !empty($borderColor) ? $borderColor : 'accent'; $isTemplate = isset($this->mData['params']['source']) && $this->mData['params']['source'] == "template"; $hash = $this->mData['hash']; $id = 'gallery-' . $this->mData['id']; $showAddButton = $this->mShowAddButton == true; $hideOverflow = $this->getParam('hideoverflow'); if (in_array($borderColor, array('accent', 'color1'))) { $borderColorClass = " {$borderColor}"; } else { $borderColorCSS = " border-color: {$borderColor};"; if ($captionsPosition == 'within') { $captionsBackgroundColor = $borderColor; } } $html = Xml::openElement('div', array('id' => $id, 'hash' => $hash, 'class' => 'wikia-gallery' . ($isTemplate ? ' template' : null) . " wikia-gallery-caption-{$captionsPosition}" . " wikia-gallery-position-{$position}" . " wikia-gallery-spacing-{$spacing}" . " wikia-gallery-border-{$borderSize}" . " wikia-gallery-captions-{$captionsAlign}" . " wikia-gallery-caption-size-{$captionsSize}")); // render gallery caption (RT #59241) if ($this->mCaption !== false) { $html .= Xml::openElement('div', array('class' => 'wikia-gallery-caption')) . $this->mCaption . Xml::closeElement('div'); } $itemWrapperWidth = $thumbSize; $thumbWrapperHeight = $height; //compensate image wrapper width depending on the border size switch ($borderSize) { case 'large': $itemWrapperWidth += 10; //5px * 2 $thumbWrapperHeight += 10; break; case 'medium': $itemWrapperWidth += 4; //2px * 2 $thumbWrapperHeight += 4; break; case 'small': $itemWrapperWidth += 2; //1px * 2 $thumbWrapperHeight += 2; break; } //adding more width for the padding $outeritemWrapperWidth = $itemWrapperWidth + 20; $rowDividerCSS = ''; if ($useRowDivider) { $rowDividerCSS = "height: " . ($thumbWrapperHeight + 100) . "px; padding: 30px 15px 20px 15px; margin: 0px; border-bottom: solid 1px #CCCCCC;"; } if ($useBuckets) { $itemSpanStyle = "width:{$outeritemWrapperWidth}px; " . ($useRowDivider ? $rowDividerCSS : 'margin: 4px;'); $itemDivStyle = "background-color: #f9f9f9; height:{$thumbWrapperHeight}px; text-align: center; border: solid 1px #CCCCCC; padding: " . ($outeritemWrapperWidth - $thumbWrapperHeight) / 2 . "px 5px;"; } else { $itemSpanStyle = "width:{$itemWrapperWidth}px; {$rowDividerCSS}"; $itemDivStyle = "height:{$thumbWrapperHeight}px;"; } foreach ($this->mFiles as $index => $imageData) { if ($perRow != 'dynamic' && $index % $perRow == 0) { $html .= Xml::openElement('div', array('class' => 'wikia-gallery-row')); } $html .= Xml::openElement('div', array('class' => 'wikia-gallery-item', 'style' => $itemSpanStyle)); $html .= Xml::openElement('div', array('class' => 'thumb', 'style' => $itemDivStyle)); $image = array(); // let's properly scale image (don't make it bigger than original size) /** * @var $imageTitle Title * @var $fileObject LocalFile */ $imageTitle = $imageData[0]; $fileObject = $fileObjectsCache[$index]; $imageTitleText = $imageTitle->getText(); $image['height'] = $height; $image['width'] = $thumbSize; $image['caption'] = $imageData[1]; if (!is_object($fileObject) || $imageTitle->getNamespace() != NS_FILE) { $image['linkTitle'] = $image['titleText'] = $imageTitleText; $image['thumbnail'] = false; $image['link'] = Skin::makeSpecialUrl("Upload", array('wpDestFile' => $image['linkTitle'])); $image['classes'] = 'image broken-image accent new'; } else { $thumbParams = WikiaPhotoGalleryHelper::getThumbnailDimensions($fileObject, $thumbSize, $height, $crop); $image['thumbnail'] = $fileObject->createThumb($thumbParams['width'], $thumbParams['height']); $image['DBKey'] = $fileObject->getTitle()->getDBKey(); $image['fileTitle'] = $fileObject->getTitle()->getText(); $image['height'] = $orientation == 'none' ? $heights[$index] : min($thumbParams['height'], $height); $imgHeightCompensation = ($height - $image['height']) / 2; if ($imgHeightCompensation > 0) { $image['heightCompensation'] = $imgHeightCompensation; } $image['width'] = min($widths[$index], $thumbSize); //Fix #59914, shared.css has auto-alignment rules /*$imgWidthCompensation = ($thumbSize - $image['width']) / 2; if ($imgHeightCompensation > 0) $image['widthCompensation'] = $imgWidthCompensation;*/ $image['link'] = $imageData[2]; $linkAttribs = $this->parseLink($imageTitle->getLocalUrl(), $imageTitleText, $image['link']); $image['link'] = $linkAttribs['href']; $image['linkTitle'] = $linkAttribs['title']; $image['classes'] = $linkAttribs['class']; $image['bytes'] = $fileObject->getSize(); if ($this->mParser && $fileObject->getHandler()) { $fileObject->getHandler()->parserTransformHook($this->mParser, $fileObject); } } wfRunHooks('GalleryBeforeRenderImage', array(&$image)); //see Image SEO project $wrapperId = preg_replace('/[^a-z0-9_]/i', '-', Sanitizer::escapeId($image['linkTitle'])); $html .= Xml::openElement('div', array('class' => 'gallery-image-wrapper' . (!$useBuckets && !empty($borderColorClass) ? $borderColorClass : null), 'id' => $wrapperId, 'style' => 'position: relative;' . ($useBuckets ? " width: {$itemWrapperWidth}px; border-style: none;" : " height:{$image['height']}px; width:{$image['width']}px;") . (!empty($image['heightCompensation']) ? " top:{$image['heightCompensation']}px;" : null) . (!empty($borderColorCSS) ? $borderColorCSS : null))); $imgStyle = null; $isVideo = WikiaFileHelper::isFileTypeVideo($fileObject); # Fix 59913 - thumbnail goes as <img /> not as <a> background. if ($orientation != 'none') { # margin calculation for image positioning if ($thumbParams['height'] > $image['height']) { $tempTopMargin = -1 * ($thumbParams['height'] - $image['height']) / 2; } else { unset($tempTopMargin); } if ($thumbParams['width'] > $image['width']) { $tempLeftMargin = -1 * ($thumbParams['width'] - $image['width']) / 2; } else { unset($tempLeftMargin); } $imgStyle = (!empty($tempTopMargin) ? " margin-top:" . $tempTopMargin . "px;" : null) . (!empty($tempLeftMargin) ? " margin-left:" . $tempLeftMargin . "px;" : null); if ($isVideo) { $image['classes'] .= ' force-lightbox'; } } $linkAttribs = array('class' => empty($image['thumbnail']) ? 'image-no-lightbox' : $image['classes'], 'href' => $image['link'], 'title' => $image['linkTitle'] . (isset($image['bytes']) ? ' (' . $skin->formatSize($image['bytes']) . ')' : ""), 'style' => "height:{$image['height']}px; width:{$image['width']}px;"); if (!empty($image['thumbnail'])) { if ($isVideo) { $thumbHtml = ''; $duration = $fileObject->getMetadataDuration(); if (!empty($duration)) { $duration = WikiaFileHelper::formatDuration($duration); $thumbHtml .= '<span class="duration">' . $duration . '</span>'; } $playButtonSize = ThumbnailHelper::getThumbnailSize($image['width']); $thumbHtml .= $this->videoPlayButton; $linkAttribs['class'] .= ' video video-thumbnail ' . $playButtonSize; } else { $thumbHtml = ''; } $imgAttribs = array('style' => (!empty($image['titleText']) ? " line-height:{$image['height']}px;" : null) . $imgStyle, 'src' => $image['thumbnail'] ? $image['thumbnail'] : null, 'title' => $image['linkTitle'] . (isset($image['bytes']) ? ' (' . $skin->formatSize($image['bytes']) . ')' : ""), 'class' => 'thumbimage', 'alt' => preg_replace('/\\.[^\\.]+$/', '', $image['linkTitle'])); if ($isVideo) { $imgAttribs['data-video-name'] = htmlspecialchars($image['fileTitle']); $imgAttribs['data-video-key'] = urlencode(htmlspecialchars($image['DBKey'])); } else { $imgAttribs['data-image-name'] = htmlspecialchars($image['fileTitle']); $imgAttribs['data-image-key'] = urlencode(htmlspecialchars($image['DBKey'])); } if (!empty($image['data-caption'])) { $imgAttribs['data-caption'] = $image['data-caption']; } if (isset($image['thumbnail-classes']) && isset($image['thumbnail-src']) && isset($image['thumbnail-onload'])) { $thumbHtml .= '<noscript>' . Xml::openElement('img', $imgAttribs) . '</noscript>'; $imgAttribs['class'] .= ' ' . $image['thumbnail-classes']; $imgAttribs['data-src'] = $imgAttribs['src']; $imgAttribs['src'] = $image['thumbnail-src']; $imgAttribs['onload'] = $image['thumbnail-onload']; } $thumbHtml .= Xml::openElement('img', $imgAttribs); } else { $thumbHtml = $image['linkTitle']; } $html .= Xml::openElement('a', $linkAttribs); $html .= $thumbHtml; $html .= Xml::closeElement('a'); if ($captionsPosition == 'below') { $html .= Xml::closeElement('div'); $html .= Xml::closeElement('div'); } // Insert video titles here if ($isVideo) { $html .= '<div class="title">' . $imageTitleText . '</div>'; } if (!empty($image['caption'])) { $html .= Xml::openElement('div', array('class' => 'lightbox-caption' . (!empty($borderColorClass) && $captionsPosition == 'within' ? $borderColorClass : null), 'style' => ($captionsPosition == 'below' ? "width:{$thumbSize}px;" : null) . (!empty($captionsColor) ? " color:{$captionsColor};" : null) . (!empty($captionsBackgroundColor) ? " background-color:{$captionsBackgroundColor}" : null) . ($useBuckets ? " margin-top: 0px;" : '') . (!empty($hideOverflow) ? " overflow: hidden" : null))); $html .= $image['caption']; $html .= Xml::closeElement('div'); } if ($captionsPosition == 'within') { $html .= Xml::closeElement('div'); $html .= Xml::closeElement('div'); } $html .= Xml::closeElement('div'); // /div.wikia-gallery-item if ($perRow != 'dynamic' && ($index % $perRow == $perRow - 1 || $index == count($this->mFiles) - 1)) { $html .= Xml::closeElement('div'); } } // "Add image to this gallery" button (this button is shown by JS only in Monaco) if ($showAddButton) { if ($perRow == 'dynamic') { $html .= Xml::element('br'); } // add button for Oasis $html .= Xml::openElement('a', array('class' => 'wikia-photogallery-add wikia-button noprint', 'style' => 'display: none')); $html .= Xml::element('img', array('src' => F::app()->wg->BlankImgUrl, 'class' => 'sprite photo', 'width' => 26, 'height' => 16)); $html .= wfMessage('wikiaPhotoGallery-viewmode-addphoto')->inContentLanguage()->text(); $html .= Xml::closeElement('a'); } $html .= Xml::closeElement('div'); wfProfileOut(__METHOD__); return $html; }
public function getHTML() { global $wgCategoryExhibitionMediaSectionRows; $cachedContent = $this->getFromCache(); if (empty($cachedContent)) { // grabs data for videos and images $aTmpData = $this->fetchSectionItems(array(NS_FILE)); // we wan't old videos if (is_array($aTmpData) && count($aTmpData) > 0) { $pages = Paginator::newFromArray($aTmpData, $wgCategoryExhibitionMediaSectionRows * 4); $pageData = $pages->getPage($this->paginatorPosition, true); $aData = array(); foreach ($pageData as $item) { $itemTitle = Title::newFromID($item['page_id']); $forceHeight = ''; $forceWidth = ''; $isVideo = WikiaFileHelper::isFileTypeVideo($itemTitle); // item is image $image = wfFindFile($itemTitle); $elementClass = 'lightbox'; if (!is_object($image) || $image->height == 0 || $image->width == 0) { $imageSrc = ''; } else { $proportions = $image->width / $image->height; if ($proportions < 1) { $calculatedWidth = floor($proportions * $this->thumbWidth); } else { $calculatedWidth = $this->thumbMedia; } $forceWidth = floor($calculatedWidth); $forceHeight = floor($calculatedWidth / $proportions); $imageServing = new ImageServing(array($item['page_id']), $calculatedWidth, array("w" => $image->width, "h" => $image->height)); $imageSrc = wfReplaceImageServer($image->getThumbUrl($imageServing->getCut($image->width, $image->height) . "-" . $image->getName())); if ($isVideo) { $videoSizeClass = ThumbnailHelper::getThumbnailSize($forceWidth); $elementClass .= ' video video-thumbnail ' . $videoSizeClass; } } $linkedFiles = $this->getLinkedFiles($itemTitle); if (!empty($linkedFiles)) { $linkText = $linkedFiles->getText(); $linkFullUrl = $linkedFiles->getFullURL(); } else { $linkText = ''; $linkFullUrl = ''; } // types casting for proper caching; $aData[] = array('id' => $item['page_id'], 'title' => $itemTitle->getText(), 'key' => $itemTitle->getDBKey(), 'img' => (string) $imageSrc, 'url' => $itemTitle->getFullURL(), 'dimensions' => array('w' => (int) $forceWidth, 'h' => (int) $forceHeight), 'class' => $elementClass, 'data-ref' => $itemTitle->getPrefixedURL(), 'targetUrl' => $linkFullUrl, 'targetText' => $linkText, 'isVideo' => $isVideo); } $aContent = array('data' => $aData, 'category' => $this->categoryTitle->getText(), 'paginator' => $pages->getBarHTML($this->sUrl)); $this->saveToCache($aContent); } else { return false; } } else { $aContent = $cachedContent; } if (!empty($aContent) && is_array($aContent)) { $oTmpl = new EasyTemplate(dirname(__FILE__) . "/templates/"); $oTmpl->set_vars($aContent); $oTmpl->set_vars(array('fromAjax' => $this->isFromAjax)); if ($this->isFromAjax) { return array('page' => $oTmpl->render($this->templateName), 'paginator' => $oTmpl->mVars['paginator']); } else { return $oTmpl->render($this->templateName); } } }