Passed
Push — master ( 0dcd20...e33123 )
by Christian
10:55 queued 10s
created

StorefrontController::decodeParam()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 2
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Controller;
4
5
use Shopware\Core\Checkout\Cart\Cart;
6
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
7
use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
8
use Shopware\Core\Framework\Adapter\Twig\TemplateFinder;
9
use Shopware\Core\Framework\Routing\RequestTransformerInterface;
10
use Shopware\Core\PlatformRequest;
11
use Shopware\Core\System\SalesChannel\SalesChannelContext;
12
use Shopware\Storefront\Event\StorefrontRenderEvent;
13
use Shopware\Storefront\Framework\Routing\RequestTransformer;
14
use Shopware\Storefront\Framework\Routing\Router;
15
use Shopware\Storefront\Framework\Routing\StorefrontResponse;
16
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
21
22
abstract class StorefrontController extends AbstractController
23
{
24
    protected function renderStorefront(string $view, array $parameters = []): Response
25
    {
26
        $request = $this->get('request_stack')->getCurrentRequest();
27
28
        $salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
29
30
        $view = $this->get(TemplateFinder::class)->find($view, false, null);
31
32
        $event = new StorefrontRenderEvent($view, $parameters, $request, $salesChannelContext);
33
        $this->get('event_dispatcher')->dispatch($event);
34
35
        $response = $this->render($view, $event->getParameters(), new StorefrontResponse());
36
37
        if (!$response instanceof StorefrontResponse) {
38
            throw new \RuntimeException('Symfony render implementation changed. Providing a response is no longer supported');
39
        }
40
41
        $host = $request->attributes->get(RequestTransformer::STOREFRONT_URL);
42
43
        /** @var SeoUrlPlaceholderHandlerInterface $seoUrlReplacer */
44
        $seoUrlReplacer = $this->container->get(SeoUrlPlaceholderHandlerInterface::class);
45
        $response->setContent(
46
            $seoUrlReplacer->replace($response->getContent(), $host, $salesChannelContext)
47
        );
48
49
        /* @var StorefrontResponse $response */
50
        $response->setData($parameters);
51
        $response->setContext($salesChannelContext);
52
        $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, '1');
53
        $response->headers->set('Content-Type', 'text/html');
54
55
        return $response;
56
    }
57
58
    protected function trans(string $snippet, array $parameters = []): string
59
    {
60
        return $this->container
61
            ->get('translator')
62
            ->trans($snippet, $parameters);
63
    }
64
65
    protected function createActionResponse(Request $request): Response
66
    {
67
        if ($request->get('redirectTo')) {
68
            $params = $this->decodeParam($request, 'redirectParameters');
69
70
            return $this->redirectToRoute($request->get('redirectTo'), $params);
0 ignored issues
show
Bug introduced by
It seems like $request->get('redirectTo') can also be of type null; however, parameter $route of Symfony\Bundle\Framework...ller::redirectToRoute() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

70
            return $this->redirectToRoute(/** @scrutinizer ignore-type */ $request->get('redirectTo'), $params);
Loading history...
71
        }
72
73
        if ($request->get('forwardTo')) {
74
            $params = $this->decodeParam($request, 'forwardParameters');
75
76
            return $this->forwardToRoute($request->get('forwardTo'), [], $params);
0 ignored issues
show
Bug introduced by
It seems like $request->get('forwardTo') can also be of type null; however, parameter $routeName of Shopware\Storefront\Cont...oller::forwardToRoute() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

76
            return $this->forwardToRoute(/** @scrutinizer ignore-type */ $request->get('forwardTo'), [], $params);
Loading history...
77
        }
78
79
        return new Response();
80
    }
81
82
    protected function forwardToRoute(string $routeName, array $attributes = [], array $routeParameters = []): Response
83
    {
84
        $router = $this->container->get('router');
85
86
        $url = $this->generateUrl($routeName, $routeParameters, Router::PATH_INFO);
87
88
        // for the route matching the request method is set to "GET" because
89
        // this method is not ought to be used as a post passthrough
90
        // rather it shall return templates or redirects to display results of the request ahead
91
        $method = $router->getContext()->getMethod();
92
        $router->getContext()->setMethod(Request::METHOD_GET);
93
94
        $route = $router->match($url);
95
        $router->getContext()->setMethod($method);
96
97
        $request = $this->container->get('request_stack')->getCurrentRequest();
98
99
        $attributes = array_merge(
100
            $this->get(RequestTransformerInterface::class)->extractInheritableAttributes($request),
101
            $route,
102
            $attributes,
103
            ['_route_params' => $routeParameters]
104
        );
105
106
        return $this->forward($route['_controller'], $attributes, $routeParameters);
107
    }
108
109
    /**
110
     * @throws CustomerNotLoggedInException
111
     */
112
    protected function denyAccessUnlessLoggedIn(bool $allowGuest = false): void
113
    {
114
        /** @var RequestStack $requestStack */
115
        $requestStack = $this->get('request_stack');
116
        $request = $requestStack->getCurrentRequest();
117
118
        if (!$request) {
119
            throw new CustomerNotLoggedInException();
120
        }
121
122
        /** @var SalesChannelContext|null $context */
123
        $context = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
124
125
        if (
126
            $context
127
            && $context->getCustomer()
128
            && (
129
                $allowGuest === true
130
                || $context->getCustomer()->getGuest() === false
131
            )
132
        ) {
133
            return;
134
        }
135
136
        throw new CustomerNotLoggedInException();
137
    }
138
139
    protected function decodeParam(Request $request, string $param): array
140
    {
141
        $params = $request->get($param);
142
143
        if (is_string($params)) {
144
            $params = json_decode($params, true);
145
        }
146
147
        if (empty($params)) {
148
            $params = [];
149
        }
150
151
        return $params;
152
    }
153
154
    protected function addCartErrors(Cart $cart): void
155
    {
156
        $groups = [
157
            'info' => $cart->getErrors()->getNotices(),
158
            'warning' => $cart->getErrors()->getWarnings(),
159
            'danger' => $cart->getErrors()->getErrors(),
160
        ];
161
162
        foreach ($groups as $type => $errors) {
163
            foreach ($errors as $error) {
164
                $parameters = [];
165
                foreach ($error->getParameters() as $key => $value) {
166
                    $parameters['%' . $key . '%'] = $value;
167
                }
168
169
                $message = $this->trans('checkout.' . $error->getMessageKey(), $parameters);
170
171
                $this->addFlash($type, $message);
172
            }
173
        }
174
    }
175
}
176