Example #1
0
 /**
  * Reflects the given class and stores the results in this service's properties.
  *
  * @param string $className Full qualified name of the class to reflect
  * @return void
  * @throws \TYPO3\FLOW3\Reflection\Exception\InvalidClassException
  */
 protected function reflectClass($className)
 {
     $this->log(sprintf('Reflecting class %s', $className), LOG_DEBUG);
     $className = trim($className, '\\');
     if (strpos($className, 'TYPO3\\FLOW3\\Persistence\\Doctrine\\Proxies') === 0 && array_search('Doctrine\\ORM\\Proxy\\Proxy', class_implements($className))) {
         // Somebody tried to reflect a doctrine proxy, which will have severe side effects.
         // see bug http://forge.typo3.org/issues/29449 for details.
         throw new Exception\InvalidClassException('The class with name "' . $className . '" is a Doctrine proxy. It is not supported to reflect doctrine proxy classes.', 1314944681);
     }
     $class = new ClassReflection($className);
     if (!isset($this->classReflectionData[$className])) {
         $this->classReflectionData[$className] = array();
     }
     if ($class->isAbstract()) {
         $this->classReflectionData[$className][self::DATA_CLASS_ABSTRACT] = TRUE;
     }
     if ($class->isFinal()) {
         $this->classReflectionData[$className][self::DATA_CLASS_FINAL] = TRUE;
     }
     foreach ($this->getParentClasses($class) as $parentClass) {
         $parentClassName = $parentClass->getName();
         if (!isset($this->classReflectionData[$parentClassName])) {
             $this->reflectClass($parentClassName);
         }
         $this->classReflectionData[$parentClassName][self::DATA_CLASS_SUBCLASSES][$className] = TRUE;
     }
     foreach ($class->getInterfaces() as $interface) {
         if (!isset($this->classReflectionData[$className][self::DATA_CLASS_ABSTRACT])) {
             $interfaceName = $interface->getName();
             if (!isset($this->classReflectionData[$interfaceName])) {
                 $this->reflectClass($interfaceName);
             }
             $this->classReflectionData[$interfaceName][self::DATA_INTERFACE_IMPLEMENTATIONS][$className] = TRUE;
         }
     }
     foreach ($this->annotationReader->getClassAnnotations($class) as $annotation) {
         $annotationClassName = get_class($annotation);
         $this->annotatedClasses[$annotationClassName][$className] = TRUE;
         $this->classReflectionData[$className][self::DATA_CLASS_ANNOTATIONS][] = $annotation;
     }
     foreach ($class->getProperties() as $property) {
         $propertyName = $property->getName();
         $this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName] = array();
         $visibility = $property->isPublic() ? self::VISIBILITY_PUBLIC : ($property->isProtected() ? self::VISIBILITY_PROTECTED : self::VISIBILITY_PRIVATE);
         $this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName][self::DATA_PROPERTY_VISIBILITY] = $visibility;
         foreach ($property->getTagsValues() as $tag => $values) {
             if (array_search($tag, $this->settings['reflection']['ignoredTags']) === FALSE) {
                 $this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName][self::DATA_PROPERTY_TAGS_VALUES][$tag] = $values;
             }
         }
         foreach ($this->annotationReader->getPropertyAnnotations($property, $propertyName) as $annotation) {
             $this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName][self::DATA_PROPERTY_ANNOTATIONS][get_class($annotation)][] = $annotation;
         }
     }
     foreach ($class->getMethods() as $method) {
         $methodName = $method->getName();
         if ($method->isFinal()) {
             $this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_FINAL] = TRUE;
         }
         if ($method->isStatic()) {
             $this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_STATIC] = TRUE;
         }
         $visibility = $method->isPublic() ? self::VISIBILITY_PUBLIC : ($method->isProtected() ? self::VISIBILITY_PROTECTED : self::VISIBILITY_PRIVATE);
         $this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_VISIBILITY] = $visibility;
         foreach ($this->getMethodAnnotations($className, $methodName) as $methodAnnotation) {
             $this->classesByMethodAnnotations[get_class($methodAnnotation)][$className] = $methodName;
         }
         $paramAnnotations = $method->isTaggedWith('param') ? $method->getTagValues('param') : array();
         foreach ($method->getParameters() as $parameter) {
             $this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_PARAMETERS][$parameter->getName()] = $this->convertParameterReflectionToArray($parameter, $method);
             if ($this->settings['reflection']['logIncorrectDocCommentHints'] === TRUE) {
                 if (isset($paramAnnotations[$parameter->getPosition()])) {
                     $parameterAnnotation = explode(' ', $paramAnnotations[$parameter->getPosition()], 3);
                     if (count($parameterAnnotation) < 2) {
                         $this->log('  Wrong @param use for "' . $method->getName() . '::' . $parameter->getName() . '": "' . implode(' ', $parameterAnnotation) . '"', LOG_DEBUG);
                     } else {
                         if (isset($this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_PARAMETERS][$parameter->getName()][self::DATA_PARAMETER_TYPE]) && $this->classReflectionData[$className][self::DATA_CLASS_METHODS][$methodName][self::DATA_METHOD_PARAMETERS][$parameter->getName()][self::DATA_PARAMETER_TYPE] !== ltrim($parameterAnnotation[0], '\\')) {
                             $this->log('  Wrong type in @param for "' . $method->getName() . '::' . $parameter->getName() . '": "' . $parameterAnnotation[0] . '"', LOG_DEBUG);
                         }
                         if ($parameter->getName() !== ltrim($parameterAnnotation[1], '$&')) {
                             $this->log('  Wrong name in @param for "' . $method->getName() . '::$' . $parameter->getName() . '": "' . $parameterAnnotation[1] . '"', LOG_DEBUG);
                         }
                     }
                 } else {
                     $this->log('  Missing @param for "' . $method->getName() . '::$' . $parameter->getName(), LOG_DEBUG);
                 }
             }
         }
     }
     // Sort reflection data so that the cache data is deterministic. This is
     // important for comparisons when checking if classes have changed in a
     // Development context.
     ksort($this->classReflectionData);
     $this->updatedReflectionData[$className] = TRUE;
 }
Example #2
0
 /**
  * @test
  */
 public function proxiedMethodsDoContainAnnotationsOnlyOnce()
 {
     $class = new ClassReflection('TYPO3\\FLOW3\\Tests\\Functional\\Object\\Fixtures\\PrototypeClassA');
     $method = $class->getMethod('setSomeProperty');
     $this->assertEquals(array('autoStart=true'), $method->getTagValues('session'));
 }
Example #3
0
 /**
  * Finds all parent classes of the given class
  *
  * @param \TYPO3\FLOW3\Reflection\ClassReflection $class The class to reflect
  * @param array $parentClasses Array of parent classes
  * @return array<\TYPO3\FLOW3\Reflection\ClassReflection>
  */
 protected function getParentClasses(\TYPO3\FLOW3\Reflection\ClassReflection $class, array $parentClasses = array())
 {
     $parentClass = $class->getParentClass();
     if ($parentClass !== FALSE) {
         $parentClasses[] = $parentClass;
         $parentClasses = $this->getParentClasses($parentClass, $parentClasses);
     }
     return $parentClasses;
 }