| Current Path : /var/www/clients/client3/web2/web/vendor/magento/module-theme/Model/Theme/ |
| Current File : /var/www/clients/client3/web2/web/vendor/magento/module-theme/Model/Theme/Registration.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Theme\Model\Theme;
use Magento\Framework\Filesystem;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Design\ThemeInterface;
/**
* Theme registration model class
*/
class Registration
{
/**
* @var \Magento\Theme\Model\ResourceModel\Theme\Data\CollectionFactory
*/
protected $_collectionFactory;
/**
* Collection of themes in file-system
*
* @var Collection
*/
protected $_themeCollection;
/**
* Allowed sequence relation by type, array(parent theme, child theme)
*
* @var array
*/
protected $_allowedRelations = [
[ThemeInterface::TYPE_PHYSICAL, ThemeInterface::TYPE_VIRTUAL],
[ThemeInterface::TYPE_VIRTUAL, ThemeInterface::TYPE_STAGING],
];
/**
* Forbidden sequence relation by type
*
* @var array
*/
protected $_forbiddenRelations = [
[ThemeInterface::TYPE_VIRTUAL, ThemeInterface::TYPE_VIRTUAL],
[ThemeInterface::TYPE_PHYSICAL, ThemeInterface::TYPE_STAGING],
];
/**
* Initialize dependencies
*
* @param \Magento\Theme\Model\ResourceModel\Theme\Data\CollectionFactory $collectionFactory
* @param \Magento\Theme\Model\Theme\Data\Collection $filesystemCollection
*/
public function __construct(
\Magento\Theme\Model\ResourceModel\Theme\Data\CollectionFactory $collectionFactory,
\Magento\Theme\Model\Theme\Data\Collection $filesystemCollection
) {
$this->_collectionFactory = $collectionFactory;
$this->_themeCollection = $filesystemCollection;
}
/**
* Theme registration
*
* @return $this
*/
public function register()
{
$this->_themeCollection->clear();
foreach ($this->_themeCollection as $theme) {
$this->_registerThemeRecursively($theme);
}
$this->checkPhysicalThemes()->checkAllowedThemeRelations();
return $this;
}
/**
* Register theme and recursively all its ascendants
*
* Second param is optional and is used to prevent circular references in inheritance chain
*
* @param ThemeInterface &$theme
* @param array $inheritanceChain
* @return $this
*
* @throws LocalizedException
*/
protected function _registerThemeRecursively(&$theme, $inheritanceChain = [])
{
if ($theme->getId()) {
return $this;
}
$themeModel = $this->getThemeFromDb($theme->getFullPath());
if ($themeModel->getId()) {
$theme = $themeModel;
return $this;
}
$tempId = $theme->getFullPath();
if (in_array($tempId, $inheritanceChain)) {
throw new LocalizedException(__('Circular-reference in theme inheritance detected for "%1"', $tempId));
}
$inheritanceChain[] = $tempId;
$parentTheme = $theme->getParentTheme();
if ($parentTheme) {
$this->_registerThemeRecursively($parentTheme, $inheritanceChain);
$theme->setParentId($parentTheme->getId());
}
$this->_savePreviewImage($theme);
$theme->setType(ThemeInterface::TYPE_PHYSICAL);
$theme->save();
return $this;
}
/**
* Save preview image for theme
*
* @param ThemeInterface $theme
* @return $this
*/
protected function _savePreviewImage(ThemeInterface $theme)
{
$themeDirectory = $theme->getCustomization()->getThemeFilesPath();
if (!$theme->getPreviewImage() || !$themeDirectory) {
return $this;
}
$imagePath = $themeDirectory . '/' . $theme->getPreviewImage();
if (0 === strpos($imagePath, (string) $themeDirectory)) {
$theme->getThemeImage()->createPreviewImage($imagePath);
}
return $this;
}
/**
* Get theme from DB by full path
*
* @param string $fullPath
* @return ThemeInterface
*/
public function getThemeFromDb($fullPath)
{
return $this->_collectionFactory->create()->getThemeByFullPath($fullPath);
}
/**
* Checks all physical themes that they were not deleted
*
* @return $this
*/
public function checkPhysicalThemes()
{
$themes = $this->_collectionFactory->create()->addTypeFilter(ThemeInterface::TYPE_PHYSICAL);
/** @var $theme ThemeInterface */
foreach ($themes as $theme) {
if (!$this->_themeCollection->hasTheme($theme)) {
$theme->setType(ThemeInterface::TYPE_VIRTUAL)->save();
}
}
return $this;
}
/**
* Check whether all themes have correct parent theme by type
*
* @return $this
*/
public function checkAllowedThemeRelations()
{
foreach ($this->_forbiddenRelations as $typesSequence) {
list($parentType, $childType) = $typesSequence;
$collection = $this->_collectionFactory->create();
$collection->addTypeRelationFilter($parentType, $childType);
/** @var $theme ThemeInterface */
foreach ($collection as $theme) {
$parentId = $this->_getResetParentId($theme);
if ($theme->getParentId() != $parentId) {
$theme->setParentId($parentId)->save();
}
}
}
return $this;
}
/**
* Reset parent themes by type
*
* @param ThemeInterface $theme
* @return int|null
*/
protected function _getResetParentId(ThemeInterface $theme)
{
$parentTheme = $theme->getParentTheme();
while ($parentTheme) {
foreach ($this->_allowedRelations as $typesSequence) {
list($parentType, $childType) = $typesSequence;
if ($theme->getType() == $childType && $parentTheme->getType() == $parentType) {
return $parentTheme->getId();
}
}
$parentTheme = $parentTheme->getParentTheme();
}
return null;
}
}