コード例 #1
0
 /**
  * Generates the necessary methods in the class.
  *
  * @param  \ReflectionClass $originalClass
  * @param  PhpClass         $class
  * @return void
  */
 public function generate(\ReflectionClass $originalClass, PhpClass $class)
 {
     $methods = ReflectionUtils::getOverrideableMethods($originalClass, true);
     // no public, non final methods
     if (empty($methods)) {
         return;
     }
     if (null !== $this->markerInterface) {
         $class->setImplementedInterfaces(array_merge($class->getImplementedInterfaces(), array($this->markerInterface)));
     }
     $initializer = new PhpProperty();
     $initializer->setName($this->prefix . 'lazyInitializer');
     $initializer->setVisibility(PhpProperty::VISIBILITY_PRIVATE);
     $class->setProperty($initializer);
     $initialized = new PhpProperty();
     $initialized->setName($this->prefix . 'initialized');
     $initialized->setDefaultValue(false);
     $initialized->setVisibility(PhpProperty::VISIBILITY_PRIVATE);
     $class->setProperty($initialized);
     $initializerSetter = new PhpMethod();
     $initializerSetter->setName($this->prefix . 'setLazyInitializer');
     $initializerSetter->setBody('$this->' . $this->prefix . 'lazyInitializer = $initializer;');
     $parameter = new PhpParameter();
     $parameter->setName('initializer');
     $parameter->setType('\\CG\\Proxy\\LazyInitializerInterface');
     $initializerSetter->addParameter($parameter);
     $class->setMethod($initializerSetter);
     $this->addMethods($class, $methods);
     $initializingMethod = new PhpMethod();
     $initializingMethod->setName($this->prefix . 'initialize');
     $initializingMethod->setVisibility(PhpMethod::VISIBILITY_PRIVATE);
     $initializingMethod->setBody($this->writer->reset()->writeln('if (null === $this->' . $this->prefix . 'lazyInitializer) {')->indent()->writeln('throw new \\RuntimeException("' . $this->prefix . 'setLazyInitializer() must be called prior to any other public method on this object.");')->outdent()->write("}\n\n")->writeln('$this->' . $this->prefix . 'lazyInitializer->initializeObject($this);')->writeln('$this->' . $this->prefix . 'initialized = true;')->getContent());
     $class->setMethod($initializingMethod);
 }
コード例 #2
0
 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);
     }
 }
コード例 #3
0
 public function testGetOverridableMethods()
 {
     $ref = new \ReflectionClass('CG\\Tests\\Core\\OverridableReflectionTest');
     $methods = ReflectionUtils::getOverrideableMethods($ref);
     $this->assertEquals(4, count($methods));
     $methods = array_map(function ($v) {
         return $v->name;
     }, $methods);
     sort($methods);
     $this->assertEquals(array('a', 'd', 'e', 'h'), $methods);
 }
コード例 #4
0
 /**
  * @param array<PointcutInterface> $pointcuts
  * @param array<string,string> $interceptors
  */
 private function processDefinition(Definition $definition, $pointcuts, &$interceptors)
 {
     if ($definition->isSynthetic()) {
         return;
     }
     // Symfony 2.6 getFactory method
     // TODO: Use only getFactory when bumping require to Symfony >= 2.6
     if (method_exists($definition, 'getFactory') && $definition->getFactory()) {
         return;
     }
     if (!method_exists($definition, 'getFactory') && ($definition->getFactoryService() || $definition->getFactoryClass())) {
         return;
     }
     if ($originalFilename = $definition->getFile()) {
         require_once $originalFilename;
     }
     if (!class_exists($definition->getClass())) {
         return;
     }
     $class = new \ReflectionClass($definition->getClass());
     // check if class is matched
     $matchingPointcuts = array();
     foreach ($pointcuts as $interceptor => $pointcut) {
         if ($pointcut->matchesClass($class)) {
             $matchingPointcuts[$interceptor] = $pointcut;
         }
     }
     if (empty($matchingPointcuts)) {
         return;
     }
     $this->addResources($class, $this->container);
     if ($class->isFinal()) {
         return;
     }
     $classAdvices = array();
     foreach (ReflectionUtils::getOverrideableMethods($class) as $method) {
         if ('__construct' === $method->name) {
             continue;
         }
         $advices = array();
         foreach ($matchingPointcuts as $interceptor => $pointcut) {
             if ($pointcut->matchesMethod($method)) {
                 $advices[] = $interceptor;
             }
         }
         if (empty($advices)) {
             continue;
         }
         $classAdvices[$method->name] = $advices;
     }
     if (empty($classAdvices)) {
         return;
     }
     $interceptors[ClassUtils::getUserClass($class->name)] = $classAdvices;
     $proxyFilename = $this->cacheDir . '/' . str_replace('\\', '-', $class->name) . '.php';
     $generator = new InterceptionGenerator();
     $generator->setFilter(function (\ReflectionMethod $method) use($classAdvices) {
         return isset($classAdvices[$method->name]);
     });
     if ($originalFilename) {
         $relativeOriginalFilename = $this->relativizePath($proxyFilename, $originalFilename);
         if ($relativeOriginalFilename[0] === '.') {
             $generator->setRequiredFile(new RelativePath($relativeOriginalFilename));
         } else {
             $generator->setRequiredFile($relativeOriginalFilename);
         }
     }
     $enhancer = new Enhancer($class, array(), array($generator));
     $enhancer->setNamingStrategy(new DefaultNamingStrategy('EnhancedProxy' . substr(md5($this->container->getParameter('jms_aop.cache_dir')), 0, 8)));
     $enhancer->writeClass($proxyFilename);
     $definition->setFile($proxyFilename);
     $definition->setClass($enhancer->getClassName($class));
     $definition->addMethodCall('__CGInterception__setLoader', array(new Reference('jms_aop.interceptor_loader')));
 }