Completed
Push — master ( efe174...d93d05 )
by Jean-Christophe
01:58
created

ControllerParser::parseRouteArray()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 13
nc 4
nop 7
1
<?php
2
namespace micro\cache;
3
use micro\orm\parser\Reflexion;
4
use micro\utils\StrUtils;
5
6
class ControllerParser {
7
	private $controllerClass;
8
	private $mainRouteClass;
9
	private $routesMethods=[];
10
11
	public function parse($controllerClass){
12
		$this->controllerClass=$controllerClass;
13
		$reflect=new \ReflectionClass($controllerClass);
14
		if(!$reflect->isAbstract()){
15
			$instance=new $controllerClass();
16
			$annotsClass= Reflexion::getAnnotationClass($controllerClass, "@route");
17
			if(\sizeof($annotsClass)>0)
18
				$this->mainRouteClass=$annotsClass[0];
19
			$methods=Reflexion::getMethods($instance,\ReflectionMethod::IS_PUBLIC);
20
			foreach ($methods as $method){
21
				$annots=Reflexion::getAnnotationsMethod($controllerClass, $method->name, "@route");
22
				if($annots!==false)
23
					$this->routesMethods[$method->name]=["annotations"=>$annots,"method"=>$method];
24
			}
25
		}
26
	}
27
28
	private static function cleanpath($prefix,$path=""){
29
		if(!StrUtils::endswith($prefix, "/"))
30
			$prefix=$prefix."/";
31
		if($path!=="" && StrUtils::startswith($path, "/"))
32
			$path=\substr($path, 1);
33
		$path=$prefix.$path;
34
		if(StrUtils::endswith($path, "/"))
35
			$path=\substr($path, 0,\strlen($path)-1);
36
		return $path;
37
	}
38
39
	public function asArray(){
40
		$result=[];
41
		$prefix="";$httpMethods=false;
42
		if($this->mainRouteClass){
43
			if(isset($this->mainRouteClass->path))
44
				$prefix=$this->mainRouteClass->path;
45
			if(isset($this->mainRouteClass->methods)){
46
				$httpMethods=$this->mainRouteClass->methods;
47
				if($httpMethods!==null){
48
					if(\is_string($httpMethods))
49
						$httpMethods=[$httpMethods];
50
				}
51
			}
52
		}
53
54
		foreach ($this->routesMethods as $method=>$arrayAnnotsMethod){
55
			$routeAnnotations=$arrayAnnotsMethod["annotations"];
56
			foreach ($routeAnnotations as $routeAnnotation){
57
				self::parseRouteArray($result, $this->controllerClass,["path"=>$routeAnnotation->path,"methods"=>$routeAnnotation->methods,"name"=>$routeAnnotation->name], $arrayAnnotsMethod["method"], $method,$prefix,$httpMethods);
58
			}
59
		}
60
		return $result;
61
	}
62
63
	public static function parseRouteArray(&$result,$controllerClass,$routeArray,\ReflectionMethod $method,$methodName,$prefix="",$httpMethods=NULL){
64
		if(isset($routeArray["path"])){
65
			$pathParameters=self::addParamsPath($routeArray["path"], $method);
66
			$name=$routeArray["name"];
67
			$path=$pathParameters["path"];
68
			$parameters=$pathParameters["parameters"];
69
			$path=self::cleanpath($prefix,$path);
70
			if(isset($routeArray["methods"]) && \is_array($routeArray["methods"])){
71
				self::createRouteMethod($result,$controllerClass,$path,$routeArray["methods"],$methodName,$parameters,$name);
72
			}elseif(\is_array($httpMethods)){
73
				self::createRouteMethod($result,$controllerClass,$path,$httpMethods,$methodName,$parameters,$name);
74
			}else{
75
				$result[$path]=["controller"=>$controllerClass,"action"=>$methodName,"parameters"=>$parameters,"name"=>$name];
76
			}
77
		}
78
	}
79
80
	public static function addParamsPath($path,\ReflectionMethod $method){
81
		$parameters=[];
82
		preg_match_all('@\{(.+?)\}@s', $path, $matches);
83
		if(isset($matches[1]) && \sizeof($matches[1])>0){
84
			$path=\preg_quote($path);
85
			$params=Reflexion::getMethodParameters($method);
86
			foreach ($matches[1] as $paramMatch){
87
				$find=\array_search($paramMatch, $params);
88
				if($find!==false){
89
					$parameters[]=$find;
90
					$path=\str_replace("\{".$paramMatch."\}", "(.+?)", $path);
91
				}else{
92
					throw new \Exception("{$paramMatch} is not a parameter of the method ".$method->name);
93
				}
94
			}
95
		}
96
		return ["path"=>$path,"parameters"=>$parameters];
97
	}
98
99
	private static function createRouteMethod(&$result,$controllerClass,$path,$httpMethods,$method,$parameters,$name){
100
		foreach ($httpMethods as $httpMethod){
101
				$result[$path][$httpMethod]=["controller"=>$controllerClass,"action"=>$method,"parameters"=>$parameters,"name"=>$name];
102
		}
103
	}
104
}
105