7
7
use Magento \Catalog \Model \Category as CategoryModel ;
8
8
use Magento \Catalog \Model \ResourceModel \Category as CategoryResourceModel ;
9
9
use Magento \Catalog \Model \ResourceModel \Product \Collection as ProductCollection ;
10
+ use Magento \Framework \App \ResourceConnection ;
10
11
use Magento \Framework \Indexer \IndexerRegistry ;
11
12
12
13
class CategoryObserver
13
14
{
15
+ /** @var IndexerRegistry */
16
+ private $ indexerRegistry ;
17
+
14
18
/** @var CategoryIndexer */
15
19
private $ indexer ;
16
20
17
21
/** @var ConfigHelper */
18
22
private $ configHelper ;
19
23
24
+ /** @var ResourceConnection */
25
+ protected $ resource ;
26
+
20
27
/**
28
+ * CategoryObserver constructor.
21
29
* @param IndexerRegistry $indexerRegistry
22
30
* @param ConfigHelper $configHelper
31
+ * @param ResourceConnection $resource
23
32
*/
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 ;
26
39
$ this ->indexer = $ indexerRegistry ->get ('algolia_categories ' );
27
40
$ this ->configHelper = $ configHelper ;
41
+ $ this ->resource = $ resource ;
28
42
}
29
43
30
44
/**
@@ -39,13 +53,27 @@ public function __construct(IndexerRegistry $indexerRegistry, ConfigHelper $conf
39
53
*/
40
54
public function beforeSave (CategoryResourceModel $ categoryResource , CategoryModel $ category )
41
55
{
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 ' )) {
44
63
/** @var ProductCollection $productCollection */
45
64
$ 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 () : []);
47
68
69
+ if (!$ this ->indexer ->isScheduled ()) {
70
+ CategoryIndexer::$ affectedProductIds = array_unique (array_merge ($ changedProductIds , $ collectionIds ));
48
71
$ 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
+ }
49
77
}
50
78
});
51
79
@@ -60,8 +88,9 @@ public function beforeSave(CategoryResourceModel $categoryResource, CategoryMode
60
88
*/
61
89
public function beforeDelete (CategoryResourceModel $ categoryResource , CategoryModel $ category )
62
90
{
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 ()) {
65
94
/* we are using products position because getProductCollection() doesn't use correct store */
66
95
$ productCollection = $ category ->getProductsPosition ();
67
96
CategoryIndexer::$ affectedProductIds = array_keys ($ productCollection );
@@ -72,4 +101,27 @@ public function beforeDelete(CategoryResourceModel $categoryResource, CategoryMo
72
101
73
102
return [$ category ];
74
103
}
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
+ }
75
127
}
0 commit comments