/** * @param Method $method * * @return $this */ public function addMethod(Method $method) { $this->methods[$method->getName()] = $method; return $this; }
/** * @param $metadataClassName */ public function generate($metadataClassName) { $oxidPath = $this->oxidPath; $this->metadata = array(); foreach ($this->mappings as $oxidClass => $proxies) { foreach ($proxies as $proxyName => $mappings) { $phpFile = new PhpFile(); $phpUse = new PhpUse(); $moduleId = "aom{$proxyName}"; $proxyClassName = "{$moduleId}_{$oxidClass}"; $phpClass = new PhpClass($proxyClassName, $phpUse); $phpClass->setExtension("{$proxyClassName}_parent"); foreach ($this->classesToLoad[$oxidClass][$proxyName] as $moduleClassName => $moduleFile) { $methodName = $this->sanatizeModuleClass($moduleClassName); $instanceProperty = lcfirst($methodName); $property = new Property($instanceProperty); $property->setVisibility(Property::VISIBILITY_PRIVATE); $phpClass->addProperty($property); $method = new Method("get{$methodName}"); $method->setVisibility(Method::VISIBILITY_PRIVATE); $body = "if (!class_exists('{$moduleClassName}', false)) {\n"; $body .= "include '{$moduleFile}';\n"; $body .= "}\n"; $body .= "if (null === \$this->{$instanceProperty}) {\n"; $body .= "\$this->{$instanceProperty} = new \\{$moduleClassName}();\n"; $body .= "}\n"; $body .= "return \$this->{$instanceProperty};\n"; $method->setBody($body); $phpClass->addMethod($method); } /** @var Mapping $mapping */ foreach ($mappings as $mapping) { $body = "\$class = \$this->get" . $this->sanatizeModuleClass($mapping->getModuleClass()); $body .= "();\n"; $body .= "\$args = func_get_args();\n"; $resultVarAssign = ""; $resultVarReturn = ""; if ($mapping->hasReturn()) { $resultVar = "\$result"; $resultVarAssign = "{$resultVar} = "; $resultVarReturn = "return {$resultVar};\n"; } if (Annotations\Method::EXECUTE_BEFORE === $mapping->getParentExecution()) { $body .= "{$resultVarAssign}call_user_func_array(array('parent', __FUNCTION__), \$args);\n"; } $body .= "{$resultVarAssign}call_user_func_array(array(\$class, '{$mapping->getModuleMethod()}'), \$args);\n"; if (Annotations\Method::EXECUTE_AFTER === $mapping->getParentExecution()) { $body .= "{$resultVarAssign}call_user_func_array(array('parent', __FUNCTION__), \$args);\n"; } $body .= $resultVarReturn; $methodReflection = new \ReflectionMethod($mapping->getOxidClass(), $mapping->getOxidMethod()); $method = new Method($mapping->getOxidMethod(), array(), $body); foreach ($methodReflection->getParameters() as $parameter) { $method->addParameter(new Method\Parameter($parameter->getName(), $parameter->getDefaultValue(), !$parameter->isOptional())); } switch (true) { case $methodReflection->isPublic(): $method->setVisibility(Method::VISIBILITY_PUBLIC); break; case $methodReflection->isProtected(): $method->setVisibility(Method::VISIBILITY_PROTECTED); break; case $methodReflection->isPrivate(): $method->setVisibility(Method::VISIBILITY_PRIVATE); break; } $method->setFinal($methodReflection->isFinal()); $method->setAbstract($methodReflection->isAbstract()); $phpClass->addMethod($method); } $vendorPath = $this->modulePath; do { $vendorPath = dirname($vendorPath) . '/vendor'; if ('/' === $vendorPath || ':' == substr($vendorPath, 1, 1)) { throw new \RuntimeException('Can not locate the vendor directory!'); } } while (!file_exists($vendorPath)); $phpAutoloader = new Code("include_once '{$this->vendorPath}/autoload.php';\n"); $phpFile->addBlock($phpAutoloader); $phpFile->addBlock($phpUse); $phpFile->addBlock($phpClass); $proxyClassExtend = str_replace('_', '/', $proxyClassName) . "/{$proxyClassName}"; $proxyClassFile = "{$oxidPath}/modules/{$proxyClassExtend}.php"; if (!file_exists(dirname($proxyClassFile))) { mkdir(dirname($proxyClassFile), 0777, true); } file_put_contents($proxyClassFile, $phpFile->generate()); /** @var Metadata $metadataClass */ $metadataClass = $this->getMetadata($proxyName, $metadataClassName, $moduleId); $metadataClass->getExtensions()->addExtension($oxidClass, $proxyClassExtend); file_put_contents("{$oxidPath}/modules/{$moduleId}/metadata.php", $metadataClass->generate()); } } }