14
14
use Magento \Catalog \Model \ResourceModel \Product \Collection ;
15
15
use Magento \Catalog \Model \ResourceModel \Product \CollectionFactory ;
16
16
use Magento \CatalogWidget \Model \Rule ;
17
+ use Magento \Framework \App \ObjectManager ;
18
+ use Magento \Framework \App \ResourceConnection ;
19
+ use Magento \Framework \EntityManager \MetadataPool ;
17
20
use Magento \Framework \Exception \LocalizedException ;
18
21
use Magento \Framework \Exception \NoSuchEntityException ;
19
22
use Magento \Rule \Model \Condition \Combine ;
@@ -53,25 +56,41 @@ class ProductTotals
53
56
*/
54
57
private $ categoryRepository ;
55
58
59
+ /**
60
+ * @var MetadataPool
61
+ */
62
+ private MetadataPool $ metadataPool ;
63
+
64
+ /**
65
+ * @var ResourceConnection
66
+ */
67
+ private ResourceConnection $ resource ;
68
+
56
69
/**
57
70
* @param CollectionFactory $productCollectionFactory
58
71
* @param Builder $sqlBuilder
59
72
* @param Rule $rule
60
73
* @param Conditions $conditionsHelper
61
74
* @param CategoryRepositoryInterface $categoryRepository
75
+ * @param MetadataPool|null $metadataPool
76
+ * @param ResourceConnection|null $resource
62
77
*/
63
78
public function __construct (
64
79
CollectionFactory $ productCollectionFactory ,
65
80
Builder $ sqlBuilder ,
66
81
Rule $ rule ,
67
82
Conditions $ conditionsHelper ,
68
- CategoryRepositoryInterface $ categoryRepository
83
+ CategoryRepositoryInterface $ categoryRepository ,
84
+ ?MetadataPool $ metadataPool = null ,
85
+ ?ResourceConnection $ resource = null
69
86
) {
70
87
$ this ->productCollectionFactory = $ productCollectionFactory ;
71
88
$ this ->sqlBuilder = $ sqlBuilder ;
72
89
$ this ->rule = $ rule ;
73
90
$ this ->conditionsHelper = $ conditionsHelper ;
74
91
$ this ->categoryRepository = $ categoryRepository ;
92
+ $ this ->metadataPool = $ metadataPool ?: ObjectManager::getInstance ()->get (MetadataPool::class);
93
+ $ this ->resource = $ resource ?: ObjectManager::getInstance ()->get (ResourceConnection::class);
75
94
}
76
95
77
96
/**
@@ -159,37 +178,85 @@ private function getProductCollection(string $conditions, bool $usePriceIndex =
159
178
return $ collection ;
160
179
}
161
180
181
+ /**
182
+ * Get parent products that don't have stand-alone properties (e.g. price or special price)
183
+ *
184
+ * @param Collection $collection
185
+ * @return Collection|null
186
+ * @throws \Exception
187
+ */
188
+ private function getParentProductsCollection (Collection $ collection ): ?Collection
189
+ {
190
+ $ parentProducts = $ this ->productCollectionFactory ->create ();
191
+ $ linkField = $ this ->metadataPool ->getMetadata (\Magento \Catalog \Api \Data \ProductInterface::class)
192
+ ->getLinkField ();
193
+ $ connection = $ this ->resource ->getConnection ();
194
+ $ productIds = $ connection ->fetchCol (
195
+ $ connection
196
+ ->select ()
197
+ ->from (['e ' => $ collection ->getTable ('catalog_product_entity ' )], ['link_table.parent_id ' ])
198
+ ->joinInner (
199
+ ['link_table ' => $ collection ->getTable ('catalog_product_super_link ' )],
200
+ 'link_table.product_id = e. ' . $ linkField ,
201
+ []
202
+ )
203
+ ->where ('link_table.product_id IN (?) ' , $ collection ->getAllIds ())
204
+ );
205
+ if ($ productIds ) {
206
+ $ parentProducts ->addIdFilter ($ productIds );
207
+ return $ parentProducts ;
208
+ }
209
+
210
+ return null ;
211
+ }
212
+
162
213
/**
163
214
* Retrieve count of all enabled products
164
215
*
165
216
* @param string $conditions
166
217
* @return int number of enabled products
218
+ * @throws LocalizedException
219
+ * @throws \Exception
167
220
*/
168
221
private function getEnabledCount (string $ conditions ): int
169
222
{
170
223
$ collection = $ this ->getProductCollection ($ conditions , true );
171
224
$ collection ->addAttributeToFilter ('status ' , Status::STATUS_ENABLED );
172
- return $ collection ->getSize ();
225
+ $ count = $ collection ->getSize ();
226
+ if ($ collection ->getSize () && $ parentProducts = $ this ->getParentProductsCollection ($ collection )) {
227
+ $ parentProducts ->addAttributeToFilter ('status ' , Status::STATUS_ENABLED );
228
+ $ count += $ parentProducts ->getSize ();
229
+ }
230
+
231
+ return $ count ;
173
232
}
174
233
175
234
/**
176
235
* Retrieve count of all disabled products
177
236
*
178
237
* @param string $conditions
179
238
* @return int number of disabled products
239
+ * @throws \Exception
180
240
*/
181
241
private function getDisabledCount (string $ conditions ): int
182
242
{
183
243
$ collection = $ this ->getProductCollection ($ conditions , false );
184
244
$ collection ->addAttributeToFilter ('status ' , Status::STATUS_DISABLED );
185
- return $ collection ->getSize ();
245
+ $ count = $ collection ->getSize ();
246
+ if ($ count && $ parentProducts = $ this ->getParentProductsCollection ($ collection )) {
247
+ $ parentProducts ->addAttributeToFilter ('status ' , Status::STATUS_DISABLED );
248
+ $ count += $ parentProducts ->getSize ();
249
+ }
250
+
251
+ return $ count ;
186
252
}
187
253
188
254
/**
189
255
* Retrieve count of all not visible individually products
190
256
*
191
257
* @param string $conditions
192
258
* @return int number of products not visible individually
259
+ * @throws \Exception
193
260
*/
194
261
private function getNotVisibleCount (string $ conditions ): int
195
262
{
@@ -202,7 +269,20 @@ private function getNotVisibleCount(string $conditions): int
202
269
Visibility::VISIBILITY_IN_SEARCH
203
270
]
204
271
);
205
- return $ collection ->getSize ();
272
+ $ count = $ collection ->getSize ();
273
+ if ($ count && $ parentProducts = $ this ->getParentProductsCollection ($ collection )) {
274
+ $ parentProducts ->addAttributeToFilter ('status ' , Status::STATUS_ENABLED );
275
+ $ parentProducts ->addAttributeToFilter (
276
+ 'visibility ' ,
277
+ [
278
+ Visibility::VISIBILITY_NOT_VISIBLE ,
279
+ Visibility::VISIBILITY_IN_SEARCH
280
+ ]
281
+ );
282
+ $ count += $ parentProducts ->getSize ();
283
+ }
284
+
285
+ return $ count ;
206
286
}
207
287
208
288
/**
0 commit comments