/** * Parses class annotation and build metadata object * * @param Nette\Reflection\ClassType $reflection * @throws vBuilder\InvalidAnnotationException if any annotation is missing or bad formed */ public function __construct(Nette\Reflection\ClassType $reflection) { // Nazev tabulky $annotations = $reflection->getAnnotations(); if (isset($annotations['Table']) && isset($annotations['Table'][0]['name'])) { $this->tableName = $annotations['Table'][0]['name']; } // Entitni chovani if (isset($annotations['Behavior'])) { foreach ($annotations['Behavior'] as $curr) { if (!is_array($curr) && !$curr instanceof \Traversable) { $this->behaviors[$curr] = array(); continue; } $curr = (array) $curr; $this->behaviors[array_shift($curr)] = $curr; } } // Sloupecky if (isset($annotations['Column'])) { foreach ($annotations['Column'] as $curr) { // Prazdne definice if ($curr === true) { continue; } if (!is_array($curr) && !$curr instanceof \Traversable) { $this->fields[$curr] = array(); continue; } $curr = (array) $curr; $name = array_shift($curr); $this->fields[$name] = array(); foreach ($curr as $k => $v) { if (is_numeric($k)) { $this->fields[$name][$v] = true; } else { $this->fields[$name][$k] = $v; } } if (isset($this->fields[$name]['id']) || isset($this->fields[$name]['pk'])) { $this->idFields[] = $name; } } } }
protected function getRepositoryList($modelClass) { $modelReflection = new ClassType($modelClass); $builder = $this->getContainerBuilder(); $builder->addDependency($modelReflection->getFileName()); $repositories = []; foreach ($modelReflection->getAnnotations() as $key => $annotations) { if ($key !== 'property-read') { continue; } foreach ($annotations as $annotation) { list($class, $name) = preg_split('#\\s+#', $annotation); $class = AnnotationsParser::expandClassName($class, $modelReflection); if (!class_exists($class)) { throw new RuntimeException("Repository '{$class}' does not exist."); } $repositories[ltrim($name, '$')] = $class; } } return $repositories; }
protected function getRepositoryList($modelClass) { $modelReflection = new ClassType($modelClass); $builder = $this->getContainerBuilder(); $builder->addDependency($modelReflection->getFileName()); $repositories = []; foreach ($modelReflection->getAnnotations() as $key => $annotations) { if ($key !== 'property-read') { continue; } foreach ($annotations as $annotation) { list($class, $name) = preg_split('#\\s+#', $annotation); $class = AnnotationsParser::expandClassName($class, $modelReflection); if (!class_exists($class)) { throw new RuntimeException("Class repository '{$class}' does not exist."); } $repositories[] = ['name' => ltrim($name, '$'), 'serviceName' => $this->prefix('repositories.' . ltrim($name, '$')), 'class' => $class, 'entities' => call_user_func([$class, 'getEntityClassNames'])]; } } return $repositories; }
protected function parseAnnotations(ClassType $reflection) { foreach ($reflection->getAnnotations() as $annotation => $values) { if ($annotation === 'property') { $access = PropertyMetadata::READWRITE; } elseif ($annotation === 'property-read') { $access = PropertyMetadata::READ; } else { continue; } foreach ($values as $value) { $splitted = preg_split('#\\s+#', $value, 3); if (count($splitted) < 2 || $splitted[1][0] !== '$') { throw new InvalidArgumentException("Annotation syntax error '{$value}'."); } $name = substr($splitted[1], 1); $types = $this->parseAnnotationTypes($splitted[0], $reflection); if ($access === PropertyMetadata::READWRITE) { $this->storageProperties[$name] = TRUE; } $this->parseAnnotationValue($name, $types, $access, isset($splitted[2]) ? $splitted[2] : NULL); } } }
protected function parseAnnotations(ClassType $reflection) { foreach ($reflection->getAnnotations() as $annotation => $values) { if ($annotation === 'property') { $isReadonly = false; } elseif ($annotation === 'property-read') { $isReadonly = true; } else { continue; } foreach ($values as $value) { $splitted = preg_split('#\\s+#', $value, 3); if (count($splitted) < 2 || $splitted[1][0] !== '$') { throw new InvalidArgumentException("Annotation syntax error '{$value}'."); } $property = new PropertyMetadata(); $property->name = substr($splitted[1], 1); $property->isReadonly = $isReadonly; $this->metadata->setProperty($property->name, $property); $this->parseAnnotationTypes($property, $splitted[0]); $this->parseAnnotationValue($property, isset($splitted[2]) ? $splitted[2] : null); } } }
/** * @return array|\Nette\Reflection\IAnnotation[] */ public function getAnnotations() { if ($this->annotations == NULL) { $reflection = new ClassType(get_called_class()); $annotations = $reflection->getAnnotations(); $this->annotations = $annotations; } return $this->annotations; }
/** * Parse class and returns names and target classes of annotated properties * @param $className * @return mixed * @throws RestException */ public function getAnnotatedProperties($className) { if (!isset($this->classProperties[$className])) { $this->classProperties[$className] = array(); $ref = new ClassType($className); if ($ref->isAbstract() or $ref->isInterface()) { throw new RestException("Class can not be either abstract nor interface"); } $ann = $ref->getAnnotations(); $parents = class_parents($className); $parents[$className] = $className; if ($className != DataHash::class and (!$parents or !in_array(DataHash::class, $parents))) { throw RestException::notInheritedForm($className, DataHash::class); } $this->parseProperties($ref, $ann, 'property'); $this->parseProperties($ref, $ann, 'property-read'); } return $this->classProperties[$className]; }
/** * @return mixed[][] */ private static function getMetadata() { $className = get_called_class(); if (!isset(self::$metadata[$className])) { self::$metadata[$className] = array(); $classReflection = new ClassType($className); $annotations = $classReflection->getAnnotations(); self::$metadata[$className] += self::parseMetadataFromAnnotation($annotations, 'property', true, true); self::$metadata[$className] += self::parseMetadataFromAnnotation($annotations, 'property-read', true, false); self::$metadata[$className] += self::parseMetadataFromAnnotation($annotations, 'property-write', false, true); } return self::$metadata[$className]; }