public function generate(\ReflectionClass $originalClass, PhpClass $genClass)
 {
     $methods = ReflectionUtils::getOverrideableMethods($originalClass);
     if (null !== $this->filter) {
         $methods = array_filter($methods, $this->filter);
     }
     if (empty($methods)) {
         return;
     }
     if (!empty($this->requiredFile)) {
         $genClass->addRequiredFile($this->requiredFile);
     }
     $interceptorLoader = new PhpProperty();
     $interceptorLoader->setName($this->prefix . 'loader')->setVisibility(PhpProperty::VISIBILITY_PRIVATE);
     $genClass->setProperty($interceptorLoader);
     $loaderSetter = new PhpMethod();
     $loaderSetter->setName($this->prefix . 'setLoader')->setVisibility(PhpMethod::VISIBILITY_PUBLIC)->setBody('$this->' . $this->prefix . 'loader = $loader;');
     $genClass->setMethod($loaderSetter);
     $loaderParam = new PhpParameter();
     $loaderParam->setName('loader')->setType('CG\\Proxy\\InterceptorLoaderInterface');
     $loaderSetter->addParameter($loaderParam);
     $interceptorCode = '$ref = new \\ReflectionMethod(%s, %s);' . "\n" . '$interceptors = $this->' . $this->prefix . 'loader->loadInterceptors($ref, $this, array(%s));' . "\n" . '$invocation = new \\CG\\Proxy\\MethodInvocation($ref, $this, array(%s), $interceptors);' . "\n\n" . 'return $invocation->proceed();';
     foreach ($methods as $method) {
         $params = array();
         foreach ($method->getParameters() as $param) {
             $params[] = '$' . $param->name;
         }
         $params = implode(', ', $params);
         $genMethod = PhpMethod::fromReflection($method)->setBody(sprintf($interceptorCode, var_export(ClassUtils::getUserClass($method->class), true), var_export($method->name, true), $params, $params))->setDocblock(null);
         $genClass->setMethod($genMethod);
     }
 }
 public function generate(\ReflectionClass $original, PhpClass $proxy)
 {
     $writer = new Writer();
     // copy over all public methods
     foreach ($original->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
         if ($method->isStatic()) {
             continue;
         }
         $writer->reset()->write('return $this->delegate->')->write($method->name)->write('(');
         $first = true;
         foreach ($method->getParameters() as $param) {
             if (!$first) {
                 $writer->write(', ');
             }
             $first = false;
             $writer->write('$')->write($param->name);
         }
         $writer->write(');');
         $proxyMethod = PhpMethod::fromReflection($method)->setBody($writer->getContent());
         $proxy->setMethod($proxyMethod);
     }
     $proxy->setProperty(PhpProperty::create('delegate')->setVisibility('private'));
     $proxy->setProperty(PhpProperty::create('container')->setVisibility('private'));
     $proxy->setMethod(PhpMethod::create('__construct')->setVisibility('public')->addParameter(PhpParameter::create('objectManager')->setType('Doctrine\\Common\\Persistence\\ObjectManager'))->addParameter(PhpParameter::create('container')->setType('Symfony\\Component\\DependencyInjection\\ContainerInterface'))->setBody($writer->reset()->writeln('$this->delegate = $objectManager;')->writeln('$this->container = $container;')->getContent()));
     $proxy->setMethod(PhpMethod::fromReflection($original->getMethod('getRepository'))->setParameters(array(PhpParameter::create('className')))->setBody($writer->reset()->writeln('$repository = $this->delegate->getRepository($className);' . "\n")->writeln('if (null !== $metadata = $this->container->get("jms_di_extra.metadata.metadata_factory")->getMetadataForClass(get_class($repository))) {')->indent()->writeln('foreach ($metadata->classMetadata as $classMetadata) {')->indent()->writeln('foreach ($classMetadata->methodCalls as $call) {')->indent()->writeln('list($method, $arguments) = $call;')->writeln('call_user_func_array(array($repository, $method), $this->prepareArguments($arguments));')->outdent()->writeln('}')->outdent()->writeln('}')->outdent()->writeln('}' . "\n")->writeln('return $repository;')->getContent()));
     $proxy->setMethod(PhpMethod::create('prepareArguments')->setVisibility('private')->addParameter(PhpParameter::create('arguments')->setType('array'))->setBody($writer->reset()->writeln('$processed = array();')->writeln('foreach ($arguments as $arg) {')->indent()->writeln('if ($arg instanceof \\Symfony\\Component\\DependencyInjection\\Reference) {')->indent()->writeln('$processed[] = $this->container->get((string) $arg, $arg->getInvalidBehavior());')->outdent()->writeln('} else if ($arg instanceof \\Symfony\\Component\\DependencyInjection\\Parameter) {')->indent()->writeln('$processed[] = $this->container->getParameter((string) $arg);')->outdent()->writeln('} else {')->indent()->writeln('$processed[] = $arg;')->outdent()->writeln('}')->outdent()->writeln('}' . "\n")->writeln('return $processed;')->getContent()));
 }
 public function generate(\ReflectionClass $class, PhpClass $genClass)
 {
     if (!empty($this->requiredFile)) {
         $genClass->addRequiredFile($this->requiredFile);
     }
     $genClass->setProperty(PhpProperty::create()->setName(self::PREFIX . 'container')->setVisibility('private'));
     $genClass->setMethod(PhpMethod::create()->setName(self::PREFIX . 'setContainer')->addParameter(PhpParameter::create()->setName('container')->setType('Symfony\\Component\\DependencyInjection\\ContainerInterface'))->setBody('$this->' . self::PREFIX . 'container = $container;'));
     $genClass->addInterfaceName('JMS\\DiExtraBundle\\DependencyInjection\\LookupMethodClassInterface');
     $genClass->setMethod(PhpMethod::create()->setName(self::PREFIX . 'getOriginalClassName')->setFinal(true)->setBody('return ' . var_export($class->name, true) . ';'));
     foreach ($this->getLookupMethods() as $name => $value) {
         $genClass->setMethod(PhpMethod::fromReflection($class->getMethod($name))->setAbstract(false)->setBody('return ' . $this->dumpValue($value) . ';')->setDocblock(null));
     }
 }
 public function override(ReflectionMethod $method, Background $annotation)
 {
     $keepOriginalCodeIn = '__' . spl_object_hash($method) . '__' . $method->getName();
     $keepOriginalMethod = PhpMethod::fromReflection($method);
     $body = $this->getOriginalBody($method);
     $keepOriginalMethod->setName($keepOriginalCodeIn)->setBody($body);
     $writer = new Writer();
     $asyncProxyMethod = PhpMethod::fromReflection($method)->setBody($writer->reset()->writeln('$arguments = func_get_args();')->writeln('$arguments = $this->__defaultTransform->encode($arguments);')->writeln('$this->__MessagingAdapter->doBackground("' . $annotation->getName() . '", $arguments);')->writeln('return true;')->getContent());
     /** array here, array there, but here is how closures are really convenient */
     $this->overrides[] = function (PhpClass $proxy) use($keepOriginalMethod, $asyncProxyMethod) {
         $proxy->setMethod($keepOriginalMethod);
         $proxy->setMethod($asyncProxyMethod);
     };
     return $keepOriginalCodeIn;
 }
 /**
  * Creates a new enhanced class
  *
  * @return string
  */
 public final function generateClass()
 {
     static $docBlock;
     if (empty($docBlock)) {
         $writer = new Writer();
         $writer->writeln('/**')->writeln(' * CG library enhanced proxy class.')->writeln(' *')->writeln(' * This code was generated automatically by the CG library, manual changes to it')->writeln(' * will be lost upon next generation.')->writeln(' */');
         $docBlock = $writer->getContent();
     }
     $this->generatedClass = PhpClass::create()->setDocblock($docBlock)->setParentClassName($this->class->name);
     $proxyClassName = $this->getClassName($this->class);
     if (false === strpos($proxyClassName, NamingStrategyInterface::SEPARATOR)) {
         throw new \RuntimeException(sprintf('The proxy class name must be suffixed with "%s" and an optional string, but got "%s".', NamingStrategyInterface::SEPARATOR, $proxyClassName));
     }
     $this->generatedClass->setName($proxyClassName);
     if (!empty($this->interfaces)) {
         $this->generatedClass->setInterfaceNames(array_map(function ($v) {
             return '\\' . $v;
         }, $this->interfaces));
         foreach ($this->getInterfaceMethods() as $method) {
             $method = PhpMethod::fromReflection($method);
             $method->setAbstract(false);
             $this->generatedClass->setMethod($method);
         }
     }
     if (!empty($this->generators)) {
         foreach ($this->generators as $generator) {
             $generator->generate($this->class, $this->generatedClass);
         }
     }
     return $this->generateCode($this->generatedClass);
 }
 /**
  * @return PhpMethod
  */
 protected static function createMethod(\ReflectionMethod $method)
 {
     return PhpMethod::fromReflection($method);
 }
Beispiel #7
0
 /**
  * generate the method object with its body and parameters
  *
  * @param ReflectionMethod $method
  * @param array|null $aspects
  * @return PhpMethod
  */
 protected function generateMethod(ReflectionMethod $method, $aspects = array())
 {
     $generator = new AspectCodeGenerator($method->class, $method->name);
     $genMethod = PhpMethod::fromReflection($method)->setBody($this->generateMethodCode($method, $generator))->setDocblock($this->generateDocBlock($method, $generator));
     foreach ($aspects as $aspect) {
         $genMethod->addParameter($this->generateAspectParameter($aspect));
     }
     return $genMethod;
 }
 private function addMethods(PhpClass $class, array $methods)
 {
     foreach ($methods as $method) {
         $initializingCode = 'if (false === $this->' . $this->prefix . 'initialized) {' . "\n" . '    $this->' . $this->prefix . 'initialize();' . "\n" . '}';
         if ($class->hasMethod($method->name)) {
             $genMethod = $class->getMethod($method->name);
             $genMethod->setBody($initializingCode . "\n" . $genMethod->getBody());
             continue;
         }
         $genMethod = PhpMethod::fromReflection($method);
         $genMethod->setBody($initializingCode . "\n\n" . 'return ' . GeneratorUtils::callMethod($method) . ';');
         $class->setMethod($genMethod);
     }
 }