33 * Copyright 2015 Adobe
44 * All Rights Reserved.
55 */
6+ declare (strict_types=1 );
7+
68namespace Magento \CatalogRuleConfigurable \Plugin \CatalogRule \Model \Rule ;
79
8- use Magento \ConfigurableProduct \Model \Product \Type \Configurable ;
910use Magento \CatalogRuleConfigurable \Plugin \CatalogRule \Model \ConfigurableProductsProvider ;
11+ use Magento \ConfigurableProduct \Model \ResourceModel \Product \Type \Configurable as ConfigurableProductsResourceModel ;
1012
1113/**
1214 * Add configurable sub products to catalog rule indexer on full reindex
1315 */
1416class ConfigurableProductHandler
1517{
1618 /**
17- * @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable
19+ * @var ConfigurableProductsResourceModel
1820 */
19- private $ configurable ;
21+ private ConfigurableProductsResourceModel $ configurable ;
2022
2123 /**
22- * @var \Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ ConfigurableProductsProvider
24+ * @var ConfigurableProductsProvider
2325 */
24- private $ configurableProductsProvider ;
26+ private ConfigurableProductsProvider $ configurableProductsProvider ;
2527
2628 /**
2729 * @var array
2830 */
29- private $ childrenProducts = [];
31+ private array $ childrenProducts = [];
3032
3133 /**
32- * @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurable
34+ * @param ConfigurableProductsResourceModel $configurable
3335 * @param ConfigurableProductsProvider $configurableProductsProvider
3436 */
3537 public function __construct (
36- \ Magento \ ConfigurableProduct \ Model \ ResourceModel \ Product \ Type \ Configurable $ configurable ,
37- ConfigurableProductsProvider $ configurableProductsProvider
38+ ConfigurableProductsResourceModel $ configurable ,
39+ ConfigurableProductsProvider $ configurableProductsProvider
3840 ) {
3941 $ this ->configurable = $ configurable ;
4042 $ this ->configurableProductsProvider = $ configurableProductsProvider ;
@@ -48,40 +50,71 @@ public function __construct(
4850 * @return array
4951 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
5052 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
53+ * @SuppressWarnings(PHPMD.NPathComplexity)
54+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
5155 */
5256 public function aroundGetMatchingProductIds (
5357 \Magento \CatalogRule \Model \Rule $ rule ,
5458 \Closure $ proceed
55- ) {
59+ ): array {
5660 $ productsFilter = $ rule ->getProductsFilter () ? (array ) $ rule ->getProductsFilter () : [];
5761 if ($ productsFilter ) {
58- $ parentProductIds = $ this ->configurable ->getParentIdsByChild ($ productsFilter );
59- $ rule ->setProductsFilter (array_unique (array_merge ($ productsFilter , $ parentProductIds )));
62+ $ rule ->setProductsFilter (
63+ array_unique (
64+ array_merge (
65+ $ productsFilter ,
66+ $ this ->configurable ->getParentIdsByChild ($ productsFilter )
67+ )
68+ )
69+ );
6070 }
6171
6272 $ productIds = $ proceed ();
73+ foreach ($ productIds as $ productId => $ productData ) {
74+ if ($ this ->hasAntecedentRule ((int ) $ productId )) {
75+ $ productIds [$ productId ]['has_antecedent_rule ' ] = true ;
76+ }
77+ }
6378
64- $ configurableProductIds = $ this ->configurableProductsProvider ->getIds (array_keys ($ productIds ));
65- foreach ( $ configurableProductIds as $ productId ) {
66- if (! isset ( $ this ->childrenProducts [$ productId ])) {
67- $ this -> childrenProducts [ $ productId ] = $ this ->configurable ->getChildrenIds ($ productId )[0 ];
79+ foreach ( $ this ->configurableProductsProvider ->getIds (array_keys ($ productIds )) as $ configurableProductId ) {
80+ if (! isset ( $ this -> childrenProducts [ $ configurableProductId ]) ) {
81+ $ this ->childrenProducts [$ configurableProductId ] =
82+ $ this ->configurable ->getChildrenIds ($ configurableProductId )[0 ];
6883 }
69- $ subProductIds = $ this -> childrenProducts [ $ productId ];
70- $ parentValidationResult = isset ($ productIds [$ productId ])
71- ? array_filter ($ productIds [$ productId ])
84+
85+ $ parentValidationResult = isset ($ productIds [$ configurableProductId ])
86+ ? array_filter ($ productIds [$ configurableProductId ])
7287 : [];
73- $ processAllChildren = !$ productsFilter || in_array ($ productId , $ productsFilter );
74- foreach ($ subProductIds as $ subProductId ) {
75- if ($ processAllChildren || in_array ($ subProductId , $ productsFilter )) {
76- $ childValidationResult = isset ($ productIds [$ subProductId ])
77- ? array_filter ($ productIds [$ subProductId ])
88+ $ processAllChildren = !$ productsFilter || in_array ($ configurableProductId , $ productsFilter );
89+ foreach ($ this -> childrenProducts [ $ configurableProductId ] as $ childrenProductId ) {
90+ if ($ processAllChildren || in_array ($ childrenProductId , $ productsFilter )) {
91+ $ childValidationResult = isset ($ productIds [$ childrenProductId ])
92+ ? array_filter ($ productIds [$ childrenProductId ])
7893 : [];
79- $ productIds [$ subProductId ] = $ parentValidationResult + $ childValidationResult ;
94+ $ productIds [$ childrenProductId ] = $ parentValidationResult + $ childValidationResult ;
8095 }
81-
8296 }
83- unset($ productIds [$ productId ]);
97+ unset($ productIds [$ configurableProductId ]);
8498 }
99+
85100 return $ productIds ;
86101 }
102+
103+ /**
104+ * Check if simple product has previously applied rule.
105+ *
106+ * @param int $productId
107+ * @return bool
108+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
109+ */
110+ private function hasAntecedentRule (int $ productId ): bool
111+ {
112+ foreach ($ this ->childrenProducts as $ parent => $ children ) {
113+ if (in_array ($ productId , $ children )) {
114+ return true ;
115+ }
116+ }
117+
118+ return false ;
119+ }
87120}
0 commit comments