1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Sylius\ShopApiPlugin\Handler; |
6
|
|
|
|
7
|
|
|
use Doctrine\Common\Collections\Collection; |
8
|
|
|
use SM\Factory\FactoryInterface; |
9
|
|
|
use Sylius\Component\Core\Model\OrderInterface; |
10
|
|
|
use Sylius\Component\Core\Model\PaymentMethodInterface; |
11
|
|
|
use Sylius\Component\Core\OrderCheckoutTransitions; |
12
|
|
|
use Sylius\Component\Core\Repository\OrderRepositoryInterface; |
13
|
|
|
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface; |
14
|
|
|
use Sylius\Component\Payment\Resolver\PaymentMethodsResolverInterface; |
15
|
|
|
use Sylius\ShopApiPlugin\Command\ChoosePaymentMethod; |
16
|
|
|
use Webmozart\Assert\Assert; |
17
|
|
|
|
18
|
|
|
final class ChoosePaymentMethodHandler |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* @var OrderRepositoryInterface |
22
|
|
|
*/ |
23
|
|
|
private $orderRepository; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var PaymentMethodRepositoryInterface |
27
|
|
|
*/ |
28
|
|
|
private $paymentMethodRepository; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var FactoryInterface |
32
|
|
|
*/ |
33
|
|
|
private $stateMachineFactory; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var PaymentMethodsResolverInterface |
37
|
|
|
*/ |
38
|
|
|
private $paymentMethodResolver; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @param OrderRepositoryInterface $orderRepository |
42
|
|
|
* @param PaymentMethodRepositoryInterface $paymentMethodRepository |
43
|
|
|
* @param PaymentMethodsResolverInterface $paymentMethodResolver |
44
|
|
|
* @param FactoryInterface $stateMachineFactory |
45
|
|
|
*/ |
46
|
|
|
public function __construct( |
47
|
|
|
OrderRepositoryInterface $orderRepository, |
48
|
|
|
PaymentMethodRepositoryInterface $paymentMethodRepository, |
49
|
|
|
PaymentMethodsResolverInterface $paymentMethodResolver, |
50
|
|
|
FactoryInterface $stateMachineFactory |
51
|
|
|
) { |
52
|
|
|
$this->orderRepository = $orderRepository; |
53
|
|
|
$this->paymentMethodRepository = $paymentMethodRepository; |
54
|
|
|
$this->stateMachineFactory = $stateMachineFactory; |
55
|
|
|
$this->paymentMethodResolver = $paymentMethodResolver; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @param ChoosePaymentMethod $choosePaymentMethod |
60
|
|
|
*/ |
61
|
|
|
public function handle(ChoosePaymentMethod $choosePaymentMethod) |
62
|
|
|
{ |
63
|
|
|
/** @var OrderInterface $cart */ |
64
|
|
|
$cart = $this->orderRepository->findOneBy(['tokenValue' => $choosePaymentMethod->orderToken()]); |
65
|
|
|
|
66
|
|
|
Assert::notNull($cart, 'Cart has not been found.'); |
67
|
|
|
|
68
|
|
|
$stateMachine = $this->stateMachineFactory->get($cart, OrderCheckoutTransitions::GRAPH); |
69
|
|
|
|
70
|
|
|
Assert::true($stateMachine->can(OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT), 'Order cannot have payment method assigned.'); |
71
|
|
|
|
72
|
|
|
/** @var PaymentMethodInterface $paymentMethod */ |
73
|
|
|
$paymentMethod = $this->paymentMethodRepository->findOneBy(['code' => $choosePaymentMethod->paymentMethod()]); |
74
|
|
|
|
75
|
|
|
Assert::notNull($paymentMethod, 'Payment method has not been found'); |
76
|
|
|
|
77
|
|
|
$paymentsAvailable = $this->getPaymentsAvailable($cart->getPayments()); |
|
|
|
|
78
|
|
|
|
79
|
|
|
Assert::true(isset($paymentsAvailable[$choosePaymentMethod->paymentIdentifier()]), 'Can not find payment with given identifier.'); |
80
|
|
|
|
81
|
|
|
$payment = $paymentsAvailable[$choosePaymentMethod->paymentIdentifier()]; |
82
|
|
|
|
83
|
|
|
$payment->setMethod($paymentMethod); |
84
|
|
|
$stateMachine->apply(OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param Collection $payments |
89
|
|
|
* |
90
|
|
|
* @return array |
91
|
|
|
*/ |
92
|
|
|
private function getPaymentsAvailable(Collection $payments): array |
93
|
|
|
{ |
94
|
|
|
$paymentsAvailable = []; |
95
|
|
|
foreach ($payments as $payment) { |
96
|
|
|
/** @var PaymentMethodInterface $paymentMethod */ |
97
|
|
|
foreach ($this->paymentMethodResolver->getSupportedMethods($payment) as $paymentMethod) { |
98
|
|
|
$paymentsAvailable[$paymentMethod->getCode()] = $payment; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
return $paymentsAvailable; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.