2
2
3
3
namespace Algolia \AlgoliaSearch \Service \Product ;
4
4
5
+ use Magento \Framework \DB \Select ;
6
+ use Magento \Catalog \Model \ResourceModel \Product \Collection as ProductCollection ;
5
7
use Magento \Catalog \Model \ResourceModel \Product \CollectionFactory ;
6
8
use Magento \Framework \Indexer \IndexerRegistry ;
7
9
use Magento \Framework \Indexer \IndexerInterface ;
10
+ use Zend_Db_Select ;
8
11
9
12
class MissingPriceIndexHandler
10
13
{
14
+ public const PRICE_INDEX_TABLE = 'catalog_product_index_price ' ;
15
+ public const PRICE_INDEX_TABLE_ALIAS = 'price_index ' ;
16
+ public const MAIN_TABLE_ALIAS = 'e ' ;
17
+
11
18
protected IndexerInterface $ indexer ;
12
19
public function __construct (
13
20
protected CollectionFactory $ productCollectionFactory ,
@@ -18,12 +25,12 @@ public function __construct(
18
25
}
19
26
20
27
/**
21
- * @param array $productIds
22
- * @return int [] Array of product IDs that were reindexed by this repair operation
28
+ * @param string[]|ProductCollection $products
29
+ * @return string [] Array of product IDs that were reindexed by this repair operation
23
30
*/
24
- public function refreshPriceIndex (array $ productIds ): array
31
+ public function refreshPriceIndex (array | ProductCollection $ products ): array
25
32
{
26
- $ reindexIds = $ this ->getProductIdsToReindex ($ productIds );
33
+ $ reindexIds = $ this ->getProductIdsToReindex ($ products );
27
34
if (empty ($ reindexIds )) {
28
35
return [];
29
36
}
@@ -34,16 +41,25 @@ public function refreshPriceIndex(array $productIds): array
34
41
}
35
42
36
43
/**
37
- * @param int[] $productIds
38
- * @return int []
44
+ * @param string[]|ProductCollection $products
45
+ * @return string []
39
46
*/
40
- protected function getProductIdsToReindex (array $ productIds ): array
47
+ protected function getProductIdsToReindex (array | ProductCollection $ products ): array
41
48
{
49
+ $ productIds = $ products instanceof ProductCollection
50
+ ? $ this ->getExpandedProductCollectionIds ($ products )
51
+ : $ products ;
52
+
42
53
$ state = $ this ->indexer ->getState ()->getStatus ();
43
54
if ($ state === \Magento \Framework \Indexer \StateInterface::STATUS_INVALID ) {
44
55
return $ productIds ;
45
56
}
46
57
58
+ return $ this ->filterProductIds ($ productIds );
59
+ }
60
+
61
+ protected function filterProductIds (array $ productIds ): array
62
+ {
47
63
$ collection = $ this ->productCollectionFactory ->create ();
48
64
49
65
$ collection ->addAttributeToSelect (['name ' , 'price ' ]);
@@ -56,8 +72,85 @@ protected function getProductIdsToReindex(array $productIds): array
56
72
57
73
$ collection ->getSelect ()
58
74
->where ('price_index.entity_id IS NULL ' )
59
- ->where ('entity_id IN (?) ' , $ productIds );
75
+ ->where ('e. entity_id IN (?) ' , $ productIds );
60
76
61
77
return $ collection ->getAllIds ();
62
78
}
79
+
80
+ protected function getExpandedProductCollectionIds (ProductCollection $ collection ): array
81
+ {
82
+ $ expandedCollection = clone $ collection ;
83
+
84
+ $ select = $ expandedCollection ->getSelect ();
85
+
86
+ $ joins = $ select ->getPart (Zend_Db_Select::FROM );
87
+
88
+ $ priceIndexJoin = $ this ->getPriceIndexJoinAlias ($ joins );
89
+
90
+ if (!$ priceIndexJoin ) {
91
+ // nothing to do here - keep calm and carry on
92
+ return [];
93
+ }
94
+
95
+ $ modifyJoin = &$ joins [$ priceIndexJoin ];
96
+ $ modifyJoin ['joinType ' ] = Zend_Db_Select::LEFT_JOIN ;
97
+
98
+ $ this ->rebuildJoins ($ select , $ joins );
99
+
100
+ return $ expandedCollection ->getAllIds ();
101
+ }
102
+
103
+ protected function rebuildJoins (Select $ select , array $ joins ): void
104
+ {
105
+ $ select ->reset (Zend_Db_Select::FROM );
106
+ foreach ($ joins as $ alias => $ joinData ) {
107
+ if ($ joinData ['joinType ' ] === Zend_Db_Select::FROM ) {
108
+ $ select ->from ([$ alias => $ joinData ['tableName ' ]]);
109
+ } elseif ($ joinData ['joinType ' ] === Zend_Db_Select::LEFT_JOIN ) {
110
+ $ select ->joinLeft (
111
+ [$ alias => $ joinData ['tableName ' ]],
112
+ $ joinData ['joinCondition ' ],
113
+ [],
114
+ $ joinData ['schema ' ]
115
+ );
116
+ } else {
117
+ $ select ->join (
118
+ [$ alias => $ joinData ['tableName ' ]],
119
+ $ joinData ['joinCondition ' ],
120
+ [],
121
+ $ joinData ['schema ' ]
122
+ );
123
+ }
124
+ $ sql = $ select ->__toString ();
125
+ }
126
+ }
127
+
128
+ private function inspectJoins (array $ joins ): void {
129
+ foreach ($ joins as $ alias => $ joinData ) {
130
+ echo "Table Alias: $ alias \n" ;
131
+ echo "Table Name: {$ joinData ['tableName ' ]}\n" ;
132
+ echo "Join Type: {$ joinData ['joinType ' ]}\n" ;
133
+ echo "Join Condition: " . ($ joinData ['joinCondition ' ] ?? 'N/A ' ) . "\n\n" ;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * @param array<string, array> $joins
139
+ * @return string
140
+ */
141
+ protected function getPriceIndexJoinAlias (array $ joins ): string
142
+ {
143
+ if (isset ($ joins [self ::PRICE_INDEX_TABLE_ALIAS ])) {
144
+ return self ::PRICE_INDEX_TABLE_ALIAS ;
145
+ }
146
+ else {
147
+ foreach ($ joins as $ alias => $ joinData ) {
148
+ if ($ joinData ['tableName ' ] === self ::PRICE_INDEX_TABLE ) {
149
+ return $ alias ;
150
+ }
151
+ }
152
+ }
153
+
154
+ return "" ;
155
+ }
63
156
}
0 commit comments