shouldProductsPositionsBeUpdated()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Odiseo\SyliusVendorPlugin\Controller;
6
7
use Odiseo\SyliusVendorPlugin\Entity\VendorInterface;
8
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
9
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
10
use Sylius\Component\Resource\ResourceActions;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\HttpFoundation\Session\Session;
14
use Symfony\Component\HttpKernel\Exception\HttpException;
15
use Webmozart\Assert\Assert;
16
17
class VendorController extends ResourceController
18
{
19
    /**
20
     * @param Request $request
21
     * @return Response
22
     */
23
    public function updateVendorPositionsAction(Request $request): Response
24
    {
25
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
26
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
27
        $vendors = $request->get('vendors');
28
29
        $this->validateCsrfProtection($request, $configuration);
30
31
        if ($this->shouldProductsPositionsBeUpdated($request, $vendors)) {
32
            /** @var Session $session */
33
            $session = $request->getSession();
34
35
            /**
36
             * @var int $id
37
             * @var string $position
38
             */
39
            foreach ($vendors as $id => $position) {
40
                try {
41
                    $this->updatePositions($position, $id);
42
                } catch (\InvalidArgumentException $exception) {
43
                    $session->getFlashBag()->add('error', $exception->getMessage());
44
45
                    return $this->redirectHandler->redirectToReferer($configuration);
46
                }
47
            }
48
49
            $this->manager->flush();
50
        }
51
52
        return $this->redirectHandler->redirectToReferer($configuration);
53
    }
54
55
    /**
56
     * @param Request $request
57
     * @param RequestConfiguration $configuration
58
     */
59
    private function validateCsrfProtection(Request $request, RequestConfiguration $configuration): void
60
    {
61
        /** @var string|null $token */
62
        $token = $request->request->get('_csrf_token');
63
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid('update-vendor-position', $token)) {
64
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
65
        }
66
    }
67
68
    /**
69
     * @param Request $request
70
     * @param array|null $vendors
71
     * @return bool
72
     */
73
    private function shouldProductsPositionsBeUpdated(Request $request, ?array $vendors): bool
74
    {
75
        return in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && null !== $vendors;
76
    }
77
78
    /**
79
     * @param string $position
80
     * @param int $id
81
     */
82
    private function updatePositions(string $position, int $id): void
83
    {
84
        Assert::numeric($position, sprintf('The position "%s" is invalid.', $position));
85
86
        /** @var VendorInterface $vendorFromBase */
87
        $vendorFromBase = $this->repository->findOneBy(['id' => $id]);
88
        $vendorFromBase->setPosition((int) $position);
89
    }
90
}
91