From ff86fb9ef0dfdd5bac9716695be872e086ab1add Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@ebay.com> Date: Sun, 15 Mar 2015 15:00:36 +0200 Subject: [PATCH] MAGETWO-33690: Category page displays outdated prices after catalog price rule is deleted --- app/code/Magento/Catalog/etc/di.xml | 3 - .../Model/Indexer/AbstractIndexer.php | 28 +++- app/code/Magento/CatalogRule/Model/Rule.php | 34 +++++ .../Model/Indexer/AbstractIndexerTest.php | 17 ++- .../CatalogRule/Test/Unit/Model/RuleTest.php | 65 +++++++++- .../Model/Indexer/CatalogRulePlugin.php | 74 ----------- .../Model/Indexer/CatalogRulePluginTest.php | 121 ------------------ 7 files changed, 140 insertions(+), 202 deletions(-) delete mode 100644 app/code/Magento/PageCache/Model/Indexer/CatalogRulePlugin.php delete mode 100644 app/code/Magento/PageCache/Test/Unit/Model/Indexer/CatalogRulePluginTest.php diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index c60e7710f85..971bebcac32 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -171,9 +171,6 @@ <plugin name="catalogProductFlatIndexerStoreGroup" type="Magento\Catalog\Model\Indexer\Product\Flat\Plugin\StoreGroup" /> <plugin name="categoryStoreGroupAroundSave" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\StoreGroup"/> </type> - <type name="Magento\CatalogRule\Model\Indexer\AbstractIndexer"> - <plugin name="abstractIndexerAroundSave" type="Magento\PageCache\Model\Indexer\CatalogRulePlugin"/> - </type> <type name="Magento\Customer\Api\GroupRepositoryInterface"> <plugin name="invalidatePriceIndexerOnCustomerGroup" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\CustomerGroup"/> </type> diff --git a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php index cf52ebbe066..170053df37c 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php @@ -16,12 +16,22 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt */ protected $indexBuilder; + /** + * Application Event Dispatcher + * + * @var \Magento\Framework\Event\ManagerInterface + */ + protected $_eventManager; + /** * @param IndexBuilder $indexBuilder */ - public function __construct(IndexBuilder $indexBuilder) - { + public function __construct( + IndexBuilder $indexBuilder, + \Magento\Framework\Event\ManagerInterface $eventManager + ) { $this->indexBuilder = $indexBuilder; + $this->_eventManager = $eventManager; } /** @@ -43,6 +53,20 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt public function executeFull() { $this->indexBuilder->reindexFull(); + $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]); + } + + /** + * Get affected cache tags + * + * @return array + */ + public function getIdentities() + { + return [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ]; } /** diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php index 61eac7c2b59..bcb85979fc7 100644 --- a/app/code/Magento/CatalogRule/Model/Rule.php +++ b/app/code/Magento/CatalogRule/Model/Rule.php @@ -143,6 +143,11 @@ class Rule extends \Magento\Rule\Model\AbstractModel */ protected $dateTime; + /** + * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor; + */ + protected $_ruleProductProcessor; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -158,6 +163,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel * @param \Magento\CatalogRule\Helper\Data $catalogRuleData * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList * @param \Magento\Framework\Stdlib\DateTime $dateTime + * @param \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $relatedCacheTypes @@ -179,6 +185,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel \Magento\CatalogRule\Helper\Data $catalogRuleData, \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList, \Magento\Framework\Stdlib\DateTime $dateTime, + \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $relatedCacheTypes = [], @@ -195,6 +202,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel $this->_cacheTypesList = $cacheTypesList; $this->_relatedCacheTypes = $relatedCacheTypes; $this->dateTime = $dateTime; + $this->_ruleProductProcessor = $ruleProductProcessor; parent::__construct($context, $registry, $formFactory, $localeDate, $resource, $resourceCollection, $data); } @@ -445,4 +453,30 @@ class Rule extends \Magento\Rule\Model\AbstractModel } return $this; } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function afterSave() + { + if ($this->isObjectNew()) { + $this->_ruleProductProcessor->reindexList($this->getMatchingProductIds()); + } else { + $this->_ruleProductProcessor->getIndexer()->invalidate(); + } + return parent::afterSave(); + } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function afterDelete() + { + $this->_ruleProductProcessor->getIndexer()->invalidate(); + return parent::afterDelete(); + } } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php index 526ea778641..6c2fd2056d7 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php @@ -18,13 +18,22 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase */ protected $indexer; + /** + * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $_eventManagerMock; + protected function setUp() { + $this->_eventManagerMock = $this->getMock('\Magento\Framework\Event\ManagerInterface'); $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false); $this->indexer = $this->getMockForAbstractClass( 'Magento\CatalogRule\Model\Indexer\AbstractIndexer', - [$this->indexBuilder] + [ + $this->indexBuilder, + $this->_eventManagerMock + ] ); } @@ -39,6 +48,12 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase public function testExecuteFull() { $this->indexBuilder->expects($this->once())->method('reindexFull'); + $this->_eventManagerMock->expects($this->once()) + ->method('dispatch') + ->with( + 'clean_cache_by_tags', + ['object' => $this->indexer] + ); $this->indexer->executeFull(); } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php index 095ca9891a7..de720aa681a 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php @@ -31,6 +31,26 @@ class RuleTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Rule\Model\Condition\Combine|\PHPUnit_Framework_MockObject_MockObject */ protected $condition; + /** + * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor|\PHPUnit_Framework_MockObject_MockObject + */ + protected $_ruleProductProcessor; + + /** + * @var \Magento\Catalog\Model\Resource\Product\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $_productCollectionFactory; + + /** + * @var \Magento\Framework\Model\Resource\Iterator|\PHPUnit_Framework_MockObject_MockObject + */ + protected $_resourceIterator; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productModel; + protected function setUp() { $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface'); @@ -74,13 +94,39 @@ class RuleTest extends \PHPUnit_Framework_TestCase '', false ); + $this->_ruleProductProcessor = $this->getMock( + '\Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor', + [], + [], + '', + false + ); + + $this->_productCollectionFactory = $this->getMock( + '\Magento\Catalog\Model\Resource\Product\CollectionFactory', + ['create'], + [], + '', + false + ); + + $this->_resourceIterator = $this->getMock( + '\Magento\Framework\Model\Resource\Iterator', + ['walk'], + [], + '', + false + ); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->rule = $this->objectManagerHelper->getObject( 'Magento\CatalogRule\Model\Rule', [ 'storeManager' => $this->storeManager, - 'combineFactory' => $this->combineFactory + 'combineFactory' => $this->combineFactory, + 'ruleProductProcessor' => $this->_ruleProductProcessor, + 'productCollectionFactory' => $this->_productCollectionFactory, + 'resourceIterator' => $this->_resourceIterator, ] ); } @@ -141,4 +187,21 @@ class RuleTest extends \PHPUnit_Framework_TestCase [true], ]; } + + public function testAfterDelete() + { + $indexer = $this->getMock('\Magento\Indexer\Model\IndexerInterface'); + $indexer->expects($this->once())->method('invalidate'); + $this->_ruleProductProcessor->expects($this->once())->method('getIndexer')->will($this->returnValue($indexer)); + $this->rule->afterDelete(); + } + + public function testAfterUpdate() + { + $this->rule->isObjectNew(false); + $indexer = $this->getMock('\Magento\Indexer\Model\IndexerInterface'); + $indexer->expects($this->once())->method('invalidate'); + $this->_ruleProductProcessor->expects($this->once())->method('getIndexer')->will($this->returnValue($indexer)); + $this->rule->afterSave(); + } } diff --git a/app/code/Magento/PageCache/Model/Indexer/CatalogRulePlugin.php b/app/code/Magento/PageCache/Model/Indexer/CatalogRulePlugin.php deleted file mode 100644 index e0088a87904..00000000000 --- a/app/code/Magento/PageCache/Model/Indexer/CatalogRulePlugin.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\PageCache\Model\Indexer; - -/** - * Class CatalogRulePlugin - * @package Magento\PageCache\Model\Indexer - */ -class CatalogRulePlugin -{ - /** - * @var \Magento\PageCache\Model\Config - */ - protected $config; - - /** - * @var \Magento\Framework\App\CacheInterface - */ - protected $cache; - - /** - * @var \Magento\Framework\App\Cache\Type\FrontendPool - */ - protected $pool; - - /** - * @param \Magento\PageCache\Model\Config $config - * @param \Magento\Framework\App\Cache\TypeListInterface $typeList - * @param \Magento\Framework\App\Cache\Type\FrontendPool $pool - */ - public function __construct( - \Magento\PageCache\Model\Config $config, - \Magento\Framework\App\CacheInterface $cache, - \Magento\Framework\App\Cache\Type\FrontendPool $pool - ) { - $this->config = $config; - $this->cache = $cache; - $this->pool = $pool; - } - - /** - * @param \Magento\CatalogRule\Model\Indexer\AbstractIndexer $subject - * - * @return \Magento\CatalogRule\Model\Indexer\AbstractIndexer - */ - public function afterExecuteFull( - \Magento\CatalogRule\Model\Indexer\AbstractIndexer $subject - ) { - if ($this->config->isEnabled()) { - $this->pool->get( - \Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER - )->clean( - \Zend_Cache::CLEANING_MODE_ALL, - [ - \Magento\Catalog\Model\Category::CACHE_TAG, - \Magento\Catalog\Model\Product::CACHE_TAG - ] - ); - - $this->cache->clean( - [ - \Magento\Catalog\Model\Category::CACHE_TAG, - \Magento\Catalog\Model\Product::CACHE_TAG, - \Magento\Catalog\Model\Product\Compare\Item::CACHE_TAG, - \Magento\Wishlist\Model\Wishlist::CACHE_TAG - ] - ); - } - return $subject; - } -} diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Indexer/CatalogRulePluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Indexer/CatalogRulePluginTest.php deleted file mode 100644 index 0e64779bebc..00000000000 --- a/app/code/Magento/PageCache/Test/Unit/Model/Indexer/CatalogRulePluginTest.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\PageCache\Test\Unit\Model\Indexer; - -/** - * Class CatalogRulePluginTest - * @package Magento\PageCache\Test\Unit\Model\Indexer - */ -class CatalogRulePluginTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $configMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $cacheMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $poolMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $frontCache; - - /** - * @var \Magento\PageCache\Model\Indexer\CatalogRulePlugin - */ - protected $model; - - protected function setUp() - { - $this->configMock = $this->getMock( - '\Magento\PageCache\Model\Config', - ['isEnabled'], - [], - '', - false - ); - - $this->cacheMock = $this->getMockForAbstractClass( - '\Magento\Framework\App\CacheInterface', - [], - '', - false, - true, - true, - ['clean'] - ); - - $this->frontCache = $this->getMockForAbstractClass( - '\Magento\Framework\Cache\FrontendInterface', - [], - '', - false, - true, - true, - ['clean'] - ); - - $this->poolMock = $this->getMock( - '\Magento\Framework\App\Cache\Type\FrontendPool', - ['get'], - ['clean'], - '', - false - ); - - $this->model = new \Magento\PageCache\Model\Indexer\CatalogRulePlugin( - $this->configMock, - $this->cacheMock, - $this->poolMock - ); - } - - public function testAfterExecuteFull() - { - $this->configMock->expects($this->once()) - ->method('isEnabled') - ->willReturn(true); - $this->poolMock->expects($this->once()) - ->method('get') - ->with(\Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER) - ->willReturn($this->frontCache); - $this->frontCache->expects($this->once())->method('clean') - ->with( - \Zend_Cache::CLEANING_MODE_ALL, - [ - \Magento\Catalog\Model\Category::CACHE_TAG, - \Magento\Catalog\Model\Product::CACHE_TAG - ] - ); - $this->cacheMock->expects($this->once()) - ->method('clean') - ->with( - [ - \Magento\Catalog\Model\Category::CACHE_TAG, - \Magento\Catalog\Model\Product::CACHE_TAG, - \Magento\Catalog\Model\Product\Compare\Item::CACHE_TAG, - \Magento\Wishlist\Model\Wishlist::CACHE_TAG - ] - ); - - $this->model->afterExecuteFull( - $this->getMockForAbstractClass( - '\Magento\CatalogRule\Model\Indexer\AbstractIndexer', - [], - '', - false - ) - ); - } -} -- GitLab