Neos\Flow\Aop\Pointcut\PointcutExpressionParser::parse PHP Method

parse() public method

Parses a string pointcut expression and returns the pointcut objects accordingly
public parse ( string $pointcutExpression, string $sourceHint ) : PointcutFilterComposite
$pointcutExpression string The expression defining the pointcut
$sourceHint string A message giving a hint on where the expression was defined. This is used in error messages.
return PointcutFilterComposite A composite of class-filters, method-filters and pointcuts
    public function parse($pointcutExpression, $sourceHint)
    {
        $this->sourceHint = $sourceHint;
        if (!is_string($pointcutExpression) || strlen($pointcutExpression) === 0) {
            throw new InvalidPointcutExpressionException(sprintf('Pointcut expression must be a valid string, "%s" given, defined in "%s"', gettype($pointcutExpression), $this->sourceHint), 1168874738);
        }
        $pointcutFilterComposite = new PointcutFilterComposite();
        $pointcutExpressionParts = preg_split(self::PATTERN_SPLITBYOPERATOR, $pointcutExpression, -1, PREG_SPLIT_DELIM_CAPTURE);
        for ($partIndex = 0; $partIndex < count($pointcutExpressionParts); $partIndex += 2) {
            $operator = $partIndex > 0 ? trim($pointcutExpressionParts[$partIndex - 1]) : '&&';
            $expression = trim($pointcutExpressionParts[$partIndex]);
            if ($expression[0] === '!') {
                $expression = trim(substr($expression, 1));
                $operator .= '!';
            }
            if (strpos($expression, '(') === false) {
                $this->parseDesignatorPointcut($operator, $expression, $pointcutFilterComposite);
            } else {
                $matches = [];
                $numberOfMatches = preg_match(self::PATTERN_MATCHPOINTCUTDESIGNATOR, $expression, $matches);
                if ($numberOfMatches !== 1) {
                    throw new InvalidPointcutExpressionException('Syntax error: Pointcut designator expected near "' . $expression . '", defined in ' . $this->sourceHint, 1168874739);
                }
                $pointcutDesignator = $matches[0];
                $signaturePattern = $this->getSubstringBetweenParentheses($expression);
                switch ($pointcutDesignator) {
                    case 'classAnnotatedWith':
                    case 'class':
                    case 'methodAnnotatedWith':
                    case 'method':
                    case 'within':
                    case 'filter':
                    case 'setting':
                        $parseMethodName = 'parseDesignator' . ucfirst($pointcutDesignator);
                        $this->{$parseMethodName}($operator, $signaturePattern, $pointcutFilterComposite);
                        break;
                    case 'evaluate':
                        $this->parseRuntimeEvaluations($operator, $signaturePattern, $pointcutFilterComposite);
                        break;
                    default:
                        throw new AopException('Support for pointcut designator "' . $pointcutDesignator . '" has not been implemented (yet), defined in ' . $this->sourceHint, 1168874740);
                }
            }
        }
        return $pointcutFilterComposite;
    }

Usage Example

 /**
  * 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;
 }
All Usage Examples Of Neos\Flow\Aop\Pointcut\PointcutExpressionParser::parse