Passed
Push — master ( 07ea47...32da0d )
by Jean-Christophe
11:56
created

ControllerParser::asArray()   B

Complexity

Conditions 8
Paths 27

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 8.7021

Importance

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