Ubiquity 2.5.2
php rapid development framework
Loading...
Searching...
No Matches
DiControllerParser.php
Go to the documentation of this file.
1<?php
2
4
5use Hybridauth\Thirdparty\OpenID\ErrorException;
7use Ubiquity\utils\base\UArray;
11
24 protected $injections = [ ];
25
26 public function parse($controllerClass, $config) {
27 $properties = Reflexion::getProperties ( $controllerClass );
28 foreach ( $properties as $property ) {
29 $propName = $property->getName ();
30 $annot = Reflexion::getAnnotationMember ( $controllerClass, $propName, 'injected' );
31 if ($annot !== false) {
32 $name = $annot->name;
33 if ($this->isInjectable ( $controllerClass, $propName, false )) {
34 $this->injections [$propName] = $this->getInjection ( $name ?? $propName, $config, $controllerClass, $annot->code ?? null);
35 }
36 } else {
37 $annot = Reflexion::getAnnotationMember ( $controllerClass, $propName, 'autowired' );
38 if ($annot !== false) {
39 $type = Reflexion::getPropertyType ( $controllerClass, $propName );
40 if ($type !== false) {
41 if ($this->isInjectable ( $controllerClass, $propName, false )) {
42 if(\is_string($type)){
43 $this->getInjectableAutowired ( $type, $propName );
44 }elseif($type instanceof \ReflectionProperty || $type instanceof \ReflectionNamedType){
45 $this->getInjectableAutowired ( $type->getName (), $propName );
46 }
47 }
48 } else {
49 throw new DiException ( sprintf ( '%s property has no type and cannot be autowired!', $propName ) );
50 }
51 }
52 }
53 }
54 $this->scanGlobalDi ( $config ['di'] ?? [ ], $controllerClass );
55 }
56
57 protected function getInjectableAutowired($type, $propName) {
58 $typeR = new \ReflectionClass ( $type );
59 if ($typeR->isInstantiable ()) {
60 $constructor = $typeR->getConstructor ();
61 $nbParams = $constructor == null ? 0 : $typeR->getConstructor ()->getNumberOfRequiredParameters ();
62 if ($nbParams == 0) {
63 $this->injections [$propName] = "function(){return new " . $type . "();}";
64 } elseif ($nbParams == 1) {
65 $this->injections [$propName] = "function(\$controller){return new " . $type . "(\$controller);}";
66 } else {
67 throw new DiException ( sprintf ( 'Service %s constructor has too many mandatory arguments for %s injection!', $type, $propName ) );
68 }
69 } else {
70 $namespace = $typeR->getNamespaceName ();
71 $oClass = $namespace . "\\" . ucfirst ( $propName );
72 if (class_exists ( $oClass )) {
73 if (is_subclass_of ( $oClass, $type )) {
74 $this->getInjectableAutowired ( $oClass, $propName );
75 } else {
76 throw new DiException ( sprintf ( 'Class %s is not a subclass of %s!', $oClass, $type ) );
77 }
78 } else {
79 throw new DiException ( sprintf ( 'Class %s does not exists!', $oClass ) );
80 }
81 }
82 }
83
84 protected function scanGlobalDi($diConfig, $controller) {
85 $classname = ClassUtils::getClassSimpleName ( $controller );
86 foreach ( $diConfig as $k => $v ) {
87 if (UString::startswith ( $k, "*." ) || UString::startswith ( $k, $classname . "." )) {
88 $dis = explode ( '.', $k );
89 $nkey = end ( $dis );
90 if (property_exists ( $controller, $nkey ) === false) {
91 $this->injections [$nkey] = $v;
92 }
93 }
94 }
95 }
96
97 protected function isInjectable($classname, $member, $silent = true) {
98 if (\property_exists($classname, $member)) {
99 $prop = new \ReflectionProperty ($classname, $member);
100 if ($prop->isPublic()) {
101 return true;
102 }
103 }
104 $setter = 'set' . ucfirst ( $member );
105 if (\method_exists ( $classname, $setter )) {
106 return true;
107 }
108 if (! $silent) {
109 throw new DiException ( sprintf ( '%s member must be public or have a setter to be injected in the class %s!', $member, $classname ) );
110 }
111 return false;
112 }
113
114 protected function getInjection($name, $config, $controller, $code = null) {
115 if ($code != null) {
116 return "function(\$controller){return " . $code . ";}";
117 }
118 if (isset ( $config ["di"] )) {
119 $di = $config ['di'];
120 if ($name != null) {
121 $classname = ClassUtils::getClassSimpleName ( $controller );
122 if (isset ( $di [$name] )) {
123 return $di [$name];
124 } elseif (isset ( $di [$classname . '.' . $name] )) {
125 return $di [$classname . '.' . $name];
126 } elseif (isset ( $di ['*.' . $name] )) {
127 return $di ['*.' . $name];
128 } else {
129 throw new \Exception ( "key " . $name . " is not present in config di array" );
130 }
131 }
132 } else {
133 throw new \Exception ( "key di is not present in config array" );
134 }
135 }
136
137 public function __toString() {
138 return "return " . UArray::asPhpArray ( $this->injections, "array" ) . ";";
139 }
140
145 public function getInjections() {
146 return $this->injections;
147 }
148}
149
Manipulates class and namespace names Ubiquity\cache$ClassUtils This class is part of Ubiquity.
Parse the controllers for dependency injections.
isInjectable($classname, $member, $silent=true)
getInjection($name, $config, $controller, $code=null)
Reflection utilities in dev environment only.
Definition Reflexion.php:17
String utilities.
Definition UString.php:15