Passed
Push — master ( b68a78...d29a76 )
by Jean-Christophe
16:10 queued 03:52
created

ControllerParser::parse()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 21
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.0073

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 17
c 1
b 0
f 1
dl 0
loc 21
ccs 16
cts 17
cp 0.9412
rs 9.0777
cc 6
nc 7
nop 1
crap 6.0073
1
<?php
2
3
namespace Ubiquity\cache\parser;
4
5
use Ubiquity\orm\parser\Reflexion;
6
use Ubiquity\utils\base\UString;
7
use Ubiquity\annotations\router\RouteAnnotation;
0 ignored issues
show
Bug introduced by
The type Ubiquity\annotations\router\RouteAnnotation was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Ubiquity\cache\ClassUtils;
9
use Ubiquity\annotations\AnnotationsEngineInterface;
10
11
/**
12
 * Scans a controller to detect routes defined by annotations.
13
 * Ubiquity\cache\parser$ControllerParser
14
 * This class is part of Ubiquity
15
 *
16
 * @author jcheron <[email protected]>
17
 * @version 1.0.8
18
 *
19
 */
20
class ControllerParser {
21
	use ControllerParserPathTrait;
22
	private $controllerClass;
23
	private $mainRouteClass;
24
	private $routesMethods = [ ];
25
	private $rest = false;
26
	private static $excludeds = [ '__construct','isValid','initialize','finalize','onInvalidControl','loadView','forward','redirectToRoute' ];
27
28
	/**
29
	 * @var AnnotationsEngineInterface
30
	 */
31
	private $annotsEngine;
32
33 17
	public function __construct(AnnotationsEngineInterface $annotsEngine){
34 17
		$this->annotsEngine=$annotsEngine;
35 17
	}
36
37 17
	public function parse($controllerClass) {
38 17
		$automated = false;
39 17
		$inherited = false;
40 17
		$this->controllerClass = $controllerClass;
41 17
		$restAnnotsClass = [ ];
42 17
		$reflect = new \ReflectionClass ( $controllerClass );
43 17
		if (! $reflect->isAbstract () && $reflect->isSubclassOf ( \Ubiquity\controllers\Controller::class )) {
44
			try {
45 17
				$annotsClass = Reflexion::getAnnotationClass ( $controllerClass, 'route' );
46 17
				$restAnnotsClass = Reflexion::getAnnotationClass ( $controllerClass, 'rest' );
47
			} catch ( \Exception $e ) {
48
				// When controllerClass generates an exception
49
			}
50 17
			$this->rest = \sizeof ( $restAnnotsClass ) > 0;
51 17
			if (isset ( $annotsClass ) && \sizeof ( $annotsClass ) > 0) {
52 17
				$this->mainRouteClass = $annotsClass [0];
53 17
				$inherited = $this->mainRouteClass->inherited;
54 17
				$automated = $this->mainRouteClass->automated;
55
			}
56 17
			$methods = Reflexion::getMethods ( $controllerClass, \ReflectionMethod::IS_PUBLIC );
57 17
			$this->parseMethods ( $methods, $controllerClass, $inherited, $automated );
58
		}
59 17
	}
60
61 17
	private function parseMethods($methods, $controllerClass, $inherited, $automated) {
62 17
		foreach ( $methods as $method ) {
63 17
			if ($method->getDeclaringClass ()->getName () === $controllerClass || $inherited) {
64
				try {
65 17
					$annots = Reflexion::getAnnotationsMethod ( $controllerClass, $method->name, [ 'route','get','post','patch','put','delete','options' ] );
66 17
					if (\count ( $annots ) > 0) {
67 17
						foreach ( $annots as $annot ) {
68 17
							$this->parseAnnot ( $annot, $method );
69
						}
70 17
						$this->routesMethods [$method->name] = [ 'annotations' => $annots,'method' => $method ];
71
					} else {
72 17
						if ($automated) {
73 17
							if ($method->class !== 'Ubiquity\\controllers\\Controller' && \array_search ( $method->name, self::$excludeds ) === false && ! UString::startswith ( $method->name, '_' ))
74 17
								$this->routesMethods [$method->name] = [ 'annotations' => $this->generateRouteAnnotationFromMethod ( $method ),'method' => $method ];
75
						}
76
					}
77
				} catch ( \Exception $e ) {
78
					// When controllerClass generates an exception
79
				}
80
			}
81
		}
82 17
	}
83
84 17
	private function parseAnnot(&$annot, $method) {
85 17
		if (UString::isNull ( $annot->path )) {
86 17
			$newAnnot = $this->generateRouteAnnotationFromMethod ( $method );
87 17
			$annot->path = $newAnnot [0]->path;
88
		} else {
89 17
			$annot->path = $this->parseMethodPath ( $method, $annot->path );
90
		}
91 17
	}
92
93 17
	private function generateRouteAnnotationFromMethod(\ReflectionMethod $method) {
94 17
		return [ $this->annotsEngine->getAnnotation(null,'route',['path'=>self::getPathFromMethod ( $method )]) ];
95
	}
96
97 17
	public function asArray() {
98 17
		$result = [ ];
99 17
		$prefix = '';
100 17
		$httpMethods = false;
101 17
		if ($this->mainRouteClass) {
102 17
			if (isset ( $this->mainRouteClass->path ))
103 17
				$prefix = $this->mainRouteClass->path;
104 17
			if (isset ( $this->mainRouteClass->methods )) {
105
				$httpMethods = $this->mainRouteClass->methods;
106
				if ($httpMethods !== null) {
107
					if (\is_string ( $httpMethods ))
108
						$httpMethods = [ $httpMethods ];
109
				}
110
			}
111
		}
112 17
		foreach ( $this->routesMethods as $method => $arrayAnnotsMethod ) {
113 17
			$routeAnnotations = $arrayAnnotsMethod ['annotations'];
114
115 17
			foreach ( $routeAnnotations as $routeAnnotation ) {
116 17
				$params = [ 'path' => $routeAnnotation->path,'methods' => $routeAnnotation->methods,'name' => $routeAnnotation->name,'cache' => $routeAnnotation->cache,'duration' => $routeAnnotation->duration,'requirements' => $routeAnnotation->requirements,'priority' => $routeAnnotation->priority ];
117 17
				self::parseRouteArray ( $result, $this->controllerClass, $params, $arrayAnnotsMethod ['method'], $method, $prefix, $httpMethods );
118
			}
119
		}
120 17
		return $result;
121
	}
122
123 43
	public static function parseRouteArray(&$result, $controllerClass, $routeArray, \ReflectionMethod $method, $methodName, $prefix = '', $httpMethods = NULL) {
124 43
		if (! isset ( $routeArray ['path'] )) {
125
			$routeArray ['path'] = self::getPathFromMethod ( $method );
126
		}
127 43
		$pathParameters = self::addParamsPath ( $routeArray ['path'], $method, $routeArray ['requirements'] );
128 43
		$name = $routeArray ['name'];
129 43
		if (! isset ( $name )) {
130 17
			$name = UString::cleanAttribute ( ClassUtils::getClassSimpleName ( $controllerClass ) . '_' . $methodName );
131
		}
132 43
		$cache = $routeArray ['cache'];
133 43
		$duration = $routeArray ['duration'];
134 43
		$path = $pathParameters ['path'];
135 43
		$parameters = $pathParameters ['parameters'];
136 43
		$priority = $routeArray ['priority'];
137 43
		$callback = $routeArray ['callback'] ?? null;
138 43
		$path = self::cleanpath ( $prefix, $path );
139 43
		if (isset ( $routeArray ['methods'] ) && \is_array ( $routeArray ['methods'] )) {
140 17
			self::createRouteMethod ( $result, $controllerClass, $path, $routeArray ['methods'], $methodName, $parameters, $name, $cache, $duration, $priority, $callback );
141 43
		} elseif (\is_array ( $httpMethods )) {
142
			self::createRouteMethod ( $result, $controllerClass, $path, $httpMethods, $methodName, $parameters, $name, $cache, $duration, $priority, $callback );
143
		} else {
144 43
			$v = [ 'controller' => $controllerClass,'action' => $methodName,'parameters' => $parameters,'name' => $name,'cache' => $cache,'duration' => $duration,'priority' => $priority ];
145 43
			if (isset ( $callback )) {
146 1
				$v ['callback'] = $callback;
147
			}
148 43
			$result [$path] = $v;
149
		}
150 43
	}
151
152 17
	private static function createRouteMethod(&$result, $controllerClass, $path, $httpMethods, $method, $parameters, $name, $cache, $duration, $priority, $callback = null) {
153 17
		foreach ( $httpMethods as $httpMethod ) {
154 17
			$v = [ 'controller' => $controllerClass,'action' => $method,'parameters' => $parameters,'name' => $name,'cache' => $cache,'duration' => $duration,'priority' => $priority ];
155 17
			if (isset ( $callback )) {
156
				$v ['callback'] = $callback;
157
			}
158 17
			$result [$path] [$httpMethod] = $v;
159
		}
160 17
	}
161
162 17
	public function isRest() {
163 17
		return $this->rest;
164
	}
165
}
166