/** * @param string * @param string|NULL * @return object * @throws ServiceNotFoundException * @throws InvalidServiceFactoryException * @throws ServiceNotInstanceOfException if $instanceof not match with service */ public function getService($name, $instanceof = NULL) { $this->hasService($name, true); $s = $this->services[$name]; if ($s->service === NULL) { if (is_string($s->factory) and !(strpos($s->factory, '::') or strncmp($s->factory, "lambda_", 8) === 0)) { $s->service = new $s->factory(); unset($s->factory); } else { if (Callback::is($s->factory) or $s->factory instanceof Closure or is_string($s->factory) or is_array($s->factory)) { $tmp = Callback::create($s->factory)->invoke($this); if (!is_object($tmp)) { $tmp = gettype($tmp); throw new InvalidServiceFactoryException("Factory for service '{$name}' returns invalid result. Object expected, {$tmp} given."); } $s->service = $tmp; unset($s->factory); } else { if (is_object($s->factory)) { $s->service = $s->factory; unset($s->factory); } else { $tmp = gettype($s->factory); throw new InvalidServiceFactoryException("Service '{$name}' has invalid factory. Callback, class name or object expected, {$tmp} given."); } } } } if ($instanceof !== NULL and !$s->service instanceof $instanceof) { throw new ServiceNotInstanceOfException("Service '{$name}' is not instance of '{$instanceof}'."); } return $s->service; }
/** * @see self::create() * @param mixed class, object, function, callback * @param string method */ protected function __construct($t, $m = NULL) { if ($m === NULL) { if (is_string($t)) { $t = explode('::', $t, 2); $this->cb = isset($t[1]) ? $t : $t[0]; } else { if (is_object($t)) { if ($t instanceof Closure) { $this->cb = $t; } else { if (Callback::is($t)) { $this->cb = $t->getNative(); } else { $this->cb = array($t, '__invoke'); } } } else { $this->cb = $t; } } } else { $this->cb = array($t, $m); } if (!is_callable($this->cb, TRUE)) { throw new InvalidArgumentException("Invalid callback."); } }
/** * <code> * $p->register('mapper', 'Orm\IRepository', function ($repositoryClass) { * return $repositoryClass . 'Mapper'; * }); * </code> * * @param string * @param string interface name * @param Callback|Closure|NULL * @return AnnotationClassParser * @throws AnnotationClassParserException */ public function register($annotation, $interface, $defaultClassFallback = NULL) { if (isset($this->registered[$annotation])) { throw new AnnotationClassParserException("Parser '{$annotation}' is already registered"); } if (!interface_exists($interface)) { throw new AnnotationClassParserException("'{$interface}' is not valid interface"); } if ($defaultClassFallback !== NULL and !is_callable($defaultClassFallback) and !Callback::is($defaultClassFallback)) { $tmp = is_string($defaultClassFallback) ? $defaultClassFallback : (is_object($defaultClassFallback) ? get_class($defaultClassFallback) : gettype($defaultClassFallback)); throw new AnnotationClassParserException("'{$tmp}' is not valid callback"); } $tmp = (object) array('annotation' => $annotation, 'interface' => $interface, 'defaultClassFallback' => $defaultClassFallback, 'cache' => array()); $this->registered[$annotation] = $tmp; return $this; }
/** * Inject same class around value in entity. * * <code> * $entity->foo = array('bar'); // call ArrayInjection::setInjectedValue(array('bar')) * $entity->foo implements ArrayInjection; * * $repo->persist($entity) // call ArrayInjection::getInjectedValue() * </code> * * Type must by class implements IEntityInjection. * @param Callback|Closure|string|IEntityInjectionLoader|NULL * null mean load from IEntityInjectionStaticLoader which is specify in type * @return MetaDataProperty $this * @see AnnotationMetaData::builtParamsInjection() */ public function setInjection($factory = NULL) { if (isset($this->data['injection'])) { throw new MetaDataException("Already has injection in {$this->class}::\${$this->name}"); } $class = $this->originalTypes; if (count($this->data['types']) != 1) { throw new MetaDataException("Injection expecte type as one class implements Orm\\IInjection, '{$class}' given in {$this->class}::\${$this->name}"); } if (!class_exists($class)) { throw new MetaDataException("Injection expecte type as class implements Orm\\IInjection, '{$class}' given in {$this->class}::\${$this->name}"); } $reflection = new ReflectionClass($class); $class = $reflection->getName(); if (!$reflection->implementsInterface('Orm\\IEntityInjection')) { throw new MetaDataException("{$class} does not implements Orm\\IEntityInjection in {$this->class}::\${$this->name}"); } if (!$reflection->isInstantiable()) { throw new MetaDataException("{$class} is abstract or not instantiable in {$this->class}::\${$this->name}"); } if ($factory instanceof IEntityInjectionLoader) { $factory = Callback::create($factory, 'create'); } else { if (Callback::is($factory) or $factory instanceof Closure or is_string($factory) and (strpos($factory, '::') or strncmp($factory, "lambda_", 8) === 0)) { $factory = Callback::create($factory); } else { if (!$factory and $reflection->implementsInterface('Orm\\IEntityInjectionStaticLoader')) { $factory = Callback::create($class, 'create'); } else { if (!$factory) { throw new MetaDataException("There is not factory callback for injection in {$this->class}::\${$this->name}, specify one or use Orm\\IEntityInjectionStaticLoader"); } $tmp = is_object($factory) ? get_class($factory) : (is_string($factory) ? $factory : gettype($factory)); throw new MetaDataException("Injection expected valid callback, '{$tmp}' given in {$this->class}::\${$this->name}, specify one or use Orm\\IEntityInjectionStaticLoader"); } } } $this->data['injection'] = InjectionFactory::create($factory, $class); return $this; }