/** * Return a single property by given name or index of info * * @param string|int $propertyNameOrInfoIndex * @throws Exception\InvalidArgumentException * @return bool|PropertyScanner */ public function getProperty($propertyNameOrInfoIndex) { $this->scan(); if (is_int($propertyNameOrInfoIndex)) { $info = $this->infos[$propertyNameOrInfoIndex]; if ($info['type'] != 'property') { throw new Exception\InvalidArgumentException('Index of info offset is not about a property'); } } elseif (is_string($propertyNameOrInfoIndex)) { $propertyFound = false; foreach ($this->infos as $info) { if ($info['type'] === 'property' && $info['name'] === $propertyNameOrInfoIndex) { $propertyFound = true; break; } } if (!$propertyFound) { return false; } } else { throw new Exception\InvalidArgumentException('Invalid property name of info index type. Must be of type int or string'); } if (!isset($info)) { return false; } $p = new PropertyScanner(array_slice($this->tokens, $info['tokenStart'], $info['tokenEnd'] - $info['tokenStart'] + 1), $this->nameInformation); $p->setClass($this->name); $p->setScannerClass($this); return $p; }
/** * @param Annotation\OneToMany $annotation * @param PropertyScanner $propertyScanner * @param ClassScanner $classScanner * @param ClassScanner[] $allClassScanners * @return array * @throws Exception\RuntimeException */ protected function handleOneToManyAnnotation(Annotation\OneToMany $annotation, PropertyScanner $propertyScanner, ClassScanner $classScanner, array $allClassScanners) { $targetEntity = $annotation->getTargetEntity(); $propertyArr = array(); $propertyArr['name'] = $propertyScanner->getName(); $propertyArr['field'] = $annotation->getName(); $propertyArr['extractor'] = $this->buildFieldExtractor($annotation->getName(), $annotation->isContainer()); $propertyArr['serializer'] = $this->buildFieldSerializer($annotation->getName(), false, $annotation->isContainer()); $propertyArr['handler'] = $this->detectPropertyAdd($classScanner, $propertyScanner); $propertyArr['getter'] = $this->detectPropertyGet($classScanner, $propertyScanner); $propertyArr['isContainer'] = $annotation->isContainer(); $ref = new \ReflectionClass($classScanner->getName()); if (!$ref->newInstance()->{$propertyArr['getter']}() instanceof \SplObjectStorage) { throw new RuntimeException("Invalid data type returned from getter in OneToMany relationship,\n must return SplObjectStorage"); } /* @var $scanner ClassScanner */ foreach ($allClassScanners as $scanner) { if ($scanner->getName() == $targetEntity) { if (!($params = $this->collectDataForClass($scanner, $allClassScanners))) { throw new RuntimeException("Invalid data type for collectDataForClass"); } $propertyArr['targetEntity'] = new ClassMetadata($params); return $propertyArr; } } throw new RuntimeException("Invalid targetEntity this Entity could not be found by entity scanner"); }