Passed
Push — master ( 9e15fe...1d956f )
by Jean-Christophe
09:32
created

ControllerParser   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 90.11%

Importance

Changes 0
Metric Value
wmc 39
eloc 90
dl 0
loc 137
ccs 82
cts 91
cp 0.9011
rs 9.28
c 0
b 0
f 0

8 Methods

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