Complex classes like PromotionContext often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PromotionContext, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
36 | final class PromotionContext implements Context |
||
37 | { |
||
38 | /** @var SharedStorageInterface */ |
||
39 | private $sharedStorage; |
||
40 | |||
41 | /** @var PromotionActionFactoryInterface */ |
||
42 | private $actionFactory; |
||
43 | |||
44 | /** @var PromotionCouponFactoryInterface */ |
||
45 | private $couponFactory; |
||
46 | |||
47 | /** @var PromotionRuleFactoryInterface */ |
||
48 | private $ruleFactory; |
||
49 | |||
50 | /** @var TestPromotionFactoryInterface */ |
||
51 | private $testPromotionFactory; |
||
52 | |||
53 | /** @var PromotionRepositoryInterface */ |
||
54 | private $promotionRepository; |
||
55 | |||
56 | /** @var PromotionCouponGeneratorInterface */ |
||
57 | private $couponGenerator; |
||
58 | |||
59 | /** @var ObjectManager */ |
||
60 | private $objectManager; |
||
61 | |||
62 | public function __construct( |
||
81 | |||
82 | /** |
||
83 | * @Given there is (also) a promotion :name |
||
84 | * @Given there is a promotion :name identified by :code code |
||
85 | */ |
||
86 | public function thereIsPromotion(string $name, ?string $code = null): void |
||
90 | |||
91 | /** |
||
92 | * @Given /^there is a promotion "([^"]+)" with "Has at least one from taxons" rule (configured with "[^"]+" and "[^"]+")$/ |
||
93 | */ |
||
94 | public function thereIsAPromotionWithHasAtLeastOneFromTaxonsRuleConfiguredWith(string $name, array $taxons): void |
||
102 | |||
103 | /** |
||
104 | * @Given /^there is a promotion "([^"]+)" with "Total price of items from taxon" rule configured with ("[^"]+" taxon) and (?:€|£|\$)([^"]+) amount for ("[^"]+" channel)$/ |
||
105 | */ |
||
106 | public function thereIsAPromotionWithTotalPriceOfItemsFromTaxonRuleConfiguredWithTaxonAndAmountForChannel( |
||
118 | |||
119 | /** |
||
120 | * @Given /^there is a promotion "([^"]+)" with priority ([^"]+)$/ |
||
121 | */ |
||
122 | public function thereIsAPromotionWithPriority($promotionName, $priority) |
||
133 | |||
134 | /** |
||
135 | * @Given /^there is an exclusive promotion "([^"]+)"(?:| with priority ([^"]+))$/ |
||
136 | */ |
||
137 | public function thereIsAnExclusivePromotionWithPriority($promotionName, $priority = 0) |
||
149 | |||
150 | /** |
||
151 | * @Given there is a promotion :promotionName limited to :usageLimit usages |
||
152 | */ |
||
153 | public function thereIsPromotionLimitedToUsages($promotionName, $usageLimit) |
||
162 | |||
163 | /** |
||
164 | * @Given the store has promotion :promotionName with coupon :couponCode |
||
165 | * @Given the store has a promotion :promotionName with a coupon :couponCode that is limited to :usageLimit usages |
||
166 | */ |
||
167 | public function thereIsPromotionWithCoupon(string $promotionName, string $couponCode, ?int $usageLimit = null): void |
||
182 | |||
183 | /** |
||
184 | * @Given /^(this promotion) has "([^"]+)", "([^"]+)" and "([^"]+)" coupons/ |
||
185 | */ |
||
186 | public function thisPromotionHasCoupons(PromotionInterface $promotion, string ...$couponCodes): void |
||
197 | |||
198 | /** |
||
199 | * @Given /^(this promotion) has already expired$/ |
||
200 | */ |
||
201 | public function thisPromotionHasExpired(PromotionInterface $promotion) |
||
207 | |||
208 | /** |
||
209 | * @Given /^(this promotion) expires tomorrow$/ |
||
210 | */ |
||
211 | public function thisPromotionExpiresTomorrow(PromotionInterface $promotion) |
||
217 | |||
218 | /** |
||
219 | * @Given /^(this promotion) has started yesterday$/ |
||
220 | */ |
||
221 | public function thisPromotionHasStartedYesterday(PromotionInterface $promotion) |
||
227 | |||
228 | /** |
||
229 | * @Given /^(this promotion) starts tomorrow$/ |
||
230 | */ |
||
231 | public function thisPromotionStartsTomorrow(PromotionInterface $promotion) |
||
237 | |||
238 | /** |
||
239 | * @Given /^(this coupon) has already expired$/ |
||
240 | */ |
||
241 | public function thisCouponHasExpired(PromotionCouponInterface $coupon) |
||
247 | |||
248 | /** |
||
249 | * @Given /^(this coupon) expires tomorrow$/ |
||
250 | */ |
||
251 | public function thisCouponExpiresTomorrow(PromotionCouponInterface $coupon) |
||
257 | |||
258 | /** |
||
259 | * @Given /^(this coupon) is set as non reusable after cancelling the order in which it has been used$/ |
||
260 | */ |
||
261 | public function thisIsSetAsNonReusableAfterCancellingTheOrderInWhichItHasBeenUsed(PromotionCouponInterface $coupon): void |
||
267 | |||
268 | /** |
||
269 | * @Given /^(this coupon) has already reached its usage limit$/ |
||
270 | */ |
||
271 | public function thisCouponHasReachedItsUsageLimit(PromotionCouponInterface $coupon) |
||
278 | |||
279 | /** |
||
280 | * @Given /^(this coupon) can be used (\d+) times?$/ |
||
281 | * @Given /^(this coupon) can be used once$/ |
||
282 | */ |
||
283 | public function thisCouponCanBeUsedNTimes(PromotionCouponInterface $coupon, int $usageLimit = 1): void |
||
289 | |||
290 | /** |
||
291 | * @Given /^(this coupon) can be used once per customer$/ |
||
292 | */ |
||
293 | public function thisCouponCanBeUsedOncePerCustomer(PromotionCouponInterface $coupon): void |
||
299 | |||
300 | /** |
||
301 | * @Given /^(this coupon) can be used twice per customer$/ |
||
302 | */ |
||
303 | public function thisCouponCanBeUsedTwicePerCustomer(PromotionCouponInterface $coupon): void |
||
309 | |||
310 | /** |
||
311 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order$/ |
||
312 | */ |
||
313 | public function itGivesFixedDiscountToEveryOrder(PromotionInterface $promotion, $discount) |
||
317 | |||
318 | /** |
||
319 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel) and ("(?:€|£|\$)[^"]+") discount to every order in the ("[^"]+" channel)$/ |
||
320 | */ |
||
321 | public function thisPromotionGivesDiscountToEveryOrderInTheChannelAndDiscountToEveryOrderInTheChannel( |
||
338 | |||
339 | /** |
||
340 | * @Given /^([^"]+) gives ("[^"]+%") discount to every order$/ |
||
341 | */ |
||
342 | public function itGivesPercentageDiscountToEveryOrder(PromotionInterface $promotion, $discount) |
||
346 | |||
347 | /** |
||
348 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with quantity at least ([^"]+)$/ |
||
349 | */ |
||
350 | public function itGivesFixedDiscountToEveryOrderWithQuantityAtLeast( |
||
359 | |||
360 | /** |
||
361 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") discount to every order with items total at least ("[^"]+")$/ |
||
362 | */ |
||
363 | public function itGivesFixedDiscountToEveryOrderWithItemsTotalAtLeast( |
||
373 | |||
374 | /** |
||
375 | * @Given /^([^"]+) gives ("[^"]+%") discount to every order with items total at least ("[^"]+")$/ |
||
376 | */ |
||
377 | public function itGivesPercentageDiscountToEveryOrderWithItemsTotalAtLeast( |
||
386 | |||
387 | /** |
||
388 | * @Given /^([^"]+) gives ("[^"]+%") off on every product when the item total is at least ("(?:€|£|\$)[^"]+")$/ |
||
389 | */ |
||
390 | public function itGivesOffOnEveryItemWhenItemTotalExceeds( |
||
400 | |||
401 | /** |
||
402 | * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order$/ |
||
403 | */ |
||
404 | public function itGivesPercentageDiscountOnShippingToEveryOrder(PromotionInterface $promotion, $discount) |
||
411 | |||
412 | /** |
||
413 | * @Given /^([^"]+) gives free shipping to every order$/ |
||
414 | */ |
||
415 | public function thePromotionGivesFreeShippingToEveryOrder(PromotionInterface $promotion) |
||
419 | |||
420 | /** |
||
421 | * @Given /^([^"]+) gives(?:| another) ("[^"]+%") off every product (classified as "[^"]+")$/ |
||
422 | */ |
||
423 | public function itGivesPercentageOffEveryProductClassifiedAs( |
||
430 | |||
431 | /** |
||
432 | * @Given /^([^"]+) gives(?:| another) ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+")$/ |
||
433 | */ |
||
434 | public function itGivesFixedOffEveryProductClassifiedAs( |
||
441 | |||
442 | /** |
||
443 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/ |
||
444 | */ |
||
445 | public function thisPromotionGivesOffOnEveryProductWithMinimumPriceAt( |
||
452 | |||
453 | /** |
||
454 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/ |
||
455 | */ |
||
456 | public function thisPromotionGivesOffOnEveryProductPricedBetween( |
||
468 | |||
469 | /** |
||
470 | * @Given /^([^"]+) gives ("[^"]+%") off on every product with minimum price at ("(?:€|£|\$)[^"]+")$/ |
||
471 | */ |
||
472 | public function thisPromotionPercentageGivesOffOnEveryProductWithMinimumPriceAt( |
||
479 | |||
480 | /** |
||
481 | * @Given /^([^"]+) gives ("[^"]+%") off on every product priced between ("(?:€|£|\$)[^"]+") and ("(?:€|£|\$)[^"]+")$/ |
||
482 | */ |
||
483 | public function thisPromotionPercentageGivesOffOnEveryProductPricedBetween( |
||
495 | |||
496 | /** |
||
497 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+")$/ |
||
498 | */ |
||
499 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAs( |
||
508 | |||
509 | /** |
||
510 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+" or "[^"]+")$/ |
||
511 | */ |
||
512 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsOr( |
||
521 | |||
522 | /** |
||
523 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains products (classified as "[^"]+") with a minimum value of ("(?:€|£|\$)[^"]+")$/ |
||
524 | */ |
||
525 | public function thePromotionGivesOffIfOrderContainsProductsClassifiedAsAndPricedAt( |
||
536 | |||
537 | /** |
||
538 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off customer's (\d)(?:st|nd|rd|th) order$/ |
||
539 | */ |
||
540 | public function itGivesFixedOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth) |
||
546 | |||
547 | /** |
||
548 | * @Given /^([^"]+) gives ("[^"]+%") off on the customer's (\d)(?:st|nd|rd|th) order$/ |
||
549 | */ |
||
550 | public function itGivesPercentageOffCustomersNthOrder(PromotionInterface $promotion, $discount, $nth) |
||
556 | |||
557 | /** |
||
558 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and ("(?:€|£|\$)[^"]+") discount on every order$/ |
||
559 | */ |
||
560 | public function itGivesPercentageOffOnEveryProductClassifiedAsAndAmountDiscountOnOrder( |
||
569 | |||
570 | /** |
||
571 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on every product (classified as "[^"]+") and a free shipping to every order with items total equal at least ("[^"]+")$/ |
||
572 | */ |
||
573 | public function itGivesOffOnEveryProductClassifiedAsAndAFreeShippingToEveryOrderWithItemsTotalEqualAtLeast( |
||
587 | |||
588 | /** |
||
589 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") and a ("(?:€|£|\$)[^"]+") discount to every order with items total equal at least ("(?:€|£|\$)[^"]+")$/ |
||
590 | */ |
||
591 | public function itGivesOffOnEveryProductClassifiedAsAndAFixedDiscountToEveryOrderWithItemsTotalEqualAtLeast( |
||
611 | |||
612 | /** |
||
613 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+" or "[^"]+") if order contains any product (classified as "[^"]+" or "[^"]+")$/ |
||
614 | */ |
||
615 | public function itGivesOffOnEveryProductClassifiedAsOrIfOrderContainsAnyProductClassifiedAsOr( |
||
633 | |||
634 | /** |
||
635 | * @Given /^([^"]+) gives ("[^"]+%") off on every product (classified as "[^"]+") if order contains any product (classified as "[^"]+")$/ |
||
636 | */ |
||
637 | public function itGivesOffOnEveryProductClassifiedAsIfOrderContainsAnyProductClassifiedAs( |
||
652 | |||
653 | /** |
||
654 | * @Given /^(it) is coupon based promotion$/ |
||
655 | * @Given /^(it) is a coupon based promotion$/ |
||
656 | */ |
||
657 | public function itIsCouponBasedPromotion(PromotionInterface $promotion): void |
||
663 | |||
664 | /** |
||
665 | * @Given /^(the promotion) was disabled for the (channel "[^"]+")$/ |
||
666 | */ |
||
667 | public function thePromotionWasDisabledForTheChannel(PromotionInterface $promotion, ChannelInterface $channel) |
||
673 | |||
674 | /** |
||
675 | * @Given /^the (coupon "[^"]+") was used up to its usage limit$/ |
||
676 | */ |
||
677 | public function theCouponWasUsed(PromotionCouponInterface $coupon) |
||
683 | |||
684 | /** |
||
685 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off if order contains (?:a|an) ("[^"]+" product)$/ |
||
686 | */ |
||
687 | public function thePromotionGivesOffIfOrderContainsProducts(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
693 | |||
694 | /** |
||
695 | * @Given /^([^"]+) gives ("(?:€|£|\$)[^"]+") off on a ("[^"]*" product)$/ |
||
696 | */ |
||
697 | public function itGivesFixedDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
701 | |||
702 | /** |
||
703 | * @Given /^([^"]+) gives ("[^"]+%") off on a ("[^"]*" product)$/ |
||
704 | */ |
||
705 | public function itGivesPercentageDiscountOffOnAProduct(PromotionInterface $promotion, $discount, ProductInterface $product) |
||
709 | |||
710 | /** |
||
711 | * @Given /^([^"]+) gives ("[^"]+%") off the order for customers from ("[^"]*" group)$/ |
||
712 | */ |
||
713 | public function thePromotionGivesOffTheOrderForCustomersFromGroup( |
||
725 | |||
726 | /** |
||
727 | * @Given /^([^"]+) gives ("[^"]+%") discount on shipping to every order over ("(?:€|£|\$)[^"]+")$/ |
||
728 | */ |
||
729 | public function itGivesDiscountOnShippingToEveryOrderOver( |
||
740 | |||
741 | /** |
||
742 | * @Given /^([^"]+) gives free shipping to every order over ("(?:€|£|\$)[^"]+")$/ |
||
743 | */ |
||
744 | public function itGivesFreeShippingToEveryOrderOver(PromotionInterface $promotion, $itemTotal) |
||
748 | |||
749 | /** |
||
750 | * @Given /^I have generated (\d+) coupons for (this promotion) with code length (\d+) and prefix "([^"]+)"$/ |
||
751 | * @Given /^I have generated (\d+) coupons for (this promotion) with code length (\d+), prefix "([^"]+)" and suffix "([^"]+)"$/ |
||
752 | */ |
||
753 | public function iHaveGeneratedCouponsForThisPromotionWithCodeLengthPrefixAndSuffix( |
||
762 | |||
763 | /** |
||
764 | * @Given /^I have generated (\d+) coupons for (this promotion) with code length (\d+) and suffix "([^"]+)"$/ |
||
765 | */ |
||
766 | public function iHaveGeneratedCouponsForThisPromotionWithCodeLengthAndSuffix( |
||
774 | |||
775 | /** |
||
776 | * @return array |
||
|
|||
777 | */ |
||
778 | private function getTaxonFilterConfiguration(array $taxonCodes) |
||
782 | |||
783 | /** |
||
784 | * @return array |
||
785 | */ |
||
786 | private function getProductsFilterConfiguration(array $productCodes) |
||
790 | |||
791 | /** |
||
792 | * @param int $minAmount |
||
793 | * @param int $maxAmount |
||
794 | * |
||
795 | * @return array |
||
796 | */ |
||
797 | private function getPriceRangeFilterConfiguration($minAmount, $maxAmount = null) |
||
806 | |||
807 | private function createPromotion(string $name, ?string $code = null): PromotionInterface |
||
820 | |||
821 | /** |
||
822 | * @param int $discount |
||
823 | */ |
||
824 | private function createUnitFixedPromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null) |
||
835 | |||
836 | /** |
||
837 | * @param int $discount |
||
838 | */ |
||
839 | private function createUnitPercentagePromotion(PromotionInterface $promotion, $discount, array $configuration = [], PromotionRuleInterface $rule = null) |
||
850 | |||
851 | /** |
||
852 | * @param int $discount |
||
853 | */ |
||
854 | private function createFixedPromotion( |
||
865 | |||
866 | /** |
||
867 | * @param float $discount |
||
868 | * @param PromotionRuleInterface $rule |
||
869 | */ |
||
870 | private function createPercentagePromotion( |
||
878 | |||
879 | private function persistPromotion(PromotionInterface $promotion, PromotionActionInterface $action, array $configuration, PromotionRuleInterface $rule = null) |
||
891 | |||
892 | private function createCoupon(string $couponCode, ?int $usageLimit = null): PromotionCouponInterface |
||
901 | |||
902 | private function generateCoupons( |
||
917 | } |
||
918 |
This check looks for the generic type
array
as a return type and suggests a more specific type. This type is inferred from the actual code.