Completed
Push — master ( 483822...8bd317 )
by Aske
02:53
created

appendFirstUriPartIfValidDimension()   C

Complexity

Conditions 13
Paths 10

Size

Total Lines 43
Code Lines 29

Duplication

Lines 14
Ratio 32.56 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 14
loc 43
rs 5.1234
cc 13
eloc 29
nc 10
nop 1

How to fix   Complexity   

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
2
namespace MOC\NotFound\ViewHelpers;
3
4
use TYPO3\Flow\Annotations as Flow;
5
use TYPO3\Flow\Configuration\ConfigurationManager;
6
use TYPO3\Flow\Core\Bootstrap;
7
use TYPO3\Flow\Http\Request;
8
use TYPO3\Flow\Http\RequestHandler;
9
use TYPO3\Flow\Http\Response;
10
use TYPO3\Flow\Http\Uri;
11
use TYPO3\Flow\Mvc\ActionRequest;
12
use TYPO3\Flow\Mvc\Routing\Router;
13
use TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper;
14
use TYPO3\Neos\Domain\Service\ContentDimensionPresetSourceInterface;
15
16
/**
17
 * Loads the content of a given URL
18
 */
19
class RequestViewHelper extends AbstractViewHelper {
20
21
	/**
22
	 * @Flow\Inject
23
	 * @var \TYPO3\Flow\Mvc\Dispatcher
24
	 */
25
	protected $dispatcher;
26
27
	/**
28
	 * @Flow\Inject(lazy = false)
29
	 * @var Bootstrap
30
	 */
31
	protected $bootstrap;
32
33
	/**
34
	 * @Flow\Inject(lazy = false)
35
	 * @var Router
36
	 */
37
	protected $router;
38
39
	/**
40
	 * @Flow\Inject
41
	 * @var ConfigurationManager
42
	 */
43
	protected $configurationManager;
44
45
	/**
46
	 * @Flow\InjectConfiguration("routing.supportEmptySegmentForDimensions", package="TYPO3.Neos")
47
	 * @var boolean
48
	 */
49
	protected $supportEmptySegmentForDimensions;
50
51
	/**
52
	 * @Flow\Inject
53
	 * @var ContentDimensionPresetSourceInterface
54
	 */
55
	protected $contentDimensionPresetSource;
56
57
	/**
58
	 * Initialize this engine
59
	 *
60
	 * @return void
61
	 */
62
	public function initializeObject() {
63
		$this->router->setRoutesConfiguration($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_ROUTES));
64
	}
65
66
	/**
67
	 * @param string $path
68
	 * @return string
69
	 * @throws \Exception
70
	 */
71
	public function render($path = NULL) {
72
		$this->appendFirstUriPartIfValidDimension($path);
73
		/** @var RequestHandler $activeRequestHandler */
74
		$activeRequestHandler = $this->bootstrap->getActiveRequestHandler();
75
		$parentHttpRequest = $activeRequestHandler->getHttpRequest();
76
		$uri = rtrim($parentHttpRequest->getBaseUri(), '/') . '/' . $path;
77
		$httpRequest = Request::create(new Uri($uri));
78
		$matchingRoute = $this->router->route($httpRequest);
79
		if (!$matchingRoute) {
0 ignored issues
show
Bug Best Practice introduced by ssh-user
The expression $matchingRoute of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
80
			$exception = new \Exception(sprintf('Uri with path "%s" could not be found.', $uri), 1426446160);
81
			$exceptionHandler = set_exception_handler(null)[0];
82
			$exceptionHandler->handleException($exception);
83
			exit();
0 ignored issues
show
Coding Style Compatibility introduced by Aske Ertmann
The method render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
84
		}
85
		$request = new ActionRequest($parentHttpRequest);
86
		foreach ($matchingRoute as $argumentName => $argumentValue) {
87
			$request->setArgument($argumentName, $argumentValue);
88
		}
89
		$response = new Response($activeRequestHandler->getHttpResponse());
90
91
		$this->dispatcher->dispatch($request, $response);
92
		return $response->getContent();
93
	}
94
95
	/**
96
	 * @param string $path
97
	 * @return void
98
	 */
99
	protected function appendFirstUriPartIfValidDimension(&$path) {
100
		$requestPath = ltrim($this->controllerContext->getRequest()->getHttpRequest()->getUri()->getPath(), '/');
101
		$matches = [];
102
		preg_match(\TYPO3\Neos\Routing\FrontendNodeRoutePartHandler::DIMENSION_REQUEST_PATH_MATCHER, $requestPath, $matches);
103
		if (!isset($matches['firstUriPart']) && !isset($matches['dimensionPresetUriSegments'])) {
104
			return;
105
		}
106
107
		$dimensionPresets = $this->contentDimensionPresetSource->getAllPresets();
108
		if (count($dimensionPresets) === 0) {
109
			return;
110
		}
111
112
		$firstUriPartExploded = explode('_', $matches['firstUriPart'] ?: $matches['dimensionPresetUriSegments']);
113
		if ($this->supportEmptySegmentForDimensions) {
114
			foreach ($firstUriPartExploded as $uriSegment) {
115
				$uriSegmentIsValid = false;
116 View Code Duplication
				foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
0 ignored issues
show
Duplication introduced by Aske Ertmann
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
					$preset = $this->contentDimensionPresetSource->findPresetByUriSegment($dimensionName, $uriSegment);
118
					if ($preset !== null) {
119
						$uriSegmentIsValid = true;
120
						break;
121
					}
122
				}
123
				if (!$uriSegmentIsValid) {
124
					return;
125
				}
126
			}
127
		} else {
128
			if (count($firstUriPartExploded) === count($dimensionPresets)) {
129
				return;
130
			}
131 View Code Duplication
			foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
0 ignored issues
show
Duplication introduced by Aske Ertmann
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
				$uriSegment = array_shift($firstUriPartExploded);
133
				$preset = $this->contentDimensionPresetSource->findPresetByUriSegment($dimensionName, $uriSegment);
134
				if ($preset === null) {
135
					return;
136
				}
137
			}
138
		}
139
140
		$path = $matches['firstUriPart'] . '/' . $path;
141
	}
142
143
}
144