/** * Makes sure that any sub classes of an adviced class also build the advices array on construction. * * @param string $className The adviced class name * @param ClassNameIndex $targetClassNameCandidates target class names for advices * @param ClassNameIndex $treatedSubClasses Already treated (sub) classes to avoid duplication * @return ClassNameIndex The new collection of already treated classes */ protected function proxySubClassesOfClassToEnsureAdvices($className, ClassNameIndex $targetClassNameCandidates, ClassNameIndex $treatedSubClasses) { if ($this->reflectionService->isClassReflected($className) === false) { return $treatedSubClasses; } if (trait_exists($className)) { return $treatedSubClasses; } if (interface_exists($className)) { return $treatedSubClasses; } $subClassNames = $this->reflectionService->getAllSubClassNamesForClass($className); foreach ($subClassNames as $subClassName) { if ($treatedSubClasses->hasClassName($subClassName)) { continue; } if ($this->reflectionService->isClassReflected($subClassName) === false || $targetClassNameCandidates->hasClassName($subClassName)) { continue; } $proxyClass = $this->compiler->getProxyClass($subClassName); if ($proxyClass === false) { continue; } $callBuildMethodsAndAdvicesArrayCode = " if (method_exists(get_parent_class(), 'Flow_Aop_Proxy_buildMethodsAndAdvicesArray') && is_callable('parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray')) parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray();\n"; $proxyClass->getConstructor()->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode); $proxyClass->getMethod('__wakeup')->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode); } $treatedSubClasses = $treatedSubClasses->union(new ClassNameIndex($subClassNames)); return $treatedSubClasses; }
/** * Adds code to build the methods and advices array in case the parent class has some. * * @param string $className * @param ClassNameIndex $treatedSubClasses * @return ClassNameIndex */ protected function addBuildMethodsAndAdvicesCodeToClass($className, ClassNameIndex $treatedSubClasses) { if ($treatedSubClasses->hasClassName($className)) { return $treatedSubClasses; } $treatedSubClasses = $treatedSubClasses->union(new ClassNameIndex([$className])); if ($this->reflectionService->isClassReflected($className) === false) { return $treatedSubClasses; } $proxyClass = $this->compiler->getProxyClass($className); if ($proxyClass === false) { return $treatedSubClasses; } $callBuildMethodsAndAdvicesArrayCode = " if (method_exists(get_parent_class(), 'Flow_Aop_Proxy_buildMethodsAndAdvicesArray') && is_callable('parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray')) parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray();\n"; $proxyClass->getConstructor()->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode); $proxyClass->getMethod('__wakeup')->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode); return $treatedSubClasses; }