Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Di / Definition / RuntimeDefinition.php
blob8d685994492d938a92362477d335416726867dd2
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Di\Definition;
12 use Zend\Code\Annotation\AnnotationCollection;
13 use Zend\Code\Reflection;
14 use Zend\Di\Definition\Annotation;
15 use Zend\Di\Di;
17 /**
18 * Class definitions based on runtime reflection
20 class RuntimeDefinition implements DefinitionInterface
23 /**
24 * @var array
26 protected $classes = array();
28 /**
29 * @var bool
31 protected $explicitLookups = false;
33 /**
34 * @var IntrospectionStrategy
36 protected $introspectionStrategy = null;
38 /**
39 * @var array
41 protected $injectionMethods = array();
43 /**
44 * Constructor
46 * @param null|IntrospectionStrategy $introspectionStrategy
47 * @param array|null $explicitClasses
49 public function __construct(IntrospectionStrategy $introspectionStrategy = null, array $explicitClasses = null)
51 $this->introspectionStrategy = ($introspectionStrategy) ?: new IntrospectionStrategy();
52 if ($explicitClasses) {
53 $this->setExplicitClasses($explicitClasses);
57 /**
58 * @param IntrospectionStrategy $introspectionStrategy
59 * @return void
61 public function setIntrospectionStrategy(IntrospectionStrategy $introspectionStrategy)
63 $this->introspectionStrategy = $introspectionStrategy;
66 /**
67 * @return IntrospectionStrategy
69 public function getIntrospectionStrategy()
71 return $this->introspectionStrategy;
74 /**
75 * Set explicit classes
77 * @param array $explicitClasses
79 public function setExplicitClasses(array $explicitClasses)
81 $this->explicitLookups = true;
82 foreach ($explicitClasses as $eClass) {
83 $this->classes[$eClass] = true;
85 $this->classes = $explicitClasses;
88 /**
89 * @param string $class
91 public function forceLoadClass($class)
93 $this->processClass($class);
96 /**
97 * {@inheritDoc}
99 public function getClasses()
101 return array_keys($this->classes);
105 * {@inheritDoc}
107 public function hasClass($class)
109 if ($this->explicitLookups === true) {
110 return (array_key_exists($class, $this->classes));
113 return class_exists($class) || interface_exists($class);
117 * {@inheritDoc}
119 public function getClassSupertypes($class)
121 if (!array_key_exists($class, $this->classes)) {
122 $this->processClass($class);
125 return $this->classes[$class]['supertypes'];
129 * {@inheritDoc}
131 public function getInstantiator($class)
133 if (!array_key_exists($class, $this->classes)) {
134 $this->processClass($class);
137 return $this->classes[$class]['instantiator'];
141 * {@inheritDoc}
143 public function hasMethods($class)
145 if (!array_key_exists($class, $this->classes)) {
146 $this->processClass($class);
149 return (count($this->classes[$class]['methods']) > 0);
153 * {@inheritDoc}
155 public function hasMethod($class, $method)
157 if (!array_key_exists($class, $this->classes)) {
158 $this->processClass($class);
161 return isset($this->classes[$class]['methods'][$method]);
165 * {@inheritDoc}
167 public function getMethods($class)
169 if (!array_key_exists($class, $this->classes)) {
170 $this->processClass($class);
173 return $this->classes[$class]['methods'];
177 * {@inheritDoc}
179 public function hasMethodParameters($class, $method)
181 if (!isset($this->classes[$class])) {
182 return false;
185 return (array_key_exists($method, $this->classes[$class]['parameters']));
189 * {@inheritDoc}
191 public function getMethodParameters($class, $method)
193 if (!is_array($this->classes[$class])) {
194 $this->processClass($class);
197 return $this->classes[$class]['parameters'][$method];
201 * @param string $class
203 protected function processClass($class)
205 $strategy = $this->introspectionStrategy; // localize for readability
207 /** @var $rClass \Zend\Code\Reflection\ClassReflection */
208 $rClass = new Reflection\ClassReflection($class);
209 $className = $rClass->getName();
210 $matches = null; // used for regex below
212 // setup the key in classes
213 $this->classes[$className] = array(
214 'supertypes' => array(),
215 'instantiator' => null,
216 'methods' => array(),
217 'parameters' => array()
220 $def = &$this->classes[$className]; // localize for brevity
222 // class annotations?
223 if ($strategy->getUseAnnotations() == true) {
224 $annotations = $rClass->getAnnotations($strategy->getAnnotationManager());
226 if (($annotations instanceof AnnotationCollection)
227 && $annotations->hasAnnotation('Zend\Di\Definition\Annotation\Instantiator')) {
228 // @todo Instantiator support in annotations
232 $rTarget = $rClass;
233 $supertypes = array();
234 do {
235 $supertypes = array_merge($supertypes, $rTarget->getInterfaceNames());
236 if (!($rTargetParent = $rTarget->getParentClass())) {
237 break;
239 $supertypes[] = $rTargetParent->getName();
240 $rTarget = $rTargetParent;
241 } while (true);
243 $def['supertypes'] = $supertypes;
245 if ($def['instantiator'] == null) {
246 if ($rClass->isInstantiable()) {
247 $def['instantiator'] = '__construct';
251 if ($rClass->hasMethod('__construct')) {
252 $def['methods']['__construct'] = Di::METHOD_IS_CONSTRUCTOR; // required
253 $this->processParams($def, $rClass, $rClass->getMethod('__construct'));
256 foreach ($rClass->getMethods(Reflection\MethodReflection::IS_PUBLIC) as $rMethod) {
258 $methodName = $rMethod->getName();
260 if ($rMethod->getName() === '__construct' || $rMethod->isStatic()) {
261 continue;
264 if ($strategy->getUseAnnotations() == true) {
265 $annotations = $rMethod->getAnnotations($strategy->getAnnotationManager());
267 if (($annotations instanceof AnnotationCollection)
268 && $annotations->hasAnnotation('Zend\Di\Definition\Annotation\Inject')) {
270 // use '@inject' and search for parameters
271 $def['methods'][$methodName] = Di::METHOD_IS_EAGER;
272 $this->processParams($def, $rClass, $rMethod);
273 continue;
277 $methodPatterns = $this->introspectionStrategy->getMethodNameInclusionPatterns();
279 // matches a method injection pattern?
280 foreach ($methodPatterns as $methodInjectorPattern) {
281 preg_match($methodInjectorPattern, $methodName, $matches);
282 if ($matches) {
283 $def['methods'][$methodName] = Di::METHOD_IS_OPTIONAL; // check ot see if this is required?
284 $this->processParams($def, $rClass, $rMethod);
285 continue 2;
289 // method
290 // by annotation
291 // by setter pattern,
292 // by interface
296 $interfaceInjectorPatterns = $this->introspectionStrategy->getInterfaceInjectionInclusionPatterns();
298 // matches the interface injection pattern
299 /** @var $rIface \ReflectionClass */
300 foreach ($rClass->getInterfaces() as $rIface) {
301 foreach ($interfaceInjectorPatterns as $interfaceInjectorPattern) {
302 preg_match($interfaceInjectorPattern, $rIface->getName(), $matches);
303 if ($matches) {
304 foreach ($rIface->getMethods() as $rMethod) {
305 if (($rMethod->getName() === '__construct') || !count($rMethod->getParameters())) {
306 // constructor not allowed in interfaces
307 // Don't call interface methods without a parameter (Some aware interfaces define setters in ZF2)
308 continue;
310 $def['methods'][$rMethod->getName()] = Di::METHOD_IS_AWARE;
311 $this->processParams($def, $rClass, $rMethod);
313 continue 2;
320 * @param array $def
321 * @param \Zend\Code\Reflection\ClassReflection $rClass
322 * @param \Zend\Code\Reflection\MethodReflection $rMethod
324 protected function processParams(&$def, Reflection\ClassReflection $rClass, Reflection\MethodReflection $rMethod)
326 if (count($rMethod->getParameters()) === 0) {
327 return;
330 $methodName = $rMethod->getName();
332 // @todo annotations here for alternate names?
334 $def['parameters'][$methodName] = array();
336 foreach ($rMethod->getParameters() as $p) {
338 /** @var $p \ReflectionParameter */
339 $actualParamName = $p->getName();
341 $fqName = $rClass->getName() . '::' . $rMethod->getName() . ':' . $p->getPosition();
343 $def['parameters'][$methodName][$fqName] = array();
345 // set the class name, if it exists
346 $def['parameters'][$methodName][$fqName][] = $actualParamName;
347 $def['parameters'][$methodName][$fqName][] = ($p->getClass() !== null) ? $p->getClass()->getName() : null;
348 $def['parameters'][$methodName][$fqName][] = !($optional = $p->isOptional() && $p->isDefaultValueAvailable());
349 $def['parameters'][$methodName][$fqName][] = $optional ? $p->getDefaultValue() : null;