/** * _processSpecialties() - Break out the specialty names for this provider * */ protected function _processSpecialties() { $specialties = array(); if ($this->_providerReflection->hasMethod('getSpecialties')) { $specialties = $this->_provider->getSpecialties(); if (!is_array($specialties)) { throw new Exception\RuntimeException('Provider ' . get_class($this->_provider) . ' must return an array for method getSpecialties().'); } } else { $defaultProperties = $this->_providerReflection->getDefaultProperties(); $specialties = isset($defaultProperties['_specialties']) ? $defaultProperties['_specialties'] : array(); if (!is_array($specialties)) { throw new Exception\RuntimeException('Provider ' . get_class($this->_provider) . '\'s property $_specialties must be an array.'); } } $this->_specialties = array_merge(array('_Global'), $specialties); }
protected function processClass($class) { $strategy = $this->introspectionStrategy; // localize for readability try { $rClass = new Reflection\ClassReflection($class); } catch (\ReflectionException $e) { if (!$this->allowReflectionExceptions) { throw $e; } return; } $className = $rClass->getName(); $matches = null; // used for regex below // setup the key in classes $this->classes[$className] = array('supertypes' => array(), 'instantiator' => null, 'methods' => array(), 'parameters' => array()); $def =& $this->classes[$className]; // localize for brevity // class annotations? if ($strategy->getUseAnnotations() == true) { $annotations = $rClass->getAnnotations($strategy->getAnnotationManager()); if ($annotations instanceof AnnotationCollection && $annotations->hasAnnotation('Zend\\Di\\Definition\\Annotation\\Instantiator')) { // @todo Instnatiator support in annotations } } $rTarget = $rClass; $supertypes = array(); do { $supertypes = array_merge($supertypes, $rTarget->getInterfaceNames()); if (!($rTargetParent = $rTarget->getParentClass())) { break; } $supertypes[] = $rTargetParent->getName(); $rTarget = $rTargetParent; } while (true); $def['supertypes'] = $supertypes; if ($def['instantiator'] == null) { if ($rClass->isInstantiable()) { $def['instantiator'] = '__construct'; } } if ($rClass->hasMethod('__construct')) { $def['methods']['__construct'] = true; // required try { $this->processParams($def, $rClass, $rClass->getMethod('__construct')); } catch (\ReflectionException $e) { if (!$this->allowReflectionExceptions) { throw $e; } return; } } foreach ($rClass->getMethods(Reflection\MethodReflection::IS_PUBLIC) as $rMethod) { $methodName = $rMethod->getName(); if ($rMethod->getName() === '__construct') { continue; } if ($strategy->getUseAnnotations() == true) { $annotations = $rMethod->getAnnotations($strategy->getAnnotationManager()); if ($annotations instanceof AnnotationCollection && $annotations->hasAnnotation('Zend\\Di\\Definition\\Annotation\\Inject')) { $def['methods'][$methodName] = true; $this->processParams($def, $rClass, $rMethod); continue; } } $methodPatterns = $this->introspectionStrategy->getMethodNameInclusionPatterns(); // matches a method injection pattern? foreach ($methodPatterns as $methodInjectorPattern) { preg_match($methodInjectorPattern, $methodName, $matches); if ($matches) { $def['methods'][$methodName] = false; // check ot see if this is required? $this->processParams($def, $rClass, $rMethod); continue 2; } } // method // by annotation // by setter pattern, // by interface } $interfaceInjectorPatterns = $this->introspectionStrategy->getInterfaceInjectionInclusionPatterns(); // matches the interface injection pattern /** @var $rIface \ReflectionClass */ foreach ($rClass->getInterfaces() as $rIface) { foreach ($interfaceInjectorPatterns as $interfaceInjectorPattern) { preg_match($interfaceInjectorPattern, $rIface->getName(), $matches); if ($matches) { foreach ($rIface->getMethods() as $rMethod) { if ($rMethod->getName() === '__construct') { // ctor not allowed in ifaces continue; } $def['methods'][$rMethod->getName()] = true; $this->processParams($def, $rClass, $rMethod); } continue 2; } } } }
/** * @param string $class * @param bool $forceLoad */ protected function processClass($class, $forceLoad = false) { if (!$forceLoad && $this->hasProcessedClass($class)) { return; } $strategy = $this->introspectionStrategy; // localize for readability /** @var $rClass \Zend\Code\Reflection\ClassReflection */ $rClass = new Reflection\ClassReflection($class); $className = $rClass->getName(); $matches = null; // used for regex below // setup the key in classes $this->classes[$className] = array('supertypes' => array(), 'instantiator' => null, 'methods' => array(), 'parameters' => array()); $def =& $this->classes[$className]; // localize for brevity // class annotations? if ($strategy->getUseAnnotations() == true) { $annotations = $rClass->getAnnotations($strategy->getAnnotationManager()); if ($annotations instanceof AnnotationCollection && $annotations->hasAnnotation('Zend\\Di\\Definition\\Annotation\\Instantiator')) { // @todo Instantiator support in annotations } } $rTarget = $rClass; $supertypes = array(); do { $supertypes = array_merge($supertypes, $rTarget->getInterfaceNames()); if (!($rTargetParent = $rTarget->getParentClass())) { break; } $supertypes[] = $rTargetParent->getName(); $rTarget = $rTargetParent; } while (true); $def['supertypes'] = $supertypes; if ($def['instantiator'] == null) { if ($rClass->isInstantiable()) { $def['instantiator'] = '__construct'; } } if ($rClass->hasMethod('__construct')) { $def['methods']['__construct'] = Di::METHOD_IS_CONSTRUCTOR; // required $this->processParams($def, $rClass, $rClass->getMethod('__construct')); } foreach ($rClass->getMethods(Reflection\MethodReflection::IS_PUBLIC) as $rMethod) { $methodName = $rMethod->getName(); if ($rMethod->getName() === '__construct' || $rMethod->isStatic()) { continue; } if ($strategy->getUseAnnotations() == true) { $annotations = $rMethod->getAnnotations($strategy->getAnnotationManager()); if ($annotations instanceof AnnotationCollection && $annotations->hasAnnotation('Zend\\Di\\Definition\\Annotation\\Inject')) { // use '@inject' and search for parameters $def['methods'][$methodName] = Di::METHOD_IS_EAGER; $this->processParams($def, $rClass, $rMethod); continue; } } $methodPatterns = $this->introspectionStrategy->getMethodNameInclusionPatterns(); // matches a method injection pattern? foreach ($methodPatterns as $methodInjectorPattern) { preg_match($methodInjectorPattern, $methodName, $matches); if ($matches) { $def['methods'][$methodName] = Di::METHOD_IS_OPTIONAL; // check ot see if this is required? $this->processParams($def, $rClass, $rMethod); continue 2; } } // method // by annotation // by setter pattern, // by interface } $interfaceInjectorPatterns = $this->introspectionStrategy->getInterfaceInjectionInclusionPatterns(); // matches the interface injection pattern /** @var $rIface \ReflectionClass */ foreach ($rClass->getInterfaces() as $rIface) { foreach ($interfaceInjectorPatterns as $interfaceInjectorPattern) { preg_match($interfaceInjectorPattern, $rIface->getName(), $matches); if ($matches) { foreach ($rIface->getMethods() as $rMethod) { if ($rMethod->getName() === '__construct' || !count($rMethod->getParameters())) { // constructor not allowed in interfaces // Don't call interface methods without a parameter (Some aware interfaces define setters in ZF2) continue; } $def['methods'][$rMethod->getName()] = Di::METHOD_IS_AWARE; $this->processParams($def, $rClass, $rMethod); } continue 2; } } } }
/** * Find the getter method for a given property in the Data Object class * * @param ClassReflection $class * @param string $camelCaseProperty * @return string processed method name * @throws \Exception If $camelCaseProperty has no corresponding getter method */ protected function _processGetterMethod(ClassReflection $class, $camelCaseProperty) { $getterName = 'get' . $camelCaseProperty; $boolGetterName = 'is' . $camelCaseProperty; if ($class->hasMethod($getterName)) { $methodName = $getterName; } elseif ($class->hasMethod($boolGetterName)) { $methodName = $boolGetterName; } else { throw new \Exception(sprintf('Property :"%s" does not exist in the Data Object class: "%s".', $camelCaseProperty, $class->getName())); } return $methodName; }
/** * Checks if method is defined * * Case sensitivity of the method is taken into account. * * @param ClassReflection $class * @param string $methodName * @return bool */ protected function classHasMethod(ClassReflection $class, $methodName) { return $class->hasMethod($methodName) && $class->getMethod($methodName)->getName() == $methodName; }
/** * Find the setter method name for a property from the given class * * @param ClassReflection $class * @param string $camelCaseProperty * @return string processed method name * @throws \Exception If $camelCaseProperty has no corresponding setter method */ public function findSetterMethodName(ClassReflection $class, $camelCaseProperty) { $setterName = 'set' . $camelCaseProperty; $boolSetterName = 'setIs' . $camelCaseProperty; if ($class->hasMethod($setterName)) { $methodName = $setterName; } elseif ($class->hasMethod($boolSetterName)) { $methodName = $boolSetterName; } else { throw new \Exception(sprintf('Property :"%s" does not exist in the provided class: "%s".', $camelCaseProperty, $class->getName())); } return $methodName; }
/** * Checks if method is defined * * Case sensitivity of the method is taken into account. * * @param ClassReflection $class * @param string $methodName * @return bool */ public function hasMethod(ClassReflection $class, $methodName) { return $class->hasMethod($methodName) && $class->getMethod($methodName)->getName() == $methodName; }