Test Failed
Push — master ( 588dda...e10d69 )
by Jean-Christophe
07:32
created

ControllerParser::parseAnnot()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
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
 *
14
 * @author jcheron <[email protected]>
15
 * @version 1.0.4
16
 */
17
class ControllerParser {
18
	use ControllerParserPathTrait;
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() {
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
		return $result;
116
	}
117
118 2
	public static function parseRouteArray(&$result, $controllerClass, $routeArray, \ReflectionMethod $method, $methodName, $prefix = "", $httpMethods = NULL) {
119
		if (! isset ( $routeArray ["path"] )) {
120
			$routeArray ["path"] = self::getPathFromMethod ( $method );
121
		}
122
		$pathParameters = self::addParamsPath ( $routeArray ["path"], $method, $routeArray ["requirements"] );
123
		$name = $routeArray ["name"];
124
		if (! isset ( $name )) {
125
			$name = UString::cleanAttribute ( ClassUtils::getClassSimpleName ( $controllerClass ) . "_" . $methodName );
126
		}
127
		$cache = $routeArray ["cache"];
128
		$duration = $routeArray ["duration"];
129
		$path = $pathParameters ["path"];
130
		$parameters = $pathParameters ["parameters"];
131
		$priority = $routeArray ["priority"];
132
		$path = self::cleanpath ( $prefix, $path );
133
		if (isset ( $routeArray ["methods"] ) && \is_array ( $routeArray ["methods"] )) {
134
			self::createRouteMethod ( $result, $controllerClass, $path, $routeArray ["methods"], $methodName, $parameters, $name, $cache, $duration, $priority );
135
		} elseif (\is_array ( $httpMethods )) {
136
			self::createRouteMethod ( $result, $controllerClass, $path, $httpMethods, $methodName, $parameters, $name, $cache, $duration, $priority );
137
		} else {
138
			$result [$path] = [ "controller" => $controllerClass,"action" => $methodName,"parameters" => $parameters,"name" => $name,"cache" => $cache,"duration" => $duration,"priority" => $priority ];
139
		}
140
	}
141
142
	private static function createRouteMethod(&$result, $controllerClass, $path, $httpMethods, $method, $parameters, $name, $cache, $duration, $priority) {
143
		foreach ( $httpMethods as $httpMethod ) {
144
			$result [$path] [$httpMethod] = [ "controller" => $controllerClass,"action" => $method,"parameters" => $parameters,"name" => $name,"cache" => $cache,"duration" => $duration,"priority" => $priority ];
145
		}
146 20
	}
147 20
148
	public function isRest() {
149
		return $this->rest;
150 20
	}
151
}
152