Skip to content

Commit

Permalink
Merge pull request #2660 from magento-honey-badgers/MAGETWO-91437-Cat…
Browse files Browse the repository at this point in the history
…egory-Product-Indexer

[honey] MAGETWO-91437: Catalog_category_product_index table doesn't update after deleting category
  • Loading branch information
cpartica authored Jun 8, 2018
2 parents 4688217 + 90e95ff commit 2b7beca
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 0 deletions.
22 changes: 22 additions & 0 deletions app/code/Magento/Catalog/Model/ResourceModel/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
namespace Magento\Catalog\Model\ResourceModel;

use Magento\Catalog\Model\Indexer\Category\Product\Processor;
use Magento\Framework\DataObject;
use Magento\Framework\EntityManager\EntityManager;

/**
Expand Down Expand Up @@ -82,6 +84,11 @@ class Category extends AbstractResource
*/
protected $aggregateCount;

/**
* @var Processor
*/
private $indexerProcessor;

/**
* Category constructor.
* @param \Magento\Eav\Model\Entity\Context $context
Expand All @@ -90,6 +97,7 @@ class Category extends AbstractResource
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param Category\TreeFactory $categoryTreeFactory
* @param Category\CollectionFactory $categoryCollectionFactory
* @param Processor $indexerProcessor
* @param array $data
* @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
*/
Expand All @@ -100,6 +108,7 @@ public function __construct(
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Catalog\Model\ResourceModel\Category\TreeFactory $categoryTreeFactory,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
Processor $indexerProcessor,
$data = [],
\Magento\Framework\Serialize\Serializer\Json $serializer = null
) {
Expand All @@ -113,6 +122,7 @@ public function __construct(
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_eventManager = $eventManager;
$this->connectionName = 'catalog';
$this->indexerProcessor = $indexerProcessor;
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\Serialize\Serializer\Json::class);
}
Expand Down Expand Up @@ -197,6 +207,18 @@ protected function _beforeDelete(\Magento\Framework\DataObject $object)
$this->deleteChildren($object);
}

/**
* Mark Category indexer as invalid to be picked up by cron.
*
* @param DataObject $object
* @return $this
*/
protected function _afterDelete(DataObject $object)
{
$this->indexerProcessor->markIndexerAsInvalid();
return parent::_afterDelete($object);
}

/**
* Delete children categories of specific category
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;

use Magento\Catalog\Model\Factory;
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
use Magento\Catalog\Model\ResourceModel\Category;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Eav\Model\Config;
Expand Down Expand Up @@ -91,6 +92,11 @@ class CategoryTest extends \PHPUnit\Framework\TestCase
*/
private $serializerMock;

/**
* @var Processor|\PHPUnit_Framework_MockObject_MockObject
*/
private $indexerProcessorMock;

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -121,6 +127,9 @@ protected function setUp()
$this->collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$this->indexerProcessorMock = $this->getMockBuilder(Processor::class)
->disableOriginalConstructor()
->getMock();

$this->serializerMock = $this->getMockBuilder(Json::class)->getMock();

Expand All @@ -131,6 +140,7 @@ protected function setUp()
$this->managerMock,
$this->treeFactoryMock,
$this->collectionFactoryMock,
$this->indexerProcessorMock,
[],
$this->serializerMock
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin;

use Magento\Catalog\Model\ResourceModel\Category as Resource;
use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor;

/**
* Perform indexer invalidation after a category delete.
*/
class Category
{
/**
* @var Processor
*/
private $fulltextIndexerProcessor;

/**
* @param Processor $fulltextIndexerProcessor
*/
public function __construct(Processor $fulltextIndexerProcessor)
{
$this->fulltextIndexerProcessor = $fulltextIndexerProcessor;
}

/**
* Mark fulltext indexer as invalid post-deletion of category.
*
* @param Resource $subjectCategory
* @param Resource $resultCategory
* @return Resource
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterDelete(Resource $subjectCategory, Resource $resultCategory) : Resource
{
$this->fulltextIndexerProcessor->markIndexerAsInvalid();

return $resultCategory;
}
}
3 changes: 3 additions & 0 deletions app/code/Magento/CatalogSearch/etc/adminhtml/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@
<argument name="filter" xsi:type="object">Magento\CatalogSearch\Ui\DataProvider\Product\AddFulltextFilterToCollection</argument>
</arguments>
</type>
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/CatalogSearch/etc/webapi_rest/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/CatalogSearch/etc/webapi_soap/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Category">
<plugin name="fulltext_search_indexer" type="Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin\Category"/>
</type>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class ProductTest extends \PHPUnit\Framework\TestCase
*/
protected $productResource;

/**
* @var \Magento\Catalog\Api\CategoryRepositoryInterface
*/
private $categoryRepository;

protected function setUp()
{
/** @var \Magento\Framework\Indexer\IndexerInterface indexer */
Expand All @@ -39,6 +44,10 @@ protected function setUp()
$this->productResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
\Magento\Catalog\Model\ResourceModel\Product::class
);

$this->categoryRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
\Magento\Catalog\Api\CategoryRepositoryInterface::class
);
}

/**
Expand Down Expand Up @@ -200,6 +209,25 @@ public function testCategoryCreate()
}
}

/**
* @magentoAppArea adminhtml
* @depends testReindexAll
*/
public function testCatalogCategoryProductIndexInvalidateAfterDelete()
{
$indexerShouldBeValid = (bool)$this->indexer->isInvalid();

$categories = $this->getCategories(1);
$this->categoryRepository->delete(array_pop($categories));

$state = $this->indexer->getState();
$state->loadByIndexer($this->indexer->getId());
$status = $state->getStatus();

$this->assertFalse($indexerShouldBeValid);
$this->assertEquals(\Magento\Framework\Indexer\StateInterface::STATUS_INVALID, $status);
}

/**
* @param int $count
* @return Category[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Model\Plugin;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\Category;
use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor;
use Magento\TestFramework\Helper\Bootstrap;

class CategoryTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Processor
*/
private $indexerProcessor;

/**
* @var CategoryRepositoryInterface
*/
private $categoryRepository;

protected function setUp()
{
$this->indexerProcessor = Bootstrap::getObjectManager()->create(Processor::class);
$this->categoryRepository = Bootstrap::getObjectManager()->create(CategoryRepositoryInterface::class);
}

/**
* @magentoDataFixture Magento/Catalog/_files/indexer_catalog_category.php
* @magentoAppArea adminhtml
*/
public function testIndexerInvalidatedAfterCategoryDelete()
{
$this->indexerProcessor->reindexAll();
$isIndexerValid = (bool)$this->indexerProcessor->getIndexer()->isValid();

$category = $this->getCategories(1);
$this->categoryRepository->delete(array_pop($category));

$state = $this->indexerProcessor->getIndexer()->getState();
$state->loadByIndexer($this->indexerProcessor->getIndexerId());
$status = $state->getStatus();

$this->assertTrue($isIndexerValid);
$this->assertEquals(\Magento\Framework\Indexer\StateInterface::STATUS_INVALID, $status);
}

/**
* @param int $count
* @return Category[]
*/
private function getCategories($count)
{
/** @var Category $category */
$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
\Magento\Catalog\Model\Category::class
);

$result = $category->getCollection()->addAttributeToSelect('name')->getItems();
$result = array_slice($result, 2);

return array_slice($result, 0, $count);
}
}

0 comments on commit 2b7beca

Please sign in to comment.