. * * The copyright holder may be reached by emailing john@kleijnweb.nl * * * * @copyright Copyright (C) 2010 Kleijn Web Development * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License */ namespace kwd\blog\virtualproxy; /** * Code generator virtual proxies * * @category virtualproxy * @package kwd\blog\virtualproxy */ class ProxyGenerator { /** * @var ReflectionClass */ private $_refl; /** * @var string */ private $_namespace; /** * Create a new generator * * @param string $namespace */ public function __construct($namespace = null) { $this->setNamespace($namespace); } /** * Prefix class names with this namespace * * @param string $namespace * @return kwd\blog\virtualproxy\ProxyGenerator */ public function setNamespace($namespace) { $this->_namespace = $namespace; return $this; } public function getProxyName($subjectName) { return "{$subjectName}Proxy"; } /** * Generate the code for a proxy by subject class * * @param string $subjectName * @return string */ public function generate($subjectName) { if(strpos($subjectName, '\\') !== false) { $segs = explode('\\', $subjectName); $subjectName = array_pop($segs); $namespace = implode('\\', $segs); } else { $namespace = $this->_namespace; } $fullSubjectName = $namespace ? "\\$namespace\\$subjectName" : $subjectName; $this->_refl = new \ReflectionClass($fullSubjectName); $proxyName = $this->getProxyName($subjectName); if(class_exists($namespace ? "\\$namespace\\$proxyName" : $proxyName, false)) { require_once 'Exception.php'; throw new Exception("Proxy '$proxyName' already exists"); } $output = $namespace ? "namespace $namespace;\n\n" : ""; $output .= "class $proxyName extends $subjectName\n{\n" . "\tprivate \$_loader;\n" . "\tprivate \$_subject;\n" . "\n"; foreach($this->_refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) { $paramStrings = array(); $delegationParamStrings = array(); foreach($method->getParameters() as $param) { $paramString = ($param->isPassedByReference() ? '&' : '') . ("\${$param->getName()}"); if($param->getClass() && $param->getClass()->getName()) { $paramString = "\\{$param->getClass()->getName()} {$paramString}"; } $paramString .= ($param->isDefaultValueAvailable() ? " = " . var_export($param->getDefaultValue(), true) : ''); $paramStrings[] = $paramString; $delegationParamStrings[] = "\${$param->getName()}"; } $paramsString = implode(', ', $paramStrings); $delegationParamsStrings = implode(', ', $delegationParamStrings); $output .= "\n\tpublic function {$method->getName()}($paramsString)\n\t{\n" . "\t\treturn \$this->_getSubject()->{$method->getName()}($delegationParamsStrings);\n" . "\t}\n"; } $output .= "\n\tprivate function _getSubject()\n\t{\n" . "\t\tif(!\$this->_subject)\n\t\t{\n" . "\t\t\t\$this->_subject = \$this->_loader->load();\n" . "\t\t}\n\n" . "\t\treturn \$this->_subject;\n" . "\t}\n" . "}"; var_dump($output); return $output; } }