2015-04-27 14:05:31 +00:00
|
|
|
<?php
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
class PortableInfoboxRenderService extends WikiaService {
|
2015-04-27 14:05:31 +00:00
|
|
|
const LOGGER_LABEL = 'portable-infobox-render-not-supported-type';
|
2015-05-07 15:16:07 +00:00
|
|
|
const DESKTOP_THUMBNAIL_WIDTH = 270;
|
|
|
|
const MOBILE_THUMBNAIL_WIDTH = 360;
|
2015-05-12 11:32:42 +00:00
|
|
|
const MOBILE_TEMPLATE_POSTFIX = '-mobile';
|
2015-04-27 14:05:31 +00:00
|
|
|
|
|
|
|
private $templates = [
|
|
|
|
'wrapper' => 'PortableInfoboxWrapper.mustache',
|
|
|
|
'title' => 'PortableInfoboxItemTitle.mustache',
|
|
|
|
'header' => 'PortableInfoboxItemHeader.mustache',
|
|
|
|
'image' => 'PortableInfoboxItemImage.mustache',
|
2015-05-12 11:32:42 +00:00
|
|
|
'image-mobile' => 'PortableInfoboxItemImageMobile.mustache',
|
2015-05-04 10:48:57 +00:00
|
|
|
'data' => 'PortableInfoboxItemData.mustache',
|
2015-04-27 14:05:31 +00:00
|
|
|
'group' => 'PortableInfoboxItemGroup.mustache',
|
2015-07-03 10:05:59 +00:00
|
|
|
'navigation' => 'PortableInfoboxItemNavigation.mustache',
|
2015-07-01 13:18:20 +00:00
|
|
|
'hero-mobile' => 'PortableInfoboxItemHeroMobile.mustache'
|
2015-04-27 14:05:31 +00:00
|
|
|
];
|
|
|
|
private $templateEngine;
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
function __construct() {
|
|
|
|
$this->templateEngine = ( new Wikia\Template\MustacheEngine )
|
|
|
|
->setPrefix( dirname( __FILE__ ) . '/../templates' );
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders infobox
|
|
|
|
*
|
|
|
|
* @param array $infoboxdata
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-04-27 14:05:31 +00:00
|
|
|
* @return string - infobox HTML
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
public function renderInfobox( array $infoboxdata, $theme, $layout ) {
|
|
|
|
wfProfileIn( __METHOD__ );
|
2015-04-27 14:05:31 +00:00
|
|
|
$infoboxHtmlContent = '';
|
2015-07-02 11:55:39 +00:00
|
|
|
$heroData = [ ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
foreach ( $infoboxdata as $item ) {
|
|
|
|
$data = $item[ 'data' ];
|
|
|
|
$type = $item[ 'type' ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
switch ( $type ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
case 'group':
|
2015-07-02 11:55:39 +00:00
|
|
|
$infoboxHtmlContent .= $this->renderGroup( $data );
|
2015-04-27 14:05:31 +00:00
|
|
|
break;
|
2015-07-01 14:19:31 +00:00
|
|
|
case 'navigation':
|
|
|
|
$infoboxHtmlContent .= $this->renderItem( 'navigation', $data );
|
2015-04-27 14:05:31 +00:00
|
|
|
break;
|
|
|
|
default:
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $this->isInfoboxHeroEnabled() && $this->isValidHeroDataItem( $item, $heroData ) ) {
|
|
|
|
$heroData[ $type ] = $data;
|
2015-07-01 13:18:20 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $this->validateType( $type ) ) {
|
|
|
|
$infoboxHtmlContent .= $this->renderItem( $type, $data );
|
2015-04-27 14:05:31 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( !empty( $heroData ) ) {
|
|
|
|
$infoboxHtmlContent = $this->renderInfoboxHero( $heroData ) . $infoboxHtmlContent;
|
2015-07-01 13:18:20 +00:00
|
|
|
}
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( !empty( $infoboxHtmlContent ) ) {
|
|
|
|
$output = $this->renderItem( 'wrapper', [ 'content' => $infoboxHtmlContent, 'theme' => $theme, 'layout' => $layout ] );
|
2015-04-27 14:05:31 +00:00
|
|
|
} else {
|
|
|
|
$output = '';
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2015-04-27 14:05:31 +00:00
|
|
|
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders group infobox component
|
|
|
|
*
|
|
|
|
* @param array $groupData
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-04-27 14:05:31 +00:00
|
|
|
* @return string - group HTML markup
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
private function renderGroup( $groupData ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
$groupHTMLContent = '';
|
2015-07-02 11:55:39 +00:00
|
|
|
$dataItems = $groupData[ 'value' ];
|
|
|
|
$layout = $groupData[ 'layout' ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
foreach ( $dataItems as $item ) {
|
|
|
|
$type = $item[ 'type' ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $this->validateType( $type ) ) {
|
|
|
|
$groupHTMLContent .= $this->renderItem( $type, $item[ 'data' ] );
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
return $this->renderItem( 'group', [ 'content' => $groupHTMLContent, 'layout' => $layout ] );
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders part of infobox
|
2015-07-10 12:10:03 +00:00
|
|
|
* If image element has invalid thumbnail, doesn't render this element at all.
|
2015-04-27 14:05:31 +00:00
|
|
|
*
|
|
|
|
* @param string $type
|
|
|
|
* @param array $data
|
2015-07-11 08:59:56 +00:00
|
|
|
* @return bool|string - HTML
|
2015-04-27 14:05:31 +00:00
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
private function renderItem( $type, array $data ) {
|
2015-05-06 14:31:57 +00:00
|
|
|
//TODO: with validated the performance of render Service and in the next phase we want to refactor it (make
|
|
|
|
// it modular) While doing this we also need to move this logic to appropriate image render class
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $type === 'image' ) {
|
2015-07-01 16:03:34 +00:00
|
|
|
$data = $this->extendImageData( $data );
|
2015-07-16 11:06:17 +00:00
|
|
|
if (!$data) {
|
2015-07-10 12:10:03 +00:00
|
|
|
return false;
|
2015-07-08 11:22:12 +00:00
|
|
|
}
|
2015-05-12 11:32:42 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $this->isWikiaMobile() ) {
|
2015-05-12 11:32:42 +00:00
|
|
|
$type = $type . self::MOBILE_TEMPLATE_POSTFIX;
|
|
|
|
}
|
2015-05-06 14:02:44 +00:00
|
|
|
}
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
return $this->templateEngine->clearData()
|
2015-07-02 11:55:39 +00:00
|
|
|
->setData( $data )
|
|
|
|
->render( $this->templates[ $type ] );
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
|
2015-05-22 15:27:20 +00:00
|
|
|
/**
|
2015-07-08 16:31:56 +00:00
|
|
|
* @desc create a thumb of the image from file title
|
|
|
|
* @param $title
|
2015-07-11 08:59:56 +00:00
|
|
|
* @return bool|MediaTransformOutput
|
2015-05-22 15:27:20 +00:00
|
|
|
*/
|
2015-07-08 16:31:56 +00:00
|
|
|
protected function getThumbnail( $title ) {
|
2015-07-02 11:55:39 +00:00
|
|
|
$file = \WikiaFileHelper::getFileFromTitle( $title );
|
2015-06-22 15:45:44 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( $file ) {
|
2015-07-07 14:28:53 +00:00
|
|
|
$width = $this->isWikiaMobile() ?
|
|
|
|
self::MOBILE_THUMBNAIL_WIDTH :
|
|
|
|
self::DESKTOP_THUMBNAIL_WIDTH;
|
2015-07-08 16:31:56 +00:00
|
|
|
$thumb = $file->transform( ['width' => $width] );
|
2015-06-22 15:45:44 +00:00
|
|
|
|
2015-07-08 16:31:56 +00:00
|
|
|
if (!is_null($thumb) && !$thumb->isError()) {
|
|
|
|
return $thumb;
|
|
|
|
}
|
2015-07-07 14:28:53 +00:00
|
|
|
}
|
2015-07-08 11:22:12 +00:00
|
|
|
return false;
|
2015-05-26 11:07:33 +00:00
|
|
|
}
|
|
|
|
|
2015-07-01 13:18:20 +00:00
|
|
|
/**
|
2015-05-20 11:56:56 +00:00
|
|
|
* required for testing mobile template rendering
|
|
|
|
* @return bool
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
protected function isWikiaMobile() {
|
|
|
|
return F::app()->checkSkin( 'wikiamobile' );
|
2015-05-07 12:36:30 +00:00
|
|
|
}
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
/**
|
|
|
|
* check if item type is supported and logs unsupported types
|
|
|
|
*
|
|
|
|
* @param string $type - template type
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-04-27 14:05:31 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
private function validateType( $type ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
$isValid = true;
|
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
if ( !isset( $this->templates[ $type ] ) ) {
|
|
|
|
Wikia\Logger\WikiaLogger::instance()->info( self::LOGGER_LABEL, [
|
2015-04-27 14:05:31 +00:00
|
|
|
'type' => $type
|
2015-07-02 11:55:39 +00:00
|
|
|
] );
|
2015-04-27 14:05:31 +00:00
|
|
|
|
|
|
|
$isValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $isValid;
|
|
|
|
}
|
2015-07-01 13:18:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* returns true if infobox hero component should be rendered
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
private function isInfoboxHeroEnabled() {
|
2015-07-01 13:18:20 +00:00
|
|
|
return $this->isWikiaMobile();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-07-17 13:43:08 +00:00
|
|
|
* checks if infobox data item is valid hero component data.
|
|
|
|
* If image is smaller than const, don't render the hero module.
|
2015-07-01 13:18:20 +00:00
|
|
|
*
|
|
|
|
* @param array $item - infobox data item
|
|
|
|
* @param array $heroData - hero component data
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-07-01 13:18:20 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2015-07-02 11:55:39 +00:00
|
|
|
private function isValidHeroDataItem( $item, $heroData ) {
|
|
|
|
$type = $item[ 'type' ];
|
2015-07-01 13:18:20 +00:00
|
|
|
|
2015-07-17 13:43:08 +00:00
|
|
|
if ( $type === 'title' && !array_key_exists( 'title', $heroData ) ) {
|
|
|
|
return true;
|
2015-07-01 13:18:20 +00:00
|
|
|
}
|
|
|
|
|
2015-07-17 13:43:08 +00:00
|
|
|
if ( $type === 'image' && !array_key_exists( 'image', $heroData ) ) {
|
|
|
|
$imageData = $this->extendImageData($item);
|
|
|
|
|
|
|
|
if ( $imageData && $imageData['data']['width'] > self::MOBILE_THUMBNAIL_WIDTH ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2015-07-01 13:18:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders infobox hero component
|
|
|
|
*
|
|
|
|
* @param array $data - infobox hero component data
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-07-01 13:18:20 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
2015-07-01 16:03:34 +00:00
|
|
|
private function renderInfoboxHero( $data ) {
|
|
|
|
if ( array_key_exists( 'image', $data ) ) {
|
|
|
|
$data[ 'image' ] = $this->extendImageData( $data[ 'image' ] );
|
|
|
|
$markup = $this->renderItem( 'hero-mobile', $data );
|
|
|
|
} else {
|
|
|
|
$markup = $this->renderItem( 'title', $data[ 'title' ] );
|
|
|
|
}
|
2015-07-02 11:55:39 +00:00
|
|
|
|
2015-07-01 16:03:34 +00:00
|
|
|
return $markup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* extends image data
|
|
|
|
*
|
|
|
|
* @param array $data
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-07-16 11:06:17 +00:00
|
|
|
* @return bool|array
|
2015-07-01 16:03:34 +00:00
|
|
|
*/
|
|
|
|
private function extendImageData( $data ) {
|
2015-07-16 11:06:17 +00:00
|
|
|
$thumbnail = $this->getThumbnail( $data[ 'name' ] );
|
2015-07-01 16:03:34 +00:00
|
|
|
|
2015-07-16 11:06:17 +00:00
|
|
|
if (!$thumbnail) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-16 11:21:20 +00:00
|
|
|
$data[ 'height' ] = $thumbnail->getHeight();
|
|
|
|
$data[ 'width' ] = $thumbnail->getWidth();
|
|
|
|
$data[ 'thumbnail' ] = $thumbnail->getUrl();
|
|
|
|
$data[ 'key' ] = urlencode( $data[ 'key' ] );
|
|
|
|
|
2015-07-01 16:03:34 +00:00
|
|
|
return $data;
|
2015-07-01 13:18:20 +00:00
|
|
|
}
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|