/** * @param stdClass * @param string * @return string|false * @throws AnnotationClassParserException * @throws AnnotationClassParserMorePossibleClassesException */ private function getByReflection(stdClass $r, ReflectionClass $reflection, $defaultClass) { $annotation = $this->parser->getByReflection($reflection); if (isset($annotation[$r->annotation])) { if (count($annotation[$r->annotation]) !== 1) { throw new AnnotationClassParserException('Cannot redeclare ' . $reflection->getName() . '::@' . $r->annotation); } $class = $annotation[$r->annotation][0]; if ($class === false) { $defaultClass = NULL; } else { if (!is_string($class)) { $tmp = gettype($class); throw new AnnotationClassParserException($reflection->getName() . "::@{$r->annotation} expected class name, {$tmp} given"); } if (PHP_VERSION_ID >= 50300 and ($ns = $reflection->getNamespaceName()) !== '' and class_exists($ns . '\\' . $class)) { $class = $ns . '\\' . $class; } else { if (!class_exists($class)) { throw new AnnotationClassParserException($reflection->getName() . "::@{$r->annotation} class '{$class}' not exists"); } } if ($defaultClass and strcasecmp($class, $defaultClass) !== 0) { throw new AnnotationClassParserMorePossibleClassesException('Exists annotation ' . $reflection->getName() . '::@' . $r->annotation . " and fallback '{$defaultClass}'"); } return $class; } } if ($defaultClass) { return $defaultClass; } return $this->getByClassName($r, get_parent_class($reflection->getName())); }
/** * @param IRepository * @param AnnotationsParser */ public function __construct(IRepository $repository, AnnotationsParser $parser) { $reflections = array($reflection = new ReflectionClass($repository)); while ($reflection = $reflection->getParentClass() and $reflection->implementsInterface('Orm\\IRepository')) { $reflections[] = $reflection; } $repoMethods = array_fill_keys(array_map('strtolower', get_class_methods($repository)), true); foreach (array_reverse($reflections) as $reflection) { $annotation = $parser->getByReflection($reflection); if (isset($annotation['method'])) { foreach ($annotation['method'] as $method) { if (preg_match('#^\\s*(?:[^\\s\\(]+\\s+)?([^\\s\\(]+)(?:\\(|\\s|$)#si', $method, $match)) { $method = $match[1]; $lcMethod = strtolower($method); if (isset($this->methods[$lcMethod]) or isset($repoMethods[$lcMethod])) { $class = $reflection->getName(); $repoClass = get_class($repository); $tmp = isset($this->methods[$lcMethod]) ? 'annotation' : 'method'; throw new MapperAutoCallerException("{$class}::@method cannot redeclare {$repoClass}::{$method}(); {$tmp} already exists."); } $this->methods[$lcMethod] = $this->methods[$method] = true; } else { $class = $reflection->getName(); throw new MapperAutoCallerException("{$class}::@method invalid format; '{$method}' given."); } } } } }
/** * Returns phpdoc annotations. * @param string class name * @return array of annotation => array * @see AnnotationsParser */ protected function getAnnotation($class) { return $this->parser->getByReflection(new ReflectionClass($class)); }