/
githubmirror
/
magento2
Обзор
Документация
Войти
/
githubmirror
/
magento2
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
2.4-develop
lib/internal/Magento/Framework/Mview/View.php
488 строк
13 KB
Alexandra Zota
ACP2E-4019: CE copyright updates for 2.4.9-beta1
22 окт 2025, 17:47
22 окт 2025, 17:47
1b769b7
Код
Авторство
О чём код?
<?php /** * Copyright 2014 Adobe * All Rights Reserved. */ declare(strict_types=1); namespace Magento\Framework\Mview; use InvalidArgumentException; use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; use Magento\Framework\Mview\View\ChangelogBatchWalkerFactory; use Magento\Framework\Mview\View\ChangelogBatchWalkerInterface; use Magento\Framework\Mview\View\ChangelogTableNotExistsException; use Magento\Framework\Mview\View\SubscriptionFactory; use Exception; use Magento\Framework\Mview\View\SubscriptionInterface; /** * Mview * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class View extends DataObject implements ViewInterface, ViewSubscriptionInterface { /** * Default batch size for partial reindex */ public const DEFAULT_BATCH_SIZE = 1000; /** * @var string */ protected $_idFieldName = 'view_id'; /** * @var ConfigInterface */ protected $config; /** * @var ActionFactory */ protected $actionFactory; /** * @var View\ChangelogInterface */ protected $changelog; /** * @var View\SubscriptionFactory */ protected $subscriptionFactory; /** * @var View\StateInterface */ protected $state; /** * @var array */ private $changelogBatchSize; /** * @var ChangelogBatchWalkerFactory */ private $changelogBatchWalkerFactory; /** * @param ConfigInterface $config * @param ActionFactory $actionFactory * @param View\StateInterface $state * @param View\ChangelogInterface $changelog * @param SubscriptionFactory $subscriptionFactory * @param array $data * @param array $changelogBatchSize * @param ChangelogBatchWalkerFactory $changelogBatchWalkerFactory */ public function __construct( ConfigInterface $config, ActionFactory $actionFactory, View\StateInterface $state, View\ChangelogInterface $changelog, SubscriptionFactory $subscriptionFactory, array $data = [], array $changelogBatchSize = [], ?ChangelogBatchWalkerFactory $changelogBatchWalkerFactory = null ) { $this->config = $config; $this->actionFactory = $actionFactory; $this->state = $state; $this->changelog = $changelog; $this->subscriptionFactory = $subscriptionFactory; $this->changelogBatchSize = $changelogBatchSize; parent::__construct($data); $this->changelogBatchWalkerFactory = $changelogBatchWalkerFactory ?: ObjectManager::getInstance()->get(ChangelogBatchWalkerFactory::class); } /** * Return ID * * @return string */ public function getId() { return $this->getData($this->_idFieldName); } /** * Set ID * * @param string $id * @return $this */ public function setId($id) { $this->setData($this->_idFieldName, $id); return $this; } /** * Id field name setter * * @param string $name * @return $this */ public function setIdFieldName($name) { $this->_idFieldName = $name; return $this; } /** * Id field name getter * * @return string */ public function getIdFieldName() { return $this->_idFieldName; } /** * Return view action class * * @return string */ public function getActionClass() { return $this->getData('action_class'); } /** * Return view group * * @return string */ public function getGroup() { return $this->getData('group'); } /** * Return view subscriptions * * @return array */ public function getSubscriptions() { return $this->getData('subscriptions'); } /** * Fill view data from config * * @param string $viewId * @return ViewInterface * @throws InvalidArgumentException */ public function load($viewId) { $view = $this->config->getView($viewId); if (empty($view) || empty($view['view_id']) || $view['view_id'] !== $viewId) { throw new InvalidArgumentException("{$viewId} view does not exist."); } $this->setId($viewId); $this->setData($view); return $this; } /** * Create subscriptions * * @return ViewInterface * @throws Exception */ public function subscribe() { if ($this->getState()->getMode() !== View\StateInterface::MODE_ENABLED) { // Create changelog table $this->getChangelog()->create(); foreach ($this->getSubscriptions() as $subscriptionConfig) { $this->initSubscriptionInstance($subscriptionConfig)->create(); } // Update view state $this->getState()->setMode(View\StateInterface::MODE_ENABLED)->save(); } return $this; } /** * @inheritDoc */ public function unsubscribe(bool $dropTable = true): ViewInterface { if ($this->getState()->getMode() != View\StateInterface::MODE_DISABLED) { // Remove subscriptions foreach ($this->getSubscriptions() as $subscriptionConfig) { $this->initSubscriptionInstance($subscriptionConfig)->remove(); } if ($dropTable) { try { $this->getChangelog()->drop(); // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (ChangelogTableNotExistsException $e) { // We want the table to not exist, and it doesn't. All done. } $this->getState()->setVersionId(0); } // Update view state $this->getState() ->setMode(View\StateInterface::MODE_DISABLED) ->setStatus(View\StateInterface::STATUS_IDLE) ->save(); } return $this; } /** * Materialize view by IDs in changelog * * @return void * @throws Exception */ public function update() { if (!$this->isIdle() || !$this->isEnabled()) { return; } try { $currentVersionId = $this->getChangelog()->getVersion(); } catch (ChangelogTableNotExistsException $e) { return; } $lastVersionId = (int)$this->getState()->getVersionId(); if ($lastVersionId >= $currentVersionId) { return; } $action = $this->actionFactory->get($this->getActionClass()); try { $this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save(); $this->executeAction($action, $lastVersionId, $currentVersionId); $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() === View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setVersionId($currentVersionId)->setStatus($statusToRestore)->save(); } catch (\Throwable $exception) { $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() === View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setStatus($statusToRestore)->save(); if (!$exception instanceof \Exception) { $exception = new \RuntimeException( 'Error when updating an mview', 0, $exception ); } throw $exception; } } /** * Execute action from last version to current version, by batches * * @param ActionInterface $action * @param int $lastVersionId * @param int $currentVersionId * @return void * @throws \Exception */ private function executeAction(ActionInterface $action, int $lastVersionId, int $currentVersionId) { $batchSize = isset($this->changelogBatchSize[$this->getChangelog()->getViewId()]) ? (int) $this->changelogBatchSize[$this->getChangelog()->getViewId()] : self::DEFAULT_BATCH_SIZE; $batches = $this->getWalker()->walk($this->getChangelog(), $lastVersionId, $currentVersionId, $batchSize); foreach ($batches as $ids) { $action->execute($ids); } } /** * Create and validate walker class for changelog * * @return \Magento\Framework\Mview\View\ChangelogBatchWalkerInterface */ private function getWalker(): ChangelogBatchWalkerInterface { $config = $this->config->getView($this->changelog->getViewId()); $walkerClass = $config['walker']; return $this->changelogBatchWalkerFactory->create($walkerClass); } /** * Suspend view updates and set version ID to changelog's end * * @return void * @throws Exception */ public function suspend() { if ($this->getState()->getMode() === View\StateInterface::MODE_ENABLED) { $state = $this->getState(); $state->setVersionId($this->getChangelog()->getVersion()); $state->setStatus(View\StateInterface::STATUS_SUSPENDED); $state->save(); } } /** * Resume view updates * * @return void * @throws Exception */ public function resume() { $state = $this->getState(); if ($state->getStatus() === View\StateInterface::STATUS_SUSPENDED) { $state->setStatus(View\StateInterface::STATUS_IDLE); $state->save(); } } /** * Clear precessed changelog entries * * @return void */ public function clearChangelog() { if ($this->getState()->getMode() === View\StateInterface::MODE_ENABLED) { $this->getChangelog()->clear($this->getState()->getVersionId()); } } /** * Return related state object * * @return View\StateInterface */ public function getState() { if (!$this->state->getViewId()) { $this->state->loadByView($this->getId()); } return $this->state; } /** * Set view state object * * @param View\StateInterface $state * @return ViewInterface */ public function setState(View\StateInterface $state) { $this->state = $state; return $this; } /** * Check whether view is enabled * * @return bool */ public function isEnabled() { return $this->getState()->getMode() === View\StateInterface::MODE_ENABLED; } /** * Check whether view is idle * * @return bool */ public function isIdle() { return $this->getState()->getStatus() === View\StateInterface::STATUS_IDLE; } /** * Check whether view is working * * @return bool */ public function isWorking() { return $this->getState()->getStatus() === View\StateInterface::STATUS_WORKING; } /** * Check whether view is suspended * * @return bool */ public function isSuspended() { return $this->getState()->getStatus() === View\StateInterface::STATUS_SUSPENDED; } /** * Return view updated datetime * * @return string */ public function getUpdated() { return $this->getState()->getUpdated(); } /** * Retrieve linked changelog * * @return View\ChangelogInterface */ public function getChangelog() { if (!$this->changelog->getViewId()) { $this->changelog->setViewId($this->getId()); } return $this->changelog; } /** * Initializes Subscription instance * * @param array $subscriptionConfig * @return SubscriptionInterface */ public function initSubscriptionInstance(array $subscriptionConfig): SubscriptionInterface { return $this->subscriptionFactory->create( [ 'view' => $this, 'tableName' => $subscriptionConfig['name'], 'columnName' => $subscriptionConfig['column'], 'subscriptionModel' => !empty($subscriptionConfig['subscription_model']) ? $subscriptionConfig['subscription_model'] : SubscriptionFactory::INSTANCE_NAME, ] ); } }