Passed
Push — master ( 7a2782...032b3c )
by Christian
11:03
created

ContextSwitchRoute::switchContext()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 72
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 47
nc 6
nop 2
dl 0
loc 72
rs 8.5341
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\System\SalesChannel\SalesChannel;
4
5
use OpenApi\Annotations as OA;
6
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
7
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
8
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
9
use Shopware\Core\Framework\DataAbstractionLayer\Validation\EntityExists;
10
use Shopware\Core\Framework\Feature;
11
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
12
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
13
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
14
use Shopware\Core\Framework\Validation\DataValidationDefinition;
15
use Shopware\Core\Framework\Validation\DataValidator;
16
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextPersister;
17
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
18
use Shopware\Core\System\SalesChannel\ContextTokenResponse;
19
use Shopware\Core\System\SalesChannel\Event\SalesChannelContextSwitchEvent;
20
use Shopware\Core\System\SalesChannel\SalesChannelContext;
21
use Symfony\Component\Routing\Annotation\Route;
22
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
23
24
/**
25
 * @RouteScope(scopes={"store-api"})
26
 */
27
class ContextSwitchRoute extends AbstractContextSwitchRoute
28
{
29
    private const SHIPPING_METHOD_ID = SalesChannelContextService::SHIPPING_METHOD_ID;
30
    private const PAYMENT_METHOD_ID = SalesChannelContextService::PAYMENT_METHOD_ID;
31
    private const BILLING_ADDRESS_ID = SalesChannelContextService::BILLING_ADDRESS_ID;
32
    private const SHIPPING_ADDRESS_ID = SalesChannelContextService::SHIPPING_ADDRESS_ID;
33
    private const COUNTRY_ID = SalesChannelContextService::COUNTRY_ID;
34
    private const STATE_ID = SalesChannelContextService::COUNTRY_STATE_ID;
35
    private const CURRENCY_ID = SalesChannelContextService::CURRENCY_ID;
36
    private const LANGUAGE_ID = SalesChannelContextService::LANGUAGE_ID;
37
38
    /**
39
     * @var SalesChannelContextPersister
40
     */
41
    protected $contextPersister;
42
43
    /**
44
     * @var DataValidator
45
     */
46
    protected $validator;
47
48
    /**
49
     * @var EventDispatcherInterface
50
     */
51
    private $eventDispatcher;
52
53
    public function __construct(
54
        DataValidator $validator,
55
        SalesChannelContextPersister $contextPersister,
56
        EventDispatcherInterface $eventDispatcher
57
    ) {
58
        $this->contextPersister = $contextPersister;
59
        $this->validator = $validator;
60
        $this->eventDispatcher = $eventDispatcher;
61
    }
62
63
    public function getDecorated(): AbstractContextSwitchRoute
64
    {
65
        throw new DecorationPatternException(self::class);
66
    }
67
68
    /**
69
     * @OA\Patch(
70
     *      path="/context",
71
     *      description="Update the context",
72
     *      operationId="updateContext",
73
     *      tags={"Store API","Context"},
74
     *      @OA\Parameter(name="currencyId", description="Currency", @OA\Schema(type="string")),
75
     *      @OA\Parameter(name="languageId", description="Language", @OA\Schema(type="string")),
76
     *      @OA\Parameter(name="billingAddressId", description="Billing Address", @OA\Schema(type="string")),
77
     *      @OA\Parameter(name="shippingAddressId", description="Shipping Address", @OA\Schema(type="string")),
78
     *      @OA\Parameter(name="paymentMethodId", description="Payment Method", @OA\Schema(type="string")),
79
     *      @OA\Parameter(name="shippingMethodId", description="Shipping Method", @OA\Schema(type="string")),
80
     *      @OA\Parameter(name="countryId", description="Country", @OA\Schema(type="string")),
81
     *      @OA\Parameter(name="countryStateId", description="Country State", @OA\Schema(type="string")),
82
     *      @OA\Response(
83
     *          response="200",
84
     *          description="Context",
85
     *          @OA\JsonContent(ref="#/definitions/ContextTokenResponse")
86
     *     )
87
     * )
88
     * @Route("/store-api/v{version}/context", name="store-api.switch-context", methods={"PATCH"})
89
     */
90
    public function switchContext(RequestDataBag $data, SalesChannelContext $context): ContextTokenResponse
91
    {
92
        $definition = new DataValidationDefinition('context_switch');
93
94
        $parameters = $data->only(
95
            self::SHIPPING_METHOD_ID,
96
            self::PAYMENT_METHOD_ID,
97
            self::BILLING_ADDRESS_ID,
98
            self::SHIPPING_ADDRESS_ID,
99
            self::COUNTRY_ID,
100
            self::STATE_ID,
101
            self::CURRENCY_ID,
102
            self::LANGUAGE_ID
103
        );
104
105
        $addressCriteria = new Criteria();
106
        if ($context->getCustomer()) {
107
            $addressCriteria->addFilter(new EqualsFilter('customer_address.customerId', $context->getCustomer()->getId()));
108
        } else {
109
            // do not allow to set address ids if the customer is not logged in
110
            if (isset($parameters[self::SHIPPING_ADDRESS_ID])) {
111
                throw new CustomerNotLoggedInException();
112
            }
113
114
            if (isset($parameters[self::BILLING_ADDRESS_ID])) {
115
                throw new CustomerNotLoggedInException();
116
            }
117
        }
118
119
        $currencyCriteria = new Criteria();
120
        $currencyCriteria->addFilter(
121
            new EqualsFilter('currency.salesChannels.id', $context->getSalesChannel()->getId())
122
        );
123
124
        $languageCriteria = new Criteria();
125
        $languageCriteria->addFilter(
126
            new EqualsFilter('language.salesChannels.id', $context->getSalesChannel()->getId())
127
        );
128
129
        $paymentMethodCriteria = new Criteria();
130
        $paymentMethodCriteria->addFilter(
131
            new EqualsFilter('payment_method.salesChannels.id', $context->getSalesChannel()->getId())
132
        );
133
134
        $shippingMethodCriteria = new Criteria();
135
        $shippingMethodCriteria->addFilter(
136
            new EqualsFilter('shipping_method.salesChannels.id', $context->getSalesChannel()->getId())
137
        );
138
139
        $definition
140
            ->add(self::LANGUAGE_ID, new EntityExists(['entity' => 'language', 'context' => $context->getContext(), 'criteria' => $languageCriteria]))
141
            ->add(self::CURRENCY_ID, new EntityExists(['entity' => 'currency', 'context' => $context->getContext(), 'criteria' => $currencyCriteria]))
142
            ->add(self::SHIPPING_METHOD_ID, new EntityExists(['entity' => 'shipping_method', 'context' => $context->getContext(), 'criteria' => $shippingMethodCriteria]))
143
            ->add(self::PAYMENT_METHOD_ID, new EntityExists(['entity' => 'payment_method', 'context' => $context->getContext(), 'criteria' => $paymentMethodCriteria]))
144
            ->add(self::BILLING_ADDRESS_ID, new EntityExists(['entity' => 'customer_address', 'context' => $context->getContext(), 'criteria' => $addressCriteria]))
145
            ->add(self::SHIPPING_ADDRESS_ID, new EntityExists(['entity' => 'customer_address', 'context' => $context->getContext(), 'criteria' => $addressCriteria]))
146
            ->add(self::COUNTRY_ID, new EntityExists(['entity' => 'country', 'context' => $context->getContext()]))
147
            ->add(self::STATE_ID, new EntityExists(['entity' => 'country_state', 'context' => $context->getContext()]))
148
        ;
149
150
        $this->validator->validate($parameters, $definition);
151
152
        if (Feature::isActive('FEATURE_NEXT_10058') && $customer = $context->getCustomer()) {
153
            $this->contextPersister->save($context->getToken(), $parameters, $customer->getId());
154
        } else {
155
            $this->contextPersister->save($context->getToken(), $parameters);
156
        }
157
158
        $event = new SalesChannelContextSwitchEvent($context, $data);
159
        $this->eventDispatcher->dispatch($event);
160
161
        return new ContextTokenResponse($context->getToken());
162
    }
163
}
164