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) {
33 if ($this->
isInjectable ( $controllerClass, $propName,
false )) {
34 $this->injections [$propName] = $this->
getInjection ( $name ?? $propName, $config, $controllerClass, $annot->code ??
null);
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)){
44 }elseif($type instanceof \ReflectionProperty || $type instanceof \ReflectionNamedType){
49 throw new DiException ( sprintf (
'%s property has no type and cannot be autowired!', $propName ) );
54 $this->
scanGlobalDi ( $config [
'di'] ?? [ ], $controllerClass );
58 $typeR = new \ReflectionClass ( $type );
59 if ($typeR->isInstantiable ()) {
60 $constructor = $typeR->getConstructor ();
61 $nbParams = $constructor ==
null ? 0 : $typeR->getConstructor ()->getNumberOfRequiredParameters ();
63 $this->injections [$propName] =
"function(){return new " . $type .
"();}";
64 } elseif ($nbParams == 1) {
65 $this->injections [$propName] =
"function(\$controller){return new " . $type .
"(\$controller);}";
67 throw new DiException ( sprintf (
'Service %s constructor has too many mandatory arguments for %s injection!', $type, $propName ) );
70 $namespace = $typeR->getNamespaceName ();
71 $oClass = $namespace .
"\\" . ucfirst ( $propName );
72 if (class_exists ( $oClass )) {
73 if (is_subclass_of ( $oClass, $type )) {
76 throw new DiException ( sprintf (
'Class %s is not a subclass of %s!', $oClass, $type ) );
79 throw new DiException ( sprintf (
'Class %s does not exists!', $oClass ) );
85 $classname = ClassUtils::getClassSimpleName ( $controller );
86 foreach ( $diConfig as $k => $v ) {
87 if (UString::startswith ( $k,
"*." ) || UString::startswith ( $k, $classname .
"." )) {
88 $dis = explode (
'.', $k );
90 if (property_exists ( $controller, $nkey ) ===
false) {
91 $this->injections [$nkey] = $v;
97 protected function isInjectable($classname, $member, $silent =
true) {
98 if (\property_exists($classname, $member)) {
99 $prop = new \ReflectionProperty ($classname, $member);
100 if ($prop->isPublic()) {
104 $setter =
'set' . ucfirst ( $member );
105 if (\method_exists ( $classname, $setter )) {
109 throw new DiException ( sprintf (
'%s member must be public or have a setter to be injected in the class %s!', $member, $classname ) );
114 protected function getInjection($name, $config, $controller, $code =
null) {
116 return "function(\$controller){return " . $code .
";}";
118 if (isset ( $config [
"di"] )) {
119 $di = $config [
'di'];
121 $classname = ClassUtils::getClassSimpleName ( $controller );
122 if (isset ( $di [$name] )) {
124 } elseif (isset ( $di [$classname .
'.' . $name] )) {
125 return $di [$classname .
'.' . $name];
126 } elseif (isset ( $di [
'*.' . $name] )) {
127 return $di [
'*.' . $name];
129 throw new \Exception (
"key " . $name .
" is not present in config di array" );
133 throw new \Exception (
"key di is not present in config array" );