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

RequestViewHelper   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 125
Duplicated Lines 11.2 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 17
c 5
b 0
f 1
lcom 1
cbo 1
dl 14
loc 125
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A initializeObject() 0 3 1
A render() 0 23 3
C appendFirstUriPartIfValidDimension() 14 43 13

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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