mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 17:27:36 +00:00
683 lines
17 KiB
PHP
683 lines
17 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
namespace Magento\Cms\Model;
|
|
|
|
use Magento\Cms\Api\Data\PageInterface;
|
|
use Magento\Cms\Helper\Page as PageHelper;
|
|
use Magento\Cms\Model\Page\CustomLayout\CustomLayoutRepository;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\DataObject\IdentityInterface;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Model\AbstractModel;
|
|
use Magento\Framework\Validation\ValidationException;
|
|
use Magento\Framework\Validator\HTML\WYSIWYGValidatorInterface;
|
|
use Magento\Backend\Model\Validator\UrlKey\CompositeUrlKey;
|
|
|
|
/**
|
|
* Cms Page Model
|
|
*
|
|
* @api
|
|
* @method Page setStoreId(int $storeId)
|
|
* @method int getStoreId()
|
|
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
* @since 100.0.2
|
|
*/
|
|
class Page extends AbstractModel implements PageInterface, IdentityInterface
|
|
{
|
|
/**
|
|
* Page ID for the 404 page.
|
|
*/
|
|
const NOROUTE_PAGE_ID = 'no-route';
|
|
|
|
/**#@+
|
|
* Page's Statuses
|
|
*/
|
|
const STATUS_ENABLED = 1;
|
|
const STATUS_DISABLED = 0;
|
|
/**#@-*/
|
|
|
|
/**
|
|
* CMS page cache tag
|
|
*/
|
|
const CACHE_TAG = 'cms_p';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $_cacheTag = self::CACHE_TAG;
|
|
|
|
/**
|
|
* Prefix of model events names
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $_eventPrefix = 'cms_page';
|
|
|
|
/**
|
|
* @var ScopeConfigInterface
|
|
*/
|
|
private $scopeConfig;
|
|
|
|
/**
|
|
* @var CustomLayoutRepository
|
|
*/
|
|
private $customLayoutRepository;
|
|
|
|
/**
|
|
* @var WYSIWYGValidatorInterface
|
|
*/
|
|
private $wysiwygValidator;
|
|
|
|
/**
|
|
* @var CompositeUrlKey
|
|
*/
|
|
private $compositeUrlValidator;
|
|
|
|
/**
|
|
* @param \Magento\Framework\Model\Context $context
|
|
* @param \Magento\Framework\Registry $registry
|
|
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
|
|
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
|
|
* @param array $data
|
|
* @param CustomLayoutRepository|null $customLayoutRepository
|
|
* @param WYSIWYGValidatorInterface|null $wysiwygValidator
|
|
* @param CompositeUrlKey|null $compositeUrlValidator
|
|
*/
|
|
public function __construct(
|
|
\Magento\Framework\Model\Context $context,
|
|
\Magento\Framework\Registry $registry,
|
|
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
|
|
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
|
|
array $data = [],
|
|
?CustomLayoutRepository $customLayoutRepository = null,
|
|
?WYSIWYGValidatorInterface $wysiwygValidator = null,
|
|
CompositeUrlKey $compositeUrlValidator = null
|
|
) {
|
|
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
|
|
$this->customLayoutRepository = $customLayoutRepository
|
|
?? ObjectManager::getInstance()->get(CustomLayoutRepository::class);
|
|
$this->wysiwygValidator = $wysiwygValidator
|
|
?? ObjectManager::getInstance()->get(WYSIWYGValidatorInterface::class);
|
|
$this->compositeUrlValidator = $compositeUrlValidator
|
|
?? ObjectManager::getInstance()->get(CompositeUrlKey::class);
|
|
}
|
|
|
|
/**
|
|
* Initialize resource model
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function _construct()
|
|
{
|
|
$this->_init(\Magento\Cms\Model\ResourceModel\Page::class);
|
|
}
|
|
|
|
/**
|
|
* Load object data
|
|
*
|
|
* @param int|null $id
|
|
* @param string $field
|
|
* @return $this
|
|
*/
|
|
public function load($id, $field = null)
|
|
{
|
|
if ($id === null) {
|
|
return $this->noRoutePage();
|
|
}
|
|
return parent::load($id, $field);
|
|
}
|
|
|
|
/**
|
|
* Load No-Route Page
|
|
*
|
|
* @return \Magento\Cms\Model\Page
|
|
*/
|
|
public function noRoutePage()
|
|
{
|
|
return $this->load(self::NOROUTE_PAGE_ID, $this->getIdFieldName());
|
|
}
|
|
|
|
/**
|
|
* Receive page store ids
|
|
*
|
|
* @return int[]
|
|
*/
|
|
public function getStores()
|
|
{
|
|
return $this->hasData('stores') ? $this->getData('stores') : (array)$this->getData('store_id');
|
|
}
|
|
|
|
/**
|
|
* Check if page identifier exist for specific store return page id if page exists
|
|
*
|
|
* @param string $identifier
|
|
* @param int $storeId
|
|
* @return int
|
|
*/
|
|
public function checkIdentifier($identifier, $storeId)
|
|
{
|
|
return $this->_getResource()->checkIdentifier($identifier, $storeId);
|
|
}
|
|
|
|
/**
|
|
* Prepare page's statuses, available event cms_page_get_available_statuses to customize statuses.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAvailableStatuses()
|
|
{
|
|
return [self::STATUS_ENABLED => __('Enabled'), self::STATUS_DISABLED => __('Disabled')];
|
|
}
|
|
|
|
/**
|
|
* Get identities
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getIdentities()
|
|
{
|
|
return [self::CACHE_TAG . '_' . $this->getId()];
|
|
}
|
|
|
|
/**
|
|
* Get ID
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getId()
|
|
{
|
|
return parent::getData(self::PAGE_ID);
|
|
}
|
|
|
|
/**
|
|
* Get identifier
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getIdentifier()
|
|
{
|
|
return $this->getData(self::IDENTIFIER);
|
|
}
|
|
|
|
/**
|
|
* Get title
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getTitle()
|
|
{
|
|
return $this->getData(self::TITLE);
|
|
}
|
|
|
|
/**
|
|
* Get page layout
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getPageLayout()
|
|
{
|
|
return $this->getData(self::PAGE_LAYOUT);
|
|
}
|
|
|
|
/**
|
|
* Get meta title
|
|
*
|
|
* @return string|null
|
|
* @since 101.0.0
|
|
*/
|
|
public function getMetaTitle()
|
|
{
|
|
return $this->getData(self::META_TITLE);
|
|
}
|
|
|
|
/**
|
|
* Get meta keywords
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getMetaKeywords()
|
|
{
|
|
return $this->getData(self::META_KEYWORDS);
|
|
}
|
|
|
|
/**
|
|
* Get meta description
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getMetaDescription()
|
|
{
|
|
return $this->getData(self::META_DESCRIPTION);
|
|
}
|
|
|
|
/**
|
|
* Get content heading
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getContentHeading()
|
|
{
|
|
return $this->getData(self::CONTENT_HEADING);
|
|
}
|
|
|
|
/**
|
|
* Get content
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getContent()
|
|
{
|
|
return $this->getData(self::CONTENT);
|
|
}
|
|
|
|
/**
|
|
* Get creation time
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCreationTime()
|
|
{
|
|
return $this->getData(self::CREATION_TIME);
|
|
}
|
|
|
|
/**
|
|
* Get update time
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getUpdateTime()
|
|
{
|
|
return $this->getData(self::UPDATE_TIME);
|
|
}
|
|
|
|
/**
|
|
* Get sort order
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSortOrder()
|
|
{
|
|
return $this->getData(self::SORT_ORDER);
|
|
}
|
|
|
|
/**
|
|
* Get layout update xml
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getLayoutUpdateXml()
|
|
{
|
|
return $this->getData(self::LAYOUT_UPDATE_XML);
|
|
}
|
|
|
|
/**
|
|
* Get custom theme
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCustomTheme()
|
|
{
|
|
return $this->getData(self::CUSTOM_THEME);
|
|
}
|
|
|
|
/**
|
|
* Get custom root template
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCustomRootTemplate()
|
|
{
|
|
return $this->getData(self::CUSTOM_ROOT_TEMPLATE);
|
|
}
|
|
|
|
/**
|
|
* Get custom layout update xml
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCustomLayoutUpdateXml()
|
|
{
|
|
return $this->getData(self::CUSTOM_LAYOUT_UPDATE_XML);
|
|
}
|
|
|
|
/**
|
|
* Get custom theme from
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCustomThemeFrom()
|
|
{
|
|
return $this->getData(self::CUSTOM_THEME_FROM);
|
|
}
|
|
|
|
/**
|
|
* Get custom theme to
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCustomThemeTo()
|
|
{
|
|
return $this->getData(self::CUSTOM_THEME_TO);
|
|
}
|
|
|
|
/**
|
|
* Is active
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isActive()
|
|
{
|
|
return (bool)$this->getData(self::IS_ACTIVE);
|
|
}
|
|
|
|
/**
|
|
* Set ID
|
|
*
|
|
* @param int $id
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setId($id)
|
|
{
|
|
return $this->setData(self::PAGE_ID, $id);
|
|
}
|
|
|
|
/**
|
|
* Set identifier
|
|
*
|
|
* @param string $identifier
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setIdentifier($identifier)
|
|
{
|
|
return $this->setData(self::IDENTIFIER, $identifier);
|
|
}
|
|
|
|
/**
|
|
* Set title
|
|
*
|
|
* @param string $title
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setTitle($title)
|
|
{
|
|
return $this->setData(self::TITLE, $title);
|
|
}
|
|
|
|
/**
|
|
* Set page layout
|
|
*
|
|
* @param string $pageLayout
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setPageLayout($pageLayout)
|
|
{
|
|
return $this->setData(self::PAGE_LAYOUT, $pageLayout);
|
|
}
|
|
|
|
/**
|
|
* Set meta title
|
|
*
|
|
* @param string $metaTitle
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
* @since 101.0.0
|
|
*/
|
|
public function setMetaTitle($metaTitle)
|
|
{
|
|
return $this->setData(self::META_TITLE, $metaTitle);
|
|
}
|
|
|
|
/**
|
|
* Set meta keywords
|
|
*
|
|
* @param string $metaKeywords
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setMetaKeywords($metaKeywords)
|
|
{
|
|
return $this->setData(self::META_KEYWORDS, $metaKeywords);
|
|
}
|
|
|
|
/**
|
|
* Set meta description
|
|
*
|
|
* @param string $metaDescription
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setMetaDescription($metaDescription)
|
|
{
|
|
return $this->setData(self::META_DESCRIPTION, $metaDescription);
|
|
}
|
|
|
|
/**
|
|
* Set content heading
|
|
*
|
|
* @param string $contentHeading
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setContentHeading($contentHeading)
|
|
{
|
|
return $this->setData(self::CONTENT_HEADING, $contentHeading);
|
|
}
|
|
|
|
/**
|
|
* Set content
|
|
*
|
|
* @param string $content
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setContent($content)
|
|
{
|
|
return $this->setData(self::CONTENT, $content);
|
|
}
|
|
|
|
/**
|
|
* Set creation time
|
|
*
|
|
* @param string $creationTime
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCreationTime($creationTime)
|
|
{
|
|
return $this->setData(self::CREATION_TIME, $creationTime);
|
|
}
|
|
|
|
/**
|
|
* Set update time
|
|
*
|
|
* @param string $updateTime
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setUpdateTime($updateTime)
|
|
{
|
|
return $this->setData(self::UPDATE_TIME, $updateTime);
|
|
}
|
|
|
|
/**
|
|
* Set sort order
|
|
*
|
|
* @param string $sortOrder
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setSortOrder($sortOrder)
|
|
{
|
|
return $this->setData(self::SORT_ORDER, $sortOrder);
|
|
}
|
|
|
|
/**
|
|
* Set layout update xml
|
|
*
|
|
* @param string $layoutUpdateXml
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setLayoutUpdateXml($layoutUpdateXml)
|
|
{
|
|
return $this->setData(self::LAYOUT_UPDATE_XML, $layoutUpdateXml);
|
|
}
|
|
|
|
/**
|
|
* Set custom theme
|
|
*
|
|
* @param string $customTheme
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCustomTheme($customTheme)
|
|
{
|
|
return $this->setData(self::CUSTOM_THEME, $customTheme);
|
|
}
|
|
|
|
/**
|
|
* Set custom root template
|
|
*
|
|
* @param string $customRootTemplate
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCustomRootTemplate($customRootTemplate)
|
|
{
|
|
return $this->setData(self::CUSTOM_ROOT_TEMPLATE, $customRootTemplate);
|
|
}
|
|
|
|
/**
|
|
* Set custom layout update xml
|
|
*
|
|
* @param string $customLayoutUpdateXml
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCustomLayoutUpdateXml($customLayoutUpdateXml)
|
|
{
|
|
return $this->setData(self::CUSTOM_LAYOUT_UPDATE_XML, $customLayoutUpdateXml);
|
|
}
|
|
|
|
/**
|
|
* Set custom theme from
|
|
*
|
|
* @param string $customThemeFrom
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCustomThemeFrom($customThemeFrom)
|
|
{
|
|
return $this->setData(self::CUSTOM_THEME_FROM, $customThemeFrom);
|
|
}
|
|
|
|
/**
|
|
* Set custom theme to
|
|
*
|
|
* @param string $customThemeTo
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setCustomThemeTo($customThemeTo)
|
|
{
|
|
return $this->setData(self::CUSTOM_THEME_TO, $customThemeTo);
|
|
}
|
|
|
|
/**
|
|
* Set is active
|
|
*
|
|
* @param int|bool $isActive
|
|
* @return \Magento\Cms\Api\Data\PageInterface
|
|
*/
|
|
public function setIsActive($isActive)
|
|
{
|
|
return $this->setData(self::IS_ACTIVE, $isActive);
|
|
}
|
|
|
|
/**
|
|
* Validate identifier before saving the entity.
|
|
*
|
|
* @return void
|
|
* @throws LocalizedException
|
|
*/
|
|
private function validateNewIdentifier(): void
|
|
{
|
|
$originalIdentifier = $this->getOrigData('identifier');
|
|
$currentIdentifier = $this->getIdentifier();
|
|
if ($this->getId() && $originalIdentifier !== $currentIdentifier) {
|
|
switch ($originalIdentifier) {
|
|
case $this->getScopeConfig()->getValue(PageHelper::XML_PATH_NO_ROUTE_PAGE):
|
|
throw new LocalizedException(
|
|
__('This identifier is reserved for "CMS No Route Page" in configuration.')
|
|
);
|
|
case $this->getScopeConfig()->getValue(PageHelper::XML_PATH_HOME_PAGE):
|
|
throw new LocalizedException(
|
|
__('This identifier is reserved for "CMS Home Page" in configuration.')
|
|
);
|
|
case $this->getScopeConfig()->getValue(PageHelper::XML_PATH_NO_COOKIES_PAGE):
|
|
throw new LocalizedException(
|
|
__('This identifier is reserved for "CMS No Cookies Page" in configuration.')
|
|
);
|
|
}
|
|
}
|
|
$errors = $this->compositeUrlValidator->validate($currentIdentifier);
|
|
if (!empty($errors)) {
|
|
throw new LocalizedException($errors[0]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
* @since 101.0.0
|
|
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
* @SuppressWarnings(PHPMD.NPathComplexity)
|
|
*/
|
|
public function beforeSave()
|
|
{
|
|
if ($this->hasDataChanges()) {
|
|
$this->setUpdateTime(null);
|
|
}
|
|
|
|
$this->validateNewIdentifier();
|
|
|
|
//Removing deprecated custom layout update if a new value is provided
|
|
$layoutUpdate = $this->getData('layout_update_selected');
|
|
if ($layoutUpdate === '_no_update_' || ($layoutUpdate && $layoutUpdate !== '_existing_')) {
|
|
$this->setCustomLayoutUpdateXml(null);
|
|
$this->setLayoutUpdateXml(null);
|
|
}
|
|
if ($layoutUpdate === '_no_update_' || $layoutUpdate === '_existing_') {
|
|
$layoutUpdate = null;
|
|
}
|
|
$this->setData('layout_update_selected', $layoutUpdate);
|
|
$this->customLayoutRepository->validateLayoutSelectedFor($this);
|
|
|
|
//Validating Content HTML.
|
|
$oldValue = null;
|
|
if ($this->getId()) {
|
|
if ($this->getOrigData()) {
|
|
$oldValue = $this->getOrigData(self::CONTENT);
|
|
} elseif (array_key_exists(self::CONTENT, $this->getStoredData())) {
|
|
$oldValue = $this->getStoredData()[self::CONTENT];
|
|
}
|
|
}
|
|
if ($this->getContent() && $this->getContent() !== $oldValue) {
|
|
try {
|
|
$this->wysiwygValidator->validate($this->getContent());
|
|
} catch (ValidationException $exception) {
|
|
throw new ValidationException(
|
|
__('Content HTML contains restricted elements. %1', $exception->getMessage()),
|
|
$exception
|
|
);
|
|
}
|
|
}
|
|
|
|
return parent::beforeSave();
|
|
}
|
|
|
|
/**
|
|
* Returns scope config.
|
|
*
|
|
* @return ScopeConfigInterface
|
|
*/
|
|
private function getScopeConfig()
|
|
{
|
|
if (null === $this->scopeConfig) {
|
|
$this->scopeConfig = \Magento\Framework\App\ObjectManager::getInstance()->get(ScopeConfigInterface::class);
|
|
}
|
|
|
|
return $this->scopeConfig;
|
|
}
|
|
}
|