pageConfig = $pageConfig;
$this->assetMergeService = $assetMergeService;
$this->urlBuilder = $urlBuilder;
$this->escaper = $escaper;
$this->string = $string;
$this->logger = $logger;
}
/**
* Render element attributes
*
* @param string $elementType
* @return string
*/
public function renderElementAttributes($elementType)
{
$resultAttributes = [];
foreach ($this->pageConfig->getElementAttributes($elementType) as $name => $value) {
$resultAttributes[] = sprintf('%s="%s"', $name, $value);
}
return implode(' ', $resultAttributes);
}
/**
* Render head content
*
* @return string
*/
public function renderHeadContent()
{
$result = '';
$result .= $this->renderMetadata();
$result .= $this->renderTitle();
$this->prepareFavicon();
$result .= $this->renderAssets($this->getAvailableResultGroups());
$result .= $this->pageConfig->getIncludes();
return $result;
}
/**
* Render title
*
* @return string
*/
public function renderTitle()
{
return '
' . $this->escaper->escapeHtml($this->pageConfig->getTitle()->get()) . '' . "\n";
}
/**
* Render metadata
*
* @return string
*/
public function renderMetadata()
{
$result = '';
foreach ($this->pageConfig->getMetadata() as $name => $content) {
$metadataTemplate = $this->getMetadataTemplate($name);
if (!$metadataTemplate) {
continue;
}
$content = $this->processMetadataContent($name, $content);
if ($content) {
$result .= str_replace(['%name', '%content'], [$name, $content], $metadataTemplate);
}
}
return $result;
}
/**
* Process metadata content
*
* @param string $name
* @param string $content
* @return mixed
*/
protected function processMetadataContent($name, $content)
{
$method = 'get' . $this->string->upperCaseWords($name, '_', '');
if ($name === 'title') {
if (!$content) {
$content = $this->escaper->escapeHtml($this->pageConfig->$method()->get());
}
return $content;
}
if (method_exists($this->pageConfig, $method)) {
$content = $this->pageConfig->$method();
}
return $content;
}
/**
* Returns metadata template
*
* @param string $name
* @return bool|string
*/
protected function getMetadataTemplate($name)
{
if (strpos($name, 'og:') === 0) {
return '' . "\n";
}
switch ($name) {
case Config::META_CHARSET:
$metadataTemplate = '' . "\n";
break;
case Config::META_CONTENT_TYPE:
$metadataTemplate = '' . "\n";
break;
case Config::META_X_UI_COMPATIBLE:
$metadataTemplate = '' . "\n";
break;
case Config::META_MEDIA_TYPE:
$metadataTemplate = false;
break;
default:
$metadataTemplate = '' . "\n";
break;
}
return $metadataTemplate;
}
/**
* Favicon preparation
*
* @return void
*/
public function prepareFavicon()
{
if ($this->pageConfig->getFaviconFile()) {
$this->pageConfig->addRemotePageAsset(
$this->pageConfig->getFaviconFile(),
Generator\Head::VIRTUAL_CONTENT_TYPE_LINK,
['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
'icon'
);
$this->pageConfig->addRemotePageAsset(
$this->pageConfig->getFaviconFile(),
Generator\Head::VIRTUAL_CONTENT_TYPE_LINK,
['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
'shortcut-icon'
);
} else {
$this->pageConfig->addPageAsset(
$this->pageConfig->getDefaultFavicon(),
['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
'icon'
);
$this->pageConfig->addPageAsset(
$this->pageConfig->getDefaultFavicon(),
['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
'shortcut-icon'
);
}
}
/**
* Returns rendered HTML for all Assets (CSS before)
*
* @param array $resultGroups
*
* @return string
*/
public function renderAssets($resultGroups = [])
{
/** @var $group \Magento\Framework\View\Asset\PropertyGroup */
foreach ($this->pageConfig->getAssetCollection()->getGroups() as $group) {
$type = $group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE);
if (!isset($resultGroups[$type])) {
$resultGroups[$type] = '';
}
$resultGroups[$type] .= $this->renderAssetGroup($group);
}
return implode('', $resultGroups);
}
/**
* Returns rendered HTML for an Asset Group
*
* @param \Magento\Framework\View\Asset\PropertyGroup $group
* @return string
*/
protected function renderAssetGroup(\Magento\Framework\View\Asset\PropertyGroup $group)
{
$groupHtml = $this->renderAssetHtml($group);
$groupHtml = $this->processIeCondition($groupHtml, $group);
return $groupHtml;
}
/**
* Process assets merge
*
* @param array $groupAssets
* @param \Magento\Framework\View\Asset\PropertyGroup $group
* @return array
*/
protected function processMerge($groupAssets, $group)
{
if ($group->getProperty(GroupedCollection::PROPERTY_CAN_MERGE) && count($groupAssets) > 1) {
$groupAssets = $this->assetMergeService->getMergedAssets(
$groupAssets,
$group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE)
);
}
return $groupAssets;
}
/**
* Returns group attributes
*
* @param \Magento\Framework\View\Asset\PropertyGroup $group
* @return string|null
*/
protected function getGroupAttributes($group)
{
$attributes = $group->getProperty('attributes');
if (!empty($attributes)) {
if (is_array($attributes)) {
$attributesString = '';
foreach ($attributes as $name => $value) {
$attributesString .= ' ' . $name . '="' . $this->escaper->escapeHtml($value) . '"';
}
$attributes = $attributesString;
} else {
$attributes = ' ' . $attributes;
}
}
return $attributes;
}
/**
* Add default attributes
*
* @param string $contentType
* @param string $attributes
* @return string
*/
protected function addDefaultAttributes($contentType, $attributes)
{
switch ($contentType) {
case 'js':
$attributes = ' type="text/javascript" ' . $attributes;
break;
case 'css':
$attributes = ' rel="stylesheet" type="text/css" ' . ($attributes ?: ' media="all"');
break;
}
return $attributes;
}
/**
* Returns assets template
*
* @param string $contentType
* @param string|null $attributes
* @return string
*/
protected function getAssetTemplate($contentType, $attributes)
{
switch ($contentType) {
case 'js':
$groupTemplate = '' . "\n";
break;
case 'css':
default:
$groupTemplate = '' . "\n";
break;
}
return $groupTemplate;
}
/**
* Process IE condition
*
* @param string $groupHtml
* @param \Magento\Framework\View\Asset\PropertyGroup $group
* @return string
*/
protected function processIeCondition($groupHtml, $group)
{
$ieCondition = $group->getProperty('ie_condition');
if (!empty($ieCondition)) {
$groupHtml = '' . "\n";
}
return $groupHtml;
}
/**
* Render HTML tags referencing corresponding URLs
*
* @param \Magento\Framework\View\Asset\PropertyGroup $group
* @return string
*/
protected function renderAssetHtml(\Magento\Framework\View\Asset\PropertyGroup $group)
{
$assets = $this->processMerge($group->getAll(), $group);
$attributes = $this->getGroupAttributes($group);
$result = '';
try {
/** @var $asset \Magento\Framework\View\Asset\AssetInterface */
foreach ($assets as $asset) {
$template = $this->getAssetTemplate(
$group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE),
$this->addDefaultAttributes($this->getAssetContentType($asset), $attributes)
);
$result .= sprintf($template, $asset->getUrl());
}
} catch (LocalizedException $e) {
$this->logger->critical($e);
$result .= sprintf($template, $this->urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']));
}
return $result;
}
/**
* Get asset content type
*
* @param \Magento\Framework\View\Asset\AssetInterface $asset
* @return string
*/
protected function getAssetContentType(\Magento\Framework\View\Asset\AssetInterface $asset)
{
return $asset->getContentType();
}
/**
* Returns available groups.
*
* @return array
*/
public function getAvailableResultGroups()
{
return array_fill_keys($this->assetTypeOrder, '');
}
}