/**
* Checks if the specified method matches against the method name
* expression.
*
* Returns TRUE if method name, visibility and arguments constraints match and the target
* method is not final.
*
* @param string $className Ignored in this pointcut filter
* @param string $methodName Name of the method to match against
* @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.
* @return boolean TRUE if the class matches, otherwise FALSE
* @throws Exception
*/
public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
{
$matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName);
if ($matchResult === false) {
throw new Exception('Error in regular expression', 1168876915);
} elseif ($matchResult !== 1) {
return false;
}
switch ($this->methodVisibility) {
case 'public':
if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName))) {
return false;
}
break;
case 'protected':
if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodProtected($methodDeclaringClassName, $methodName))) {
return false;
}
break;
}
if ($methodDeclaringClassName !== null && $this->reflectionService->isMethodFinal($methodDeclaringClassName, $methodName)) {
return false;
}
$methodArguments = $methodDeclaringClassName === null ? [] : $this->reflectionService->getMethodParameters($methodDeclaringClassName, $methodName);
foreach (array_keys($this->methodArgumentConstraints) as $argumentName) {
$objectAccess = explode('.', $argumentName, 2);
$argumentName = $objectAccess[0];
if (!array_key_exists($argumentName, $methodArguments)) {
$this->systemLogger->log('The argument "' . $argumentName . '" declared in pointcut does not exist in method ' . $methodDeclaringClassName . '->' . $methodName, LOG_NOTICE);
return false;
}
}
return true;
}