getMethodAnnotations() public method

Returns the specified method annotations or an empty array
public getMethodAnnotations ( string $className, string $methodName, string $annotationClassName = null ) : array
$className string Name of the class
$methodName string Name of the method
$annotationClassName string Annotation to filter for
return array
 /**
  * Checks if the specified method matches with the method annotation filter pattern
  *
  * @param string $className Name of the class to check against - not used here
  * @param string $methodName Name of the method
  * @param string $methodDeclaringClassName Name of the class the method was originally declared in
  * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection - not used here
  * @return boolean TRUE if the class matches, otherwise FALSE
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     if ($methodDeclaringClassName === null || !method_exists($methodDeclaringClassName, $methodName)) {
         return false;
     }
     $designatedAnnotations = $this->reflectionService->getMethodAnnotations($methodDeclaringClassName, $methodName, $this->annotation);
     if ($designatedAnnotations !== [] || $this->annotationValueConstraints === []) {
         $matches = $designatedAnnotations !== [];
     } else {
         // It makes no sense to check property values for an annotation that is used multiple times, we shortcut and check the value against the first annotation found.
         $firstFoundAnnotation = $designatedAnnotations;
         $annotationProperties = $this->reflectionService->getClassPropertyNames($this->annotation);
         foreach ($this->annotationValueConstraints as $propertyName => $expectedValue) {
             if (!array_key_exists($propertyName, $annotationProperties)) {
                 $this->systemLogger->log('The property "' . $propertyName . '" declared in pointcut does not exist in annotation ' . $this->annotation, LOG_NOTICE);
                 return false;
             }
             if ($firstFoundAnnotation->{$propertyName} === $expectedValue) {
                 $matches = true;
             } else {
                 return false;
             }
         }
     }
     return $matches;
 }
コード例 #2
0
 /**
  * Builds the method documentation block for the specified method keeping the vital annotations
  *
  * @param string $className Name of the class the method is declared in
  * @param string $methodName Name of the method to create the parameters code for
  * @return string $methodDocumentation DocComment for the given method
  */
 protected function buildMethodDocumentation($className, $methodName)
 {
     $methodDocumentation = "    /**\n     * Autogenerated Proxy Method\n";
     if ($this->reflectionService->hasMethod($className, $methodName)) {
         $methodTags = $this->reflectionService->getMethodTagsValues($className, $methodName);
         $allowedTags = ['param', 'return', 'throws'];
         foreach ($methodTags as $tag => $values) {
             if (in_array($tag, $allowedTags)) {
                 if (count($values) === 0) {
                     $methodDocumentation .= '     * @' . $tag . "\n";
                 } else {
                     foreach ($values as $value) {
                         $methodDocumentation .= '     * @' . $tag . ' ' . $value . "\n";
                     }
                 }
             }
         }
         $methodAnnotations = $this->reflectionService->getMethodAnnotations($className, $methodName);
         foreach ($methodAnnotations as $annotation) {
             $methodDocumentation .= '     * ' . Compiler::renderAnnotation($annotation) . "\n";
         }
     }
     $methodDocumentation .= "     */\n";
     return $methodDocumentation;
 }
コード例 #3
0
 /**
  * Detects and registers any validators for arguments:
  * - by the data type specified in the param annotations
  * - additional validators specified in the validate annotations of a method
  *
  * @param string $className
  * @param string $methodName
  * @param array $methodParameters Optional pre-compiled array of method parameters
  * @param array $methodValidateAnnotations Optional pre-compiled array of validate annotations (as array)
  * @return array An Array of ValidatorConjunctions for each method parameters.
  * @throws Exception\InvalidValidationConfigurationException
  * @throws Exception\NoSuchValidatorException
  * @throws Exception\InvalidTypeHintException
  */
 public function buildMethodArgumentsValidatorConjunctions($className, $methodName, array $methodParameters = null, array $methodValidateAnnotations = null)
 {
     $validatorConjunctions = [];
     if ($methodParameters === null) {
         $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName);
     }
     if (count($methodParameters) === 0) {
         return $validatorConjunctions;
     }
     foreach ($methodParameters as $parameterName => $methodParameter) {
         $validatorConjunction = $this->createValidator(ConjunctionValidator::class);
         if (!array_key_exists('type', $methodParameter)) {
             throw new Exception\InvalidTypeHintException('Missing type information, probably no @param annotation for parameter "$' . $parameterName . '" in ' . $className . '->' . $methodName . '()', 1281962564);
         }
         if (strpos($methodParameter['type'], '\\') === false) {
             $typeValidator = $this->createValidator($methodParameter['type']);
         } else {
             $typeValidator = null;
         }
         if ($typeValidator !== null) {
             $validatorConjunction->addValidator($typeValidator);
         }
         $validatorConjunctions[$parameterName] = $validatorConjunction;
     }
     if ($methodValidateAnnotations === null) {
         $validateAnnotations = $this->reflectionService->getMethodAnnotations($className, $methodName, Flow\Validate::class);
         $methodValidateAnnotations = array_map(function ($validateAnnotation) {
             return ['type' => $validateAnnotation->type, 'options' => $validateAnnotation->options, 'argumentName' => $validateAnnotation->argumentName];
         }, $validateAnnotations);
     }
     foreach ($methodValidateAnnotations as $annotationParameters) {
         $newValidator = $this->createValidator($annotationParameters['type'], $annotationParameters['options']);
         if ($newValidator === null) {
             throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Could not resolve class name for  validator "' . $annotationParameters['type'] . '".', 1239853109);
         }
         if (isset($validatorConjunctions[$annotationParameters['argumentName']])) {
             $validatorConjunctions[$annotationParameters['argumentName']]->addValidator($newValidator);
         } elseif (strpos($annotationParameters['argumentName'], '.') !== false) {
             $objectPath = explode('.', $annotationParameters['argumentName']);
             $argumentName = array_shift($objectPath);
             $validatorConjunctions[$argumentName]->addValidator($this->buildSubObjectValidator($objectPath, $newValidator));
         } else {
             throw new Exception\InvalidValidationConfigurationException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Validator specified for argument name "' . $annotationParameters['argumentName'] . '", but this argument does not exist.', 1253172726);
         }
     }
     return $validatorConjunctions;
 }
コード例 #4
0
 /**
  * Creates and returns an aspect from the annotations found in a class which
  * is tagged as an aspect. The object acting as an advice will already be
  * fetched (and therefore instantiated if necessary).
  *
  * @param  string $aspectClassName Name of the class which forms the aspect, contains advices etc.
  * @return mixed The aspect container containing one or more advisors or FALSE if no container could be built
  * @throws Aop\Exception
  */
 protected function buildAspectContainer($aspectClassName)
 {
     $aspectContainer = new AspectContainer($aspectClassName);
     $methodNames = get_class_methods($aspectClassName);
     foreach ($methodNames as $methodName) {
         foreach ($this->reflectionService->getMethodAnnotations($aspectClassName, $methodName) as $annotation) {
             $annotationClass = get_class($annotation);
             switch ($annotationClass) {
                 case Flow\Around::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $advice = new Aop\Advice\AroundAdvice($aspectClassName, $methodName);
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                     $advisor = new Aop\Advisor($advice, $pointcut);
                     $aspectContainer->addAdvisor($advisor);
                     break;
                 case Flow\Before::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $advice = new Aop\Advice\BeforeAdvice($aspectClassName, $methodName);
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                     $advisor = new Aop\Advisor($advice, $pointcut);
                     $aspectContainer->addAdvisor($advisor);
                     break;
                 case Flow\AfterReturning::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $advice = new Aop\Advice\AfterReturningAdvice($aspectClassName, $methodName);
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                     $advisor = new Aop\Advisor($advice, $pointcut);
                     $aspectContainer->addAdvisor($advisor);
                     break;
                 case Flow\AfterThrowing::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $advice = new Aop\Advice\AfterThrowingAdvice($aspectClassName, $methodName);
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                     $advisor = new Aop\Advisor($advice, $pointcut);
                     $aspectContainer->addAdvisor($advisor);
                     break;
                 case Flow\After::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $advice = new Aop\Advice\AfterAdvice($aspectClassName, $methodName);
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                     $advisor = new Aop\Advisor($advice, $pointcut);
                     $aspectContainer->addAdvisor($advisor);
                     break;
                 case Flow\Pointcut::class:
                     $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->expression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass));
                     $pointcut = new Aop\Pointcut\Pointcut($annotation->expression, $pointcutFilterComposite, $aspectClassName, $methodName);
                     $aspectContainer->addPointcut($pointcut);
                     break;
             }
         }
     }
     $introduceAnnotation = $this->reflectionService->getClassAnnotation($aspectClassName, Flow\Introduce::class);
     if ($introduceAnnotation !== null) {
         if ($introduceAnnotation->interfaceName === null && $introduceAnnotation->traitName === null) {
             throw new Aop\Exception('The introduction in class "' . $aspectClassName . '" does neither contain an interface name nor a trait name, at least one is required.', 1172694761);
         }
         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($introduceAnnotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $introduceAnnotation->interfaceName, Flow\Introduce::class));
         $pointcut = new Aop\Pointcut\Pointcut($introduceAnnotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
         if ($introduceAnnotation->interfaceName !== null) {
             $introduction = new Aop\InterfaceIntroduction($aspectClassName, $introduceAnnotation->interfaceName, $pointcut);
             $aspectContainer->addInterfaceIntroduction($introduction);
         }
         if ($introduceAnnotation->traitName !== null) {
             $introduction = new TraitIntroduction($aspectClassName, $introduceAnnotation->traitName, $pointcut);
             $aspectContainer->addTraitIntroduction($introduction);
         }
     }
     foreach ($this->reflectionService->getClassPropertyNames($aspectClassName) as $propertyName) {
         $introduceAnnotation = $this->reflectionService->getPropertyAnnotation($aspectClassName, $propertyName, Flow\Introduce::class);
         if ($introduceAnnotation !== null) {
             $pointcutFilterComposite = $this->pointcutExpressionParser->parse($introduceAnnotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $propertyName, Flow\Introduce::class));
             $pointcut = new Aop\Pointcut\Pointcut($introduceAnnotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName);
             $introduction = new PropertyIntroduction($aspectClassName, $propertyName, $pointcut);
             $aspectContainer->addPropertyIntroduction($introduction);
         }
     }
     if (count($aspectContainer->getAdvisors()) < 1 && count($aspectContainer->getPointcuts()) < 1 && count($aspectContainer->getInterfaceIntroductions()) < 1 && count($aspectContainer->getTraitIntroductions()) < 1 && count($aspectContainer->getPropertyIntroductions()) < 1) {
         throw new Aop\Exception('The class "' . $aspectClassName . '" is tagged to be an aspect but doesn\'t contain advices nor pointcut or introduction declarations.', 1169124534);
     }
     return $aspectContainer;
 }