Skip to content

Commit f28ba40

Browse files
authored
Category Product Updates for Update on Schedule (#819)
1 parent 727da54 commit f28ba40

File tree

3 files changed

+138
-7
lines changed

3 files changed

+138
-7
lines changed

Model/Indexer/CategoryObserver.php

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,38 @@
77
use Magento\Catalog\Model\Category as CategoryModel;
88
use Magento\Catalog\Model\ResourceModel\Category as CategoryResourceModel;
99
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
10+
use Magento\Framework\App\ResourceConnection;
1011
use Magento\Framework\Indexer\IndexerRegistry;
1112

1213
class CategoryObserver
1314
{
15+
/** @var IndexerRegistry */
16+
private $indexerRegistry;
17+
1418
/** @var CategoryIndexer */
1519
private $indexer;
1620

1721
/** @var ConfigHelper */
1822
private $configHelper;
1923

24+
/** @var ResourceConnection */
25+
protected $resource;
26+
2027
/**
28+
* CategoryObserver constructor.
2129
* @param IndexerRegistry $indexerRegistry
2230
* @param ConfigHelper $configHelper
31+
* @param ResourceConnection $resource
2332
*/
24-
public function __construct(IndexerRegistry $indexerRegistry, ConfigHelper $configHelper)
25-
{
33+
public function __construct(
34+
IndexerRegistry $indexerRegistry,
35+
ConfigHelper $configHelper,
36+
ResourceConnection $resource
37+
) {
38+
$this->indexerRegistry = $indexerRegistry;
2639
$this->indexer = $indexerRegistry->get('algolia_categories');
2740
$this->configHelper = $configHelper;
41+
$this->resource = $resource;
2842
}
2943

3044
/**
@@ -39,13 +53,27 @@ public function __construct(IndexerRegistry $indexerRegistry, ConfigHelper $conf
3953
*/
4054
public function beforeSave(CategoryResourceModel $categoryResource, CategoryModel $category)
4155
{
42-
$categoryResource->addCommitCallback(function () use ($category) {
43-
if (!$this->indexer->isScheduled() || $this->configHelper->isQueueActive()) {
56+
$categoryResource->addCommitCallback(function() use ($category) {
57+
$collectionIds = [];
58+
// To reduce the indexing operation for products, only update if these values have changed
59+
if ($category->getOrigData('name') !== $category->getData('name')
60+
|| $category->getOrigData('include_in_menu') !== $category->getData('include_in_menu')
61+
|| $category->getOrigData('is_active') !== $category->getData('is_active')
62+
|| $category->getOrigData('path') !== $category->getData('path')) {
4463
/** @var ProductCollection $productCollection */
4564
$productCollection = $category->getProductCollection();
46-
CategoryIndexer::$affectedProductIds = (array) $productCollection->getColumnValues('entity_id');
65+
$collectionIds = (array) $productCollection->getColumnValues('entity_id');
66+
}
67+
$changedProductIds = ($category->getChangedProductIds() !== null ? (array) $category->getChangedProductIds() : []);
4768

69+
if (!$this->indexer->isScheduled()) {
70+
CategoryIndexer::$affectedProductIds = array_unique(array_merge($changedProductIds, $collectionIds));
4871
$this->indexer->reindexRow($category->getId());
72+
} else {
73+
// missing logic, if scheduled, when category is saved w/out product, products need to be added to _cl
74+
if (count($changedProductIds) === 0 && count($collectionIds) > 0) {
75+
$this->updateCategoryProducts($collectionIds);
76+
}
4977
}
5078
});
5179

@@ -60,8 +88,9 @@ public function beforeSave(CategoryResourceModel $categoryResource, CategoryMode
6088
*/
6189
public function beforeDelete(CategoryResourceModel $categoryResource, CategoryModel $category)
6290
{
63-
$categoryResource->addCommitCallback(function () use ($category) {
64-
if (!$this->indexer->isScheduled() || $this->configHelper->isQueueActive()) {
91+
$categoryResource->addCommitCallback(function() use ($category) {
92+
// mview should be able to handle the changes for catalog_category_product relationship
93+
if (!$this->indexer->isScheduled()) {
6594
/* we are using products position because getProductCollection() doesn't use correct store */
6695
$productCollection = $category->getProductsPosition();
6796
CategoryIndexer::$affectedProductIds = array_keys($productCollection);
@@ -72,4 +101,27 @@ public function beforeDelete(CategoryResourceModel $categoryResource, CategoryMo
72101

73102
return [$category];
74103
}
104+
105+
/**
106+
* @param array $productIds
107+
*/
108+
private function updateCategoryProducts(array $productIds)
109+
{
110+
$productIndexer = $this->indexerRegistry->get('algolia_products');
111+
if (!$productIndexer->isScheduled()) {
112+
// if the product index is not schedule, it should still index these products
113+
$productIndexer->reindexList($productIds);
114+
} else {
115+
$view = $productIndexer->getView();
116+
$changelogTableName = $this->resource->getTableName($view->getChangelog()->getName());
117+
$connection = $this->resource->getConnection();
118+
if ($connection->isTableExists($changelogTableName)) {
119+
$data = [];
120+
foreach ($productIds as $productId) {
121+
$data[] = ['entity_id' => $productId];
122+
}
123+
$connection->insertMultiple($changelogTableName, $data);
124+
}
125+
}
126+
}
75127
}

Model/Observer/CategoryMoveAfter.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Model\Observer;
4+
5+
use Algolia\AlgoliaSearch\Helper\ConfigHelper;
6+
use Magento\Catalog\Model\Category;
7+
use Magento\Framework\App\ResourceConnection;
8+
use Magento\Framework\Event\Observer;
9+
use Magento\Framework\Event\ObserverInterface;
10+
use Magento\Framework\Indexer\IndexerRegistry;
11+
12+
class CategoryMoveAfter implements ObserverInterface
13+
{
14+
15+
/** @var IndexerRegistry */
16+
private $indexerRegistry;
17+
18+
/** @var ConfigHelper */
19+
private $configHelper;
20+
21+
/** @var ResourceConnection */
22+
protected $resource;
23+
24+
/**
25+
* @param IndexerRegistry $indexerRegistry
26+
* @param ConfigHelper $configHelper
27+
* @param ResourceConnection $resource
28+
*/
29+
public function __construct(
30+
IndexerRegistry $indexerRegistry,
31+
ConfigHelper $configHelper,
32+
ResourceConnection $resource
33+
) {
34+
$this->indexerRegistry = $indexerRegistry;
35+
$this->configHelper = $configHelper;
36+
$this->resource = $resource;
37+
}
38+
39+
/**
40+
* Category::move() does not run save so the plugin observing the save method
41+
* is not able to process the products that need updating.
42+
*
43+
* @param Observer $observer
44+
* @return bool|void
45+
*/
46+
public function execute(Observer $observer)
47+
{
48+
/** @var Category $category */
49+
$category = $observer->getEvent()->getCategory();
50+
if (!$this->configHelper->indexProductOnCategoryProductsUpdate($category->getStoreId())) {
51+
return false;
52+
}
53+
54+
$productIndexer = $this->indexerRegistry->get('algolia_products');
55+
if ($category->getOrigData('path') !== $category->getData('path')) {
56+
$productIds = array_keys($category->getProductsPosition());
57+
58+
if (!$productIndexer->isScheduled()) {
59+
// if the product index is not schedule, it should still index these products
60+
$productIndexer->reindexList($productIds);
61+
} else {
62+
$view = $productIndexer->getView();
63+
$changelogTableName = $this->resource->getTableName($view->getChangelog()->getName());
64+
$connection = $this->resource->getConnection();
65+
if ($connection->isTableExists($changelogTableName)) {
66+
$data = [];
67+
foreach ($productIds as $productId) {
68+
$data[] = ['entity_id' => $productId];
69+
}
70+
$connection->insertMultiple($changelogTableName, $data);
71+
}
72+
}
73+
}
74+
}
75+
}

etc/adminhtml/events.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
<observer name="algoliasearch_create_merchandising_query_rule" instance="Algolia\AlgoliaSearch\Model\Observer\Merchandising"/>
4242
</event>
4343

44+
<event name="catalog_category_move_after">
45+
<observer name="algoliasearch_category_move_after" instance="Algolia\AlgoliaSearch\Model\Observer\CategoryMoveAfter"/>
46+
</event>
47+
4448
<event name="algolia_product_collection_add_additional_data">
4549
<observer name="algoliasearch_product_permissions" instance="Algolia\AlgoliaSearch\Model\Observer\CatalogPermissions\ProductCollectionAddPermissions" />
4650
</event>

0 commit comments

Comments
 (0)