Passed
Push — master ( 459710...c9812f )
by Christian
18:02 queued 07:04
created

validateBillingAddress()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 3
dl 0
loc 17
ccs 0
cts 0
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Page\Checkout\Confirm;
4
5
use Shopware\Core\Checkout\Cart\Address\Error\AddressValidationError;
6
use Shopware\Core\Checkout\Cart\Cart;
7
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
8
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
9
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
10
use Shopware\Core\Checkout\Payment\PaymentMethodCollection;
11
use Shopware\Core\Checkout\Payment\SalesChannel\AbstractPaymentMethodRoute;
12
use Shopware\Core\Checkout\Shipping\SalesChannel\AbstractShippingMethodRoute;
13
use Shopware\Core\Checkout\Shipping\ShippingMethodCollection;
14
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
15
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
16
use Shopware\Core\Framework\Validation\BuildValidationEvent;
17
use Shopware\Core\Framework\Validation\DataValidationFactoryInterface;
18
use Shopware\Core\Framework\Validation\DataValidator;
19
use Shopware\Core\System\SalesChannel\SalesChannelContext;
20
use Shopware\Storefront\Page\GenericPageLoaderInterface;
21
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22
use Symfony\Component\HttpFoundation\Request;
23
24
class CheckoutConfirmPageLoader
25
{
26
    /**
27
     * @var EventDispatcherInterface
28
     */
29
    private $eventDispatcher;
30
31
    /**
32
     * @var CartService
33
     */
34
    private $cartService;
35
36
    /**
37
     * @var AbstractShippingMethodRoute
38
     */
39
    private $shippingMethodRoute;
40
41
    /**
42
     * @var AbstractPaymentMethodRoute
43
     */
44
    private $paymentMethodRoute;
45
46
    /**
47
     * @var GenericPageLoaderInterface
48
     */
49
    private $genericPageLoader;
50
51
    /**
52
     * @var DataValidationFactoryInterface
53
     */
54
    private $addressValidationFactory;
55
56
    /**
57
     * @var DataValidator
58
     */
59
    private $validator;
60
61
    public function __construct(
62
        EventDispatcherInterface $eventDispatcher,
63
        CartService $cartService,
64
        AbstractShippingMethodRoute $shippingMethodRoute,
65
        AbstractPaymentMethodRoute $paymentMethodRoute,
66
        GenericPageLoaderInterface $genericPageLoader,
67
        DataValidationFactoryInterface $addressValidationFactory,
68
        DataValidator $validator
69
    ) {
70
        $this->eventDispatcher = $eventDispatcher;
71
        $this->cartService = $cartService;
72
        $this->shippingMethodRoute = $shippingMethodRoute;
73
        $this->paymentMethodRoute = $paymentMethodRoute;
74
        $this->genericPageLoader = $genericPageLoader;
75
        $this->addressValidationFactory = $addressValidationFactory;
76
        $this->validator = $validator;
77
    }
78
79
    /**
80
     * @throws CustomerNotLoggedInException
81
     * @throws InconsistentCriteriaIdsException
82
     */
83
    public function load(Request $request, SalesChannelContext $context): CheckoutConfirmPage
84
    {
85
        $page = $this->genericPageLoader->load($request, $context);
86
        $page = CheckoutConfirmPage::createFrom($page);
87
88
        if ($page->getMetaInformation()) {
89
            $page->getMetaInformation()->setRobots('noindex,follow');
90
        }
91
92
        $page->setPaymentMethods($this->getPaymentMethods($context));
93
        $page->setShippingMethods($this->getShippingMethods($context));
94
95
        $cart = $this->cartService->getCart($context->getToken(), $context);
96
        $this->validateCustomerAddresses($cart, $context);
97
        $page->setCart($cart);
98
99
        $this->eventDispatcher->dispatch(
100
            new CheckoutConfirmPageLoadedEvent($page, $context, $request)
101
        );
102
103
        return $page;
104
    }
105
106
    private function getPaymentMethods(SalesChannelContext $context): PaymentMethodCollection
107
    {
108
        $request = new Request();
109
        $request->query->set('onlyAvailable', true);
110
111
        return $this->paymentMethodRoute->load($request, $context)->getPaymentMethods();
112
    }
113
114
    private function getShippingMethods(SalesChannelContext $context): ShippingMethodCollection
115
    {
116
        $request = new Request();
117
        $request->query->set('onlyAvailable', true);
118
119
        return $this->shippingMethodRoute
0 ignored issues
show
Deprecated Code introduced by
The function Shopware\Core\Checkout\S...pingMethodRoute::load() has been deprecated: tag:v6.4.0 - Parameter $criteria will be mandatory in future implementation ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

119
        return /** @scrutinizer ignore-deprecated */ $this->shippingMethodRoute

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
120
            ->load($request, $context, new Criteria())
0 ignored issues
show
Unused Code introduced by
The call to Shopware\Core\Checkout\S...pingMethodRoute::load() has too many arguments starting with new Shopware\Core\Framew...Layer\Search\Criteria(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
            ->/** @scrutinizer ignore-call */ load($request, $context, new Criteria())

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
121
            ->getShippingMethods();
122
    }
123
124
    /**
125
     * @throws CustomerNotLoggedInException
126
     */
127
    private function validateCustomerAddresses(Cart $cart, SalesChannelContext $context): void
128
    {
129
        $customer = $context->getCustomer();
130
        if ($customer === null) {
131
            throw new CustomerNotLoggedInException();
132
        }
133
134
        $billingAddress = $customer->getActiveBillingAddress();
135
        $shippingAddress = $customer->getActiveShippingAddress();
136
137
        $this->validateBillingAddress($billingAddress, $cart, $context);
138
        $this->validateShippingAddress($shippingAddress, $billingAddress, $cart, $context);
139
    }
140
141
    private function validateBillingAddress(
142
        ?CustomerAddressEntity $billingAddress,
143
        Cart $cart,
144
        SalesChannelContext $context
145
    ): void {
146
        $validation = $this->addressValidationFactory->create($context);
147
        $validationEvent = new BuildValidationEvent($validation, $context->getContext());
148
        $this->eventDispatcher->dispatch($validationEvent);
149
150
        if ($billingAddress === null) {
151
            return;
152
        }
153
154
        $violations = $this->validator->getViolations($billingAddress->jsonSerialize(), $validation);
155
156
        if ($violations->count() > 0) {
157
            $cart->getErrors()->add(new AddressValidationError(true, $violations));
158
        }
159
    }
160
161
    private function validateShippingAddress(
162
        ?CustomerAddressEntity $shippingAddress,
163
        ?CustomerAddressEntity $billingAddress,
164
        Cart $cart,
165
        SalesChannelContext $context
166
    ): void {
167
        $validation = $this->addressValidationFactory->create($context);
168
        $validationEvent = new BuildValidationEvent($validation, $context->getContext());
169
        $this->eventDispatcher->dispatch($validationEvent);
170
171
        if ($shippingAddress === null) {
172
            return;
173
        }
174
175
        if ($billingAddress !== null && $shippingAddress->getId() === $billingAddress->getId()) {
176
            return;
177
        }
178
179
        $violations = $this->validator->getViolations($shippingAddress->jsonSerialize(), $validation);
180
        if ($violations->count() > 0) {
181
            $cart->getErrors()->add(new AddressValidationError(false, $violations));
182
        }
183
    }
184
}
185