Completed
Push — master ( 126d02...18882d )
by Aske
15s queued 11s
created

RequestViewHelper::initializeArguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
namespace MOC\NotFound\ViewHelpers;
3
4
use Neos\Flow\Annotations as Flow;
5
use Neos\Flow\Configuration\ConfigurationManager;
6
use Neos\Flow\Core\Bootstrap;
7
use Neos\Flow\Http\Request;
8
use Neos\Flow\Http\RequestHandler;
9
use Neos\Flow\Http\Response;
10
use Neos\Flow\Http\Uri;
11
use Neos\Flow\Mvc\ActionRequest;
12
use Neos\Flow\Mvc\Dispatcher;
13
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
14
use Neos\Flow\Mvc\Routing\Dto\RouteContext;
15
use Neos\Flow\Mvc\Routing\Dto\RouteParameters;
16
use Neos\Flow\Mvc\Routing\Router;
17
use Neos\Flow\Security\Context as SecurityContext;
18
use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;
19
use Neos\Neos\Domain\Service\ContentDimensionPresetSourceInterface;
20
use Neos\Neos\Routing\FrontendNodeRoutePartHandler;
21
22
/**
23
 * Loads the content of a given URL
24
 */
25
class RequestViewHelper extends AbstractViewHelper
26
{
27
    /**
28
     * @Flow\Inject
29
     * @var Dispatcher
30
     */
31
    protected $dispatcher;
32
33
    /**
34
     * @Flow\Inject(lazy=false)
35
     * @var Bootstrap
36
     */
37
    protected $bootstrap;
38
39
    /**
40
     * @Flow\Inject(lazy=false)
41
     * @var Router
42
     */
43
    protected $router;
44
45
    /**
46
     * @Flow\Inject(lazy=false)
47
     * @var SecurityContext
48
     */
49
    protected $securityContext;
50
51
    /**
52
     * @Flow\Inject
53
     * @var ConfigurationManager
54
     */
55
    protected $configurationManager;
56
57
    /**
58
     * @Flow\InjectConfiguration(path="routing.supportEmptySegmentForDimensions", package="Neos.Neos")
59
     * @var boolean
60
     */
61
    protected $supportEmptySegmentForDimensions;
62
63
    /**
64
     * @Flow\Inject
65
     * @var ContentDimensionPresetSourceInterface
66
     */
67
    protected $contentDimensionPresetSource;
68
69
    /**
70
     * Initialize this engine
71
     *
72
     * @return void
73
     */
74
    public function initializeObject()
75
    {
76
        $this->router->setRoutesConfiguration($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_ROUTES));
77
    }
78
    
79
    /**
80
     * @return void
81
     * @throws \Neos\FluidAdaptor\Core\ViewHelper\Exception
82
     * @api
83
     */
84
    public function initializeArguments()
85
    {
86
        parent::initializeArguments();
87
        $this->registerArgument('path', 'string', 'Path');
88
    }
89
90
    /**
91
     * @return string
92
     * @throws \Exception
93
     */
94
    public function render()
95
    {
96
        $this->appendFirstUriPartIfValidDimension($path);
97
        /** @var RequestHandler $activeRequestHandler */
98
        $activeRequestHandler = $this->bootstrap->getActiveRequestHandler();
99
        $parentHttpRequest = $activeRequestHandler->getHttpRequest();
100
        $uri = rtrim($parentHttpRequest->getBaseUri(), '/') . '/' . $path;
0 ignored issues
show
Bug introduced by
The method getBaseUri() does not seem to exist on object<Psr\Http\Message\ServerRequestInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
101
        $httpRequest = Request::create(new Uri($uri));
102
        $routeContext = new RouteContext($httpRequest, RouteParameters::createEmpty());
103
        try {
104
            $matchingRoute = $this->router->route($routeContext);
105
        } catch (NoMatchingRouteException $exception) {
106
            $matchingRoute = null;
107
        }
108
        if (!$matchingRoute) {
109
            $exception = new \Exception(sprintf('Uri with path "%s" could not be found.', $uri), 1426446160);
110
            $exceptionHandler = set_exception_handler(null)[0];
111
            $exceptionHandler->handleException($exception);
112
            exit();
113
        }
114
        $request = new ActionRequest($parentHttpRequest);
115
        foreach ($matchingRoute as $argumentName => $argumentValue) {
116
            $request->setArgument($argumentName, $argumentValue);
117
        }
118
        $response = new Response($activeRequestHandler->getHttpResponse());
119
120
        $this->securityContext->withoutAuthorizationChecks(function () use ($request, $response) {
121
            $this->dispatcher->dispatch($request, $response);
122
        });
123
124
        return $response->getContent();
125
    }
126
127
    /**
128
     * @param string $path
129
     * @return void
130
     */
131
    protected function appendFirstUriPartIfValidDimension(&$path)
132
    {
133
        $requestPath = ltrim($this->controllerContext->getRequest()->getHttpRequest()->getUri()->getPath(), '/');
134
        $matches = [];
135
        preg_match(FrontendNodeRoutePartHandler::DIMENSION_REQUEST_PATH_MATCHER, $requestPath, $matches);
136
        if (!isset($matches['firstUriPart']) && !isset($matches['dimensionPresetUriSegments'])) {
137
            return;
138
        }
139
140
        $dimensionPresets = $this->contentDimensionPresetSource->getAllPresets();
141
        if (count($dimensionPresets) === 0) {
142
            return;
143
        }
144
145
        $firstUriPartExploded = explode('_', $matches['firstUriPart'] ?: $matches['dimensionPresetUriSegments']);
146
        if ($this->supportEmptySegmentForDimensions) {
147
            foreach ($firstUriPartExploded as $uriSegment) {
148
                $uriSegmentIsValid = false;
149
                foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
150
                    $preset = $this->contentDimensionPresetSource->findPresetByUriSegment($dimensionName, $uriSegment);
151
                    if ($preset !== null) {
152
                        $uriSegmentIsValid = true;
153
                        break;
154
                    }
155
                }
156
                if (!$uriSegmentIsValid) {
157
                    return;
158
                }
159
            }
160
        } else {
161
            if (count($firstUriPartExploded) !== count($dimensionPresets)) {
162
                $this->appendDefaultDimensionPresetUriSegments($dimensionPresets, $path);
163
                return;
164
            }
165
            foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
166
                $uriSegment = array_shift($firstUriPartExploded);
167
                $preset = $this->contentDimensionPresetSource->findPresetByUriSegment($dimensionName, $uriSegment);
168
                if ($preset === null) {
169
                    $this->appendDefaultDimensionPresetUriSegments($dimensionPresets, $path);
170
                    return;
171
                }
172
            }
173
        }
174
175
        $path = $matches['firstUriPart'] . '/' . $path;
176
    }
177
178
    /**
179
     * @param array $dimensionPresets
180
     * @param string $path
181
     * @return void
182
     */
183
    protected function appendDefaultDimensionPresetUriSegments(array $dimensionPresets, &$path) {
184
        $defaultDimensionPresetUriSegments = [];
185
        foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
186
            $defaultDimensionPresetUriSegments[] = $dimensionPreset['presets'][$dimensionPreset['defaultPreset']]['uriSegment'];
187
        }
188
        $path = implode('_', $defaultDimensionPresetUriSegments) . '/' . $path;
189
    }
190
}
191