Bug #11017

Using a method visibility inside a pointcut throws an exception

Added by Christopher Hlubek over 4 years ago. Updated over 4 years ago.

Status:Resolved Start date:2010-11-23
Priority:Should have Due date:
Assigned To:Christopher Hlubek % Done:

100%

Category:AOP
Target version:TYPO3 Flow Base Distribution - 1.0 alpha 14
PHP Version: Complexity:
Has patch: Affected Flow version:

Description

FLOW3 throws an Exception if a pointcut like this is registered.

/**
 * Advice for logging service requests
 *
 * @param \F3\FLOW3\AOP\JoinPointInterface
 * @return void
 * @after method(public F3\Foo\Service\.*Service->[a-z].*())
 */
public function logServiceRequest(\F3\FLOW3\AOP\JoinPointInterface $joinPoint) {
}

Without "public" the pointcut works but it will match non-public methods.

15 ReflectionClass::__construct("")

Packages/Framework/FLOW3/Classes/Reflection/ClassReflection.php:

00042:   */
00043:  public function __construct($className) {

00044:   parent::__construct($className);

00045:  }
00046: 

14 F3\FLOW3\Reflection\ClassReflection::__construct("")

Packages/Framework/FLOW3/Classes/Reflection/ReflectionService.php:

00836:   $this->log('Reflecting class "' . $className . '" (' . ($this->initialized ? '' : 'not ') . 'initialized)', LOG_DEBUG);
00837: 

00838:   $class = new \F3\FLOW3\Reflection\ClassReflection($className);

00839:   $this->reflectedClassNames[$className] = time();
00840: 

13 F3\FLOW3\Reflection\ReflectionService::reflectClass("")

Packages/Framework/FLOW3/Classes/Reflection/ReflectionService.php:

00552:  public function isMethodPublic($className, $methodName) {
00553:   $className = trim($className, '\\');

00554:   if (!isset($this->reflectedClassNames[$className])) $this->reflectClass($className);

00555:   return (isset($this->methodVisibilities[$className][$methodName]) && $this->methodVisibilities[$className][$methodName] === ' ');
00556:  }

12 F3\FLOW3\Reflection\ReflectionService::isMethodPublic(NULL, "__construct")

Packages/Framework/FLOW3/Classes/AOP/Pointcut/PointcutMethodNameFilter.php:

00100:   switch ($this->methodVisibility) {
00101:    case 'public' :

00102:     $visibilityMatches = $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName);

00103:    break;
00104:    case 'protected' :

11 F3\FLOW3\AOP\Pointcut\PointcutMethodNameFilter::matches("F3\CouchDB\EntityByParentIdentifierView", "__construct", NULL, 102)

Packages/Framework/FLOW3/Classes/AOP/Pointcut/PointcutFilterComposite.php:

00084:    list($operator, $filter) = $operatorAndFilter;
00085: 

00086:    $currentFilterMatches = $filter->matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier);

00087:    $currentRuntimeEvaluationsDefintion = $filter->getRuntimeEvaluationsDefinition();
00088: 

10 F3\FLOW3\AOP\Pointcut\PointcutFilterComposite::matches("F3\CouchDB\EntityByParentIdentifierView", "__construct", NULL, 102)

Packages/Framework/FLOW3/Classes/AOP/Pointcut/PointcutFilterComposite.php:

00084:    list($operator, $filter) = $operatorAndFilter;
00085: 

00086:    $currentFilterMatches = $filter->matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier);

00087:    $currentRuntimeEvaluationsDefintion = $filter->getRuntimeEvaluationsDefinition();
00088: 

9 F3\FLOW3\AOP\Pointcut\PointcutFilterComposite::matches("F3\CouchDB\EntityByParentIdentifierView", "__construct", NULL, 102)

Packages/Framework/FLOW3/Classes/AOP/Pointcut/Pointcut.php:

00112:   }
00113: 

00114:   return $this->pointcutFilterComposite->matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier);

00115:  }
00116: 

8 F3\FLOW3\AOP\Pointcut\Pointcut::matches("F3\CouchDB\EntityByParentIdentifierView", "__construct", NULL, 102)

Packages/Framework/FLOW3/Classes/AOP/Builder/ProxyClassBuilder.php:

00294:      if ($this->reflectionService->isMethodFinal($targetClassName, $methodName)) continue;
00295: 

00296:      if ($pointcut->matches($targetClassName, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)) {

00297:       $advice = $advisor->getAdvice();
00298:       $interceptedMethods[$methodName]['groupedAdvices'][get_class($advice)][] = $advice;

7 F3\FLOW3\AOP\Builder\ProxyClassBuilder::addAdvicedMethodsToInterceptedMethods(array, array, "F3\CouchDB\EntityByParentIdentifierView", array)

Packages/Framework/FLOW3/Classes/AOP/Builder/ProxyClassBuilder.php:

00145: 
00146:   $interceptedMethods = array();

00147:   $this->addAdvicedMethodsToInterceptedMethods($interceptedMethods, array_merge($methodsFromTargetClass, $methodsFromIntroducedInterfaces), $targetClassName, $aspectContainers);

00148:   $this->addIntroducedMethodsToInterceptedMethods($interceptedMethods, $methodsFromIntroducedInterfaces);
00149:   if (count($interceptedMethods) < 1 && count($introducedInterfaces) < 1) return FALSE;

6 F3\FLOW3\AOP\Builder\ProxyClassBuilder::buildProxyClass("F3\CouchDB\EntityByParentIdentifierView", array, "Development")

Packages/Framework/FLOW3/Classes/AOP/Framework.php:

00244: 
00245:    foreach ($dirtyTargetClassNames as $targetClassName) {

00246:     $proxyBuildResult = $this->proxyClassBuilder->buildProxyClass($targetClassName, $this->aspectContainers, $this->objectManager->getContext());

00247:     if ($proxyBuildResult !== FALSE) {
00248:      $this->targetAndProxyClassNames[$targetClassName] = $proxyBuildResult['proxyClassName'];

Associated revisions

Revision 57e14528
Added by Christopher Hlubek over 4 years ago

[+BUGFIX] FLOW3 (AOP): Fix method visibility for default constructor

Advices with a visibility specifier in the pointcut expression failed
when the default constructor with a NULL original declaring class name
was encountered.

Change-Id: I900b364b3143f112500498a9ec7f67bc626cc14e
Fixes: #11017

History

#1 Updated by Karsten Dambekalns over 4 years ago

And what is the exception? That's only the backtrace... :)

#2 Updated by Christopher Hlubek over 4 years ago

It's a ReflectionException: Class does not exist because isMethodPublic is called on a NULL class name.

#3 Updated by Karsten Dambekalns over 4 years ago

  • Status changed from New to Under Review
  • Assigned To set to Christopher Hlubek
  • Target version set to 1.0 alpha 14

#4 Updated by Christopher Hlubek over 4 years ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100

Also available in: Atom PDF