Return list of advices for class
public getAdvicesForClass ( ReflectionClas\ReflectionClass $class, array $advisors ) : array | Go\Aop\Advice[] | ||
$class | ReflectionClas\ReflectionClass | Class to advise |
$advisors | array | List of advisor to match |
return | array | Go\Aop\Advice[] | List of advices for class |
/** * Check that list of advices for fields works correctly */ public function testGetSinglePropertyAdviceForClassFromAdvisor() { $propName = 'adviceMatcher'; // $this->adviceMatcher; $pointcut = $this->getMock(Pointcut::class); $pointcut->expects($this->any())->method('getClassFilter')->will($this->returnValue(TruePointFilter::getInstance())); $pointcut->expects($this->any())->method('matches')->will($this->returnCallback(function ($point) use($propName) { return $point->name === $propName; })); $pointcut->expects($this->any())->method('getKind')->will($this->returnValue(Pointcut::KIND_PROPERTY)); $advice = $this->getMock(Advice::class); $advisor = new DefaultPointcutAdvisor($pointcut, $advice); $advices = $this->adviceMatcher->getAdvicesForClass($this->reflectionClass, array($advisor)); $this->assertArrayHasKey(AspectContainer::PROPERTY_PREFIX, $advices); $this->assertArrayHasKey($propName, $advices[AspectContainer::PROPERTY_PREFIX]); $this->assertCount(1, $advices[AspectContainer::PROPERTY_PREFIX]); }
/** * Performs weaving of single class if needed * * @param array|Advisor[] $advisors * @param StreamMetaData $metadata Source stream information * @param ParsedClass $class Instance of class to analyze * @param integer $lineOffset Current offset, will be updated to store the last position * * @return bool True if was class processed, false otherwise */ private function processSingleClass(array $advisors, StreamMetaData $metadata, ParsedClass $class, &$lineOffset) { $advices = $this->adviceMatcher->getAdvicesForClass($class, $advisors); if (!$advices) { // Fast return if there aren't any advices for that class return false; } // Sort advices in advance to keep the correct order in cache foreach ($advices as &$typeAdvices) { foreach ($typeAdvices as &$joinpointAdvices) { if (is_array($joinpointAdvices)) { $joinpointAdvices = AbstractJoinpoint::sortAdvices($joinpointAdvices); } } } // Prepare new parent name $newParentName = $class->getShortName() . AspectContainer::AOP_PROXIED_SUFFIX; // Replace original class name with new $metadata->source = $this->adjustOriginalClass($class, $metadata->source, $newParentName); // Prepare child Aop proxy $useStatic = $this->kernel->hasFeature(Features::USE_STATIC_FOR_LSB); $child = $this->kernel->hasFeature(Features::USE_TRAIT) && $class->isTrait() ? new TraitProxy($class, $advices, $useStatic) : new ClassProxy($class, $advices, $useStatic); // Set new parent name instead of original $child->setParentName($newParentName); $contentToInclude = $this->saveProxyToCache($class, $child); // Add child to source $tokenCount = $class->getBroker()->getFileTokens($class->getFileName())->count(); if ($tokenCount - $class->getEndPosition() < 3) { // If it's the last class in a file, just add child source $metadata->source .= $contentToInclude . PHP_EOL; } else { $lastLine = $class->getEndLine() + $lineOffset; // returns the last line of class $dataArray = explode("\n", $metadata->source); $currentClassArray = array_splice($dataArray, 0, $lastLine); $childClassArray = explode("\n", $contentToInclude); $lineOffset += count($childClassArray) + 2; // returns LoC for child class + 2 blank lines $dataArray = array_merge($currentClassArray, array(''), $childClassArray, array(''), $dataArray); $metadata->source = implode("\n", $dataArray); } return true; }
/** * Performs weaving of single class if needed * * @param array|Advisor[] $advisors * @param StreamMetaData $metadata Source stream information * @param ReflectionClass $class Instance of class to analyze * @param integer $lineOffset Current offset, will be updated to store the last position * * @return bool True if was class processed, false otherwise */ private function processSingleClass(array $advisors, StreamMetaData $metadata, ReflectionClass $class, &$lineOffset) { $advices = $this->adviceMatcher->getAdvicesForClass($class, $advisors); if (empty($advices)) { // Fast return if there aren't any advices for that class return false; } // Sort advices in advance to keep the correct order in cache foreach ($advices as &$typeAdvices) { foreach ($typeAdvices as &$joinpointAdvices) { if (is_array($joinpointAdvices)) { $joinpointAdvices = AbstractJoinpoint::sortAdvices($joinpointAdvices); } } } // Prepare new parent name $newParentName = $class->getShortName() . AspectContainer::AOP_PROXIED_SUFFIX; // Replace original class name with new $metadata->source = $this->adjustOriginalClass($class, $metadata->source, $newParentName); // Prepare child Aop proxy $child = $class->isTrait() ? new TraitProxy($class, $advices) : new ClassProxy($class, $advices); // Set new parent name instead of original $child->setParentName($newParentName); $contentToInclude = $this->saveProxyToCache($class, $child); // Add child to source $lastLine = $class->getEndLine() + $lineOffset; // returns the last line of class $dataArray = explode("\n", $metadata->source); $currentClassArray = array_splice($dataArray, 0, $lastLine); $childClassArray = explode("\n", $contentToInclude); $lineOffset += count($childClassArray) + 2; // returns LoC for child class + 2 blank lines $dataArray = array_merge($currentClassArray, array(''), $childClassArray, array(''), $dataArray); $metadata->source = implode("\n", $dataArray); return true; }