2015-04-27 14:05:31 +00:00
|
|
|
<?php
|
|
|
|
|
2015-08-27 08:30:25 +00:00
|
|
|
use Wikia\PortableInfobox\Helpers\PortableInfoboxRenderServiceHelper;
|
2015-07-28 11:49:17 +00:00
|
|
|
|
2015-07-02 11:55:39 +00:00
|
|
|
class PortableInfoboxRenderService extends WikiaService {
|
2015-05-12 11:32:42 +00:00
|
|
|
const MOBILE_TEMPLATE_POSTFIX = '-mobile';
|
2015-09-28 15:46:40 +00:00
|
|
|
const MEDIA_CONTEXT_INFOBOX_HERO_IMAGE = 'infobox-hero-image';
|
2015-09-30 08:10:31 +00:00
|
|
|
const MEDIA_CONTEXT_INFOBOX = 'infobox';
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-08-27 08:30:25 +00:00
|
|
|
private static $templates = [
|
2015-04-27 14:05:31 +00:00
|
|
|
'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-28 09:46:41 +00:00
|
|
|
'horizontal-group-content' => 'PortableInfoboxHorizontalGroupContent.mustache',
|
2015-07-03 10:05:59 +00:00
|
|
|
'navigation' => 'PortableInfoboxItemNavigation.mustache',
|
2015-10-16 01:15:52 +00:00
|
|
|
'hero-mobile' => 'PortableInfoboxItemHeroMobile.mustache',
|
|
|
|
'image-collection' => 'PortableInfoboxItemImageCollection.mustache',
|
2015-10-20 23:09:23 +00:00
|
|
|
'image-collection-mobile' => 'PortableInfoboxItemImageCollectionMobile.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 )
|
2015-08-27 08:30:25 +00:00
|
|
|
->setPrefix( self::getTemplatesDir() );
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getTemplatesDir() {
|
|
|
|
return dirname( __FILE__ ) . '/../templates';
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getTemplates() {
|
|
|
|
return self::$templates;
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders infobox
|
|
|
|
*
|
|
|
|
* @param array $infoboxdata
|
2015-07-02 11:55:39 +00:00
|
|
|
*
|
2015-11-03 16:19:29 +00:00
|
|
|
* @param $theme
|
|
|
|
* @param $layout
|
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-07-28 11:49:17 +00:00
|
|
|
|
2015-07-28 14:13:36 +00:00
|
|
|
$helper = new PortableInfoboxRenderServiceHelper();
|
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-29 13:32:52 +00:00
|
|
|
if ( $helper->isWikiaMobile() && $helper->isValidHeroDataItem( $item, $heroData ) ) {
|
2015-07-02 11:55:39 +00:00
|
|
|
$heroData[ $type ] = $data;
|
2015-07-01 13:18:20 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-08-27 08:46:38 +00:00
|
|
|
if ( $helper->isTypeSupportedInTemplates( $type, self::getTemplates() ) ) {
|
2015-07-02 11:55:39 +00:00
|
|
|
$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 ) ) {
|
2015-08-27 08:47:43 +00:00
|
|
|
$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-10-26 21:59:34 +00:00
|
|
|
$cssClasses = [];
|
2015-12-23 10:20:39 +00:00
|
|
|
$helper = new PortableInfoboxRenderServiceHelper();
|
2015-04-27 14:05:31 +00:00
|
|
|
$groupHTMLContent = '';
|
2015-07-02 11:55:39 +00:00
|
|
|
$dataItems = $groupData[ 'value' ];
|
|
|
|
$layout = $groupData[ 'layout' ];
|
2015-10-26 21:59:34 +00:00
|
|
|
$collapse = $groupData[ 'collapse' ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-09-04 15:30:54 +00:00
|
|
|
if ( $layout === 'horizontal' ) {
|
2015-07-28 09:46:41 +00:00
|
|
|
$groupHTMLContent .= $this->renderItem(
|
|
|
|
'horizontal-group-content',
|
2015-07-28 11:49:17 +00:00
|
|
|
$helper->createHorizontalGroupData( $dataItems )
|
2015-07-28 09:46:41 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
foreach ( $dataItems as $item ) {
|
|
|
|
$type = $item[ 'type' ];
|
2015-04-27 14:05:31 +00:00
|
|
|
|
2015-08-27 08:46:38 +00:00
|
|
|
if ( $helper->isTypeSupportedInTemplates( $type, self::getTemplates() ) ) {
|
2015-07-28 09:46:41 +00:00
|
|
|
$groupHTMLContent .= $this->renderItem( $type, $item[ 'data' ] );
|
|
|
|
}
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-26 21:59:34 +00:00
|
|
|
if ( $collapse !== null && count( $dataItems ) > 0 && $dataItems[ 0 ][ 'type' ] === 'header' ) {
|
|
|
|
$cssClasses[] = 'pi-collapse';
|
|
|
|
$cssClasses[] = 'pi-collapse-' . $collapse;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->renderItem( 'group', [
|
|
|
|
'content' => $groupHTMLContent,
|
|
|
|
'cssClasses' => implode(' ', $cssClasses)
|
|
|
|
] );
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
|
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 ) {
|
2015-07-28 14:13:36 +00:00
|
|
|
$helper = new PortableInfoboxRenderServiceHelper();
|
|
|
|
|
2015-07-01 16:03:34 +00:00
|
|
|
if ( array_key_exists( 'image', $data ) ) {
|
2015-10-16 01:15:52 +00:00
|
|
|
$image = $data[ 'image' ][ 0 ];
|
|
|
|
$image[ 'context' ] = self::MEDIA_CONTEXT_INFOBOX_HERO_IMAGE;
|
|
|
|
$image = $helper->extendImageData( $image );
|
|
|
|
$data['image'] = $image;
|
2015-07-01 16:03:34 +00:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-07-28 11:49:17 +00:00
|
|
|
* renders part of infobox
|
|
|
|
* If image element has invalid thumbnail, doesn't render this element at all.
|
2015-07-01 16:03:34 +00:00
|
|
|
*
|
2015-07-28 11:49:17 +00:00
|
|
|
* @param string $type
|
2015-07-01 16:03:34 +00:00
|
|
|
* @param array $data
|
2015-08-27 08:30:25 +00:00
|
|
|
*
|
2015-07-28 11:49:17 +00:00
|
|
|
* @return bool|string - HTML
|
2015-07-01 16:03:34 +00:00
|
|
|
*/
|
2015-07-28 11:49:17 +00:00
|
|
|
private function renderItem( $type, array $data ) {
|
2015-07-28 14:13:36 +00:00
|
|
|
$helper = new PortableInfoboxRenderServiceHelper();
|
2015-07-16 11:21:20 +00:00
|
|
|
|
2015-07-28 11:49:17 +00:00
|
|
|
if ( $type === 'image' ) {
|
2015-10-16 01:15:52 +00:00
|
|
|
$images = array();
|
2015-12-23 12:20:55 +00:00
|
|
|
|
2015-10-16 01:15:52 +00:00
|
|
|
for ( $i = 0; $i < count($data); $i++ ) {
|
|
|
|
$data[$i][ 'context' ] = self::MEDIA_CONTEXT_INFOBOX;
|
|
|
|
$data[$i] = $helper->extendImageData( $data[$i] );
|
2015-12-28 10:59:53 +00:00
|
|
|
$data[$i] = SanitizerBuilder::createFromType( $type )->sanitize( $data[$i] );
|
2015-12-23 12:20:55 +00:00
|
|
|
|
2015-10-16 01:15:52 +00:00
|
|
|
if ( !!$data[$i] ) {
|
|
|
|
$images[] = $data[$i];
|
|
|
|
}
|
|
|
|
}
|
2015-12-23 12:20:55 +00:00
|
|
|
|
2015-10-16 01:15:52 +00:00
|
|
|
if ( count ( $images ) === 0 ) {
|
2015-07-28 11:49:17 +00:00
|
|
|
return false;
|
2015-10-16 01:15:52 +00:00
|
|
|
} else if ( count ( $images ) === 1 ) {
|
|
|
|
$data = $images[0];
|
|
|
|
$templateName = $type;
|
|
|
|
} else {
|
2015-10-21 02:55:23 +00:00
|
|
|
$images[0]['isFirst'] = true;
|
2015-10-16 01:15:52 +00:00
|
|
|
$data = array( 'images' => $images );
|
|
|
|
$templateName = 'image-collection';
|
2015-07-28 11:49:17 +00:00
|
|
|
}
|
2015-12-23 12:20:55 +00:00
|
|
|
|
2015-07-28 11:49:17 +00:00
|
|
|
if ( $helper->isWikiaMobile() ) {
|
2015-10-16 01:15:52 +00:00
|
|
|
$templateName = $templateName . self::MOBILE_TEMPLATE_POSTFIX;
|
2015-07-28 11:49:17 +00:00
|
|
|
}
|
2015-10-16 01:15:52 +00:00
|
|
|
} else {
|
|
|
|
$templateName = $type;
|
2015-07-21 23:13:28 +00:00
|
|
|
}
|
2015-07-20 13:00:35 +00:00
|
|
|
|
2015-07-28 11:49:17 +00:00
|
|
|
if ( $helper->isWikiaMobile() ) {
|
2015-12-28 10:59:53 +00:00
|
|
|
$data = SanitizerBuilder::createFromType( $type )->sanitize( $data );
|
2015-07-21 23:13:28 +00:00
|
|
|
}
|
2015-07-20 13:00:35 +00:00
|
|
|
|
2015-07-28 11:49:17 +00:00
|
|
|
return $this->templateEngine->clearData()
|
|
|
|
->setData( $data )
|
2015-10-16 01:15:52 +00:00
|
|
|
->render( self::getTemplates()[ $templateName ] );
|
2015-07-20 13:00:35 +00:00
|
|
|
}
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|