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