public function build()
{
$allAvailableClassNamesByPackage = $this->objectManager->getRegisteredClassNames();
$possibleTargetClassNames = $this->getProxyableClasses($allAvailableClassNamesByPackage);
$actualAspectClassNames = $this->reflectionService->getClassNamesByAnnotation(Flow\Aspect::class);
sort($possibleTargetClassNames);
sort($actualAspectClassNames);
$this->aspectContainers = $this->buildAspectContainers($actualAspectClassNames);
$rebuildEverything = false;
if ($this->objectConfigurationCache->has('allAspectClassesUpToDate') === false) {
$rebuildEverything = true;
$this->systemLogger->log('Aspects have been modified, therefore rebuilding all target classes.', LOG_INFO);
$this->objectConfigurationCache->set('allAspectClassesUpToDate', true);
}
$possibleTargetClassNameIndex = new ClassNameIndex();
$possibleTargetClassNameIndex->setClassNames($possibleTargetClassNames);
$targetClassNameCandidates = new ClassNameIndex();
foreach ($this->aspectContainers as $aspectContainer) {
$targetClassNameCandidates->applyUnion($aspectContainer->reduceTargetClassNames($possibleTargetClassNameIndex));
}
$targetClassNameCandidates->sort();
$treatedSubClasses = new ClassNameIndex();
foreach ($targetClassNameCandidates->getClassNames() as $targetClassName) {
$isUnproxied = $this->objectConfigurationCache->has('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
$hasCacheEntry = $this->compiler->hasCacheEntryForClass($targetClassName) || $isUnproxied;
if ($rebuildEverything === true || $hasCacheEntry === false) {
$proxyBuildResult = $this->buildProxyClass($targetClassName, $this->aspectContainers);
if ($proxyBuildResult === false) {
// In case the proxy was not build because there was nothing adviced,
// it might be an advice in the parent and so we need to try to treat this class.
$treatedSubClasses = $this->addBuildMethodsAndAdvicesCodeToClass($targetClassName, $treatedSubClasses);
}
$treatedSubClasses = $this->proxySubClassesOfClassToEnsureAdvices($targetClassName, $targetClassNameCandidates, $treatedSubClasses);
if ($proxyBuildResult !== false) {
if ($isUnproxied) {
$this->objectConfigurationCache->remove('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
}
$this->systemLogger->log(sprintf('Built AOP proxy for class "%s".', $targetClassName), LOG_DEBUG);
} else {
$this->objectConfigurationCache->set('unproxiedClass-' . str_replace('\\', '_', $targetClassName), true);
}
}
}
}