Test Failed
Push — master ( 93f81f...e78505 )
by Jean-Christophe
78:02
created

ControllerParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
ccs 1
cts 1
cp 1
rs 10
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\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 17
28 17
	/**
29 17
	 * @var AnnotationsEngineInterface
30 17
	 */
31 17
	private $annotsEngine;
32 17
33 17
	public function __construct(AnnotationsEngineInterface $annotsEngine){
34
		$this->annotsEngine=$annotsEngine;
35 17
	}
36 17
37
	public function parse($controllerClass) {
38
		$automated = false;
39
		$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 17
			try {
45
				$annotsClass = Reflexion::getAnnotationClass ( $controllerClass, 'route' );
46 17
				$restAnnotsClass = Reflexion::getAnnotationClass ( $controllerClass, 'rest' );
47 17
			} catch ( \Exception $e ) {
48
				// When controllerClass generates an exception
49 17
			}
50
			$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
				$automated = $this->mainRouteClass->automated;
55 17
			}
56 17
			$methods = Reflexion::getMethods ( $controllerClass, \ReflectionMethod::IS_PUBLIC );
57 17
			$this->parseMethods ( $methods, $controllerClass, $inherited, $automated );
58 17
		}
59
	}
60 17
61
	private function parseMethods($methods, $controllerClass, $inherited, $automated) {
62 17
		foreach ( $methods as $method ) {
63 17
			if ($method->getDeclaringClass ()->getName () === $controllerClass || $inherited) {
64 17
				try {
65
					$annots = Reflexion::getAnnotationsMethod ( $controllerClass, $method->name, [ 'route','get','post','patch','put','delete','options' ] );
66
					if (\count ( $annots ) > 0) {
67
						foreach ( $annots as $annot ) {
68
							$this->parseAnnot ( $annot, $method );
69
						}
70
						$this->routesMethods [$method->name] = [ 'annotations' => $annots,'method' => $method ];
71
					} else {
72 17
						if ($automated) {
73
							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 17
						}
76 17
					}
77 17
				} catch ( \Exception $e ) {
78
					// When controllerClass generates an exception
79 17
				}
80
			}
81 17
		}
82
	}
83 17
84 17
	private function parseAnnot(&$annot, $method) {
85 17
		if (UString::isNull ( $annot->path )) {
86 17
			$newAnnot = $this->generateRouteAnnotationFromMethod ( $method );
87
			$annot->path = $newAnnot [0]->path;
88
		} else {
89 17
			$annot->path = $this->parseMethodPath ( $method, $annot->path );
90 17
		}
91 17
	}
92 17
93 17
	private function generateRouteAnnotationFromMethod(\ReflectionMethod $method) {
94 17
		return [ $this->annotsEngine->getAnnotation(null,'route',['path'=>self::getPathFromMethod ( $method )]) ];
95 17
	}
96 17
97
	public function asArray() {
98
		$result = [ ];
99
		$prefix = '';
100
		$httpMethods = false;
101
		if ($this->mainRouteClass) {
102
			if (isset ( $this->mainRouteClass->path ))
103
				$prefix = $this->mainRouteClass->path;
104 17
			if (isset ( $this->mainRouteClass->methods )) {
105 17
				$httpMethods = $this->mainRouteClass->methods;
106
				if ($httpMethods !== null) {
107 17
					if (\is_string ( $httpMethods ))
108 17
						$httpMethods = [ $httpMethods ];
109 17
				}
110
			}
111
		}
112 17
		foreach ( $this->routesMethods as $method => $arrayAnnotsMethod ) {
113
			$routeAnnotations = $arrayAnnotsMethod ['annotations'];
114
115 43
			foreach ( $routeAnnotations as $routeAnnotation ) {
116 43
				$params = [ 'path' => $routeAnnotation->path,'methods' => $routeAnnotation->methods,'name' => $routeAnnotation->name,'cache' => $routeAnnotation->cache,'duration' => $routeAnnotation->duration,'requirements' => $routeAnnotation->requirements,'priority' => $routeAnnotation->priority ];
117
				self::parseRouteArray ( $result, $this->controllerClass, $params, $arrayAnnotsMethod ['method'], $method, $prefix, $httpMethods );
118
			}
119 43
		}
120 43
		return $result;
121 43
	}
122 17
123
	public static function parseRouteArray(&$result, $controllerClass, $routeArray, \ReflectionMethod $method, $methodName, $prefix = '', $httpMethods = NULL) {
124 43
		if (! isset ( $routeArray ['path'] )) {
125 43
			$routeArray ['path'] = self::getPathFromMethod ( $method );
126 43
		}
127 43
		$pathParameters = self::addParamsPath ( $routeArray ['path'], $method, $routeArray ['requirements'] );
128 43
		$name = $routeArray ['name'];
129 43
		if (! isset ( $name )) {
130 43
			$name = UString::cleanAttribute ( ClassUtils::getClassSimpleName ( $controllerClass ) . '_' . $methodName );
131 43
		}
132 17
		$cache = $routeArray ['cache'];
133 43
		$duration = $routeArray ['duration'];
134
		$path = $pathParameters ['path'];
135
		$parameters = $pathParameters ['parameters'];
136 43
		$priority = $routeArray ['priority'];
137 43
		$callback = $routeArray ['callback'] ?? null;
138 1
		$path = self::cleanpath ( $prefix, $path );
139
		if (isset ( $routeArray ['methods'] ) && \is_array ( $routeArray ['methods'] )) {
140 43
			self::createRouteMethod ( $result, $controllerClass, $path, $routeArray ['methods'], $methodName, $parameters, $name, $cache, $duration, $priority, $callback );
141
		} elseif (\is_array ( $httpMethods )) {
142 43
			self::createRouteMethod ( $result, $controllerClass, $path, $httpMethods, $methodName, $parameters, $name, $cache, $duration, $priority, $callback );
143
		} else {
144 17
			$v = [ 'controller' => $controllerClass,'action' => $methodName,'parameters' => $parameters,'name' => $name,'cache' => $cache,'duration' => $duration,'priority' => $priority ];
145 17
			if (isset ( $callback )) {
146 17
				$v ['callback'] = $callback;
147 17
			}
148
			$result [$path] = $v;
149
		}
150 17
	}
151
152 17
	private static function createRouteMethod(&$result, $controllerClass, $path, $httpMethods, $method, $parameters, $name, $cache, $duration, $priority, $callback = null) {
153
		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
			$result [$path] [$httpMethod] = $v;
159
		}
160
	}
161
162
	public function isRest() {
163
		return $this->rest;
164
	}
165
}
166