Passed
Push — master ( be71ba...d26f6c )
by Jean-Christophe
03:55
created

generateRouteAnnotationFromMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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