Пример #1
0
 public function __construct(AspectKernel $kernel)
 {
     $this->kernel = $kernel;
     $this->options = $kernel->getOptions();
     $this->cacheDir = $this->options['cacheDir'];
     $this->appDir = $this->options['appDir'];
     if ($this->cacheDir && file_exists($this->cacheDir . self::CACHE_FILE_NAME)) {
         $this->cacheState = (include $this->cacheDir . self::CACHE_FILE_NAME);
     }
 }
Пример #2
0
 /**
  * Static configurator for filter
  *
  * @param AspectKernel $kernel Kernel to use for configuration
  * @param string $filterName Name of the filter to inject
  * @param CachePathManager $cacheManager Cache manager
  */
 protected static function configure(AspectKernel $kernel, $filterName, CachePathManager $cacheManager)
 {
     if (self::$kernel) {
         throw new \RuntimeException("Filter injector can be configured only once.");
     }
     self::$kernel = $kernel;
     self::$options = $kernel->getOptions();
     self::$filterName = $filterName;
     self::$cachePathManager = $cacheManager;
 }
Пример #3
0
 /**
  * Returns an annotation reader
  *
  * @return Reader $reader
  */
 private static function getReader()
 {
     if (!self::$annotationReader) {
         self::$annotationReader = AspectKernel::getInstance()->getContainer()->get('aspect.annotation.reader');
     }
     return self::$annotationReader;
 }
Пример #4
0
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $output->writeln('Start up application with supplied config...');
     $config = $input->getArgument('applicationConfig');
     $path = stream_resolve_include_path($config);
     if (!is_readable($path)) {
         throw new \InvalidArgumentException("Invalid loader path: {$config}");
     }
     // Init the application once using given config
     // This way the late static binding on the AspectKernel
     // will be on the goaop-zf2-module kernel
     \Zend\Mvc\Application::init(include $path);
     if (!class_exists(AspectKernel::class, false)) {
         $message = "Kernel was not initialized yet. Maybe missing module Go\\ZF2\\GoAopModule in config {$path}";
         throw new \InvalidArgumentException($message);
     }
     $kernel = AspectKernel::getInstance();
     $options = $kernel->getOptions();
     if (empty($options['cacheDir'])) {
         throw new \InvalidArgumentException('Cache warmer require the `cacheDir` options to be configured');
     }
     $enumerator = new Enumerator($options['appDir'], $options['includePaths'], $options['excludePaths']);
     $iterator = $enumerator->enumerate();
     $totalFiles = iterator_count($iterator);
     $output->writeln("Total <info>{$totalFiles}</info> files to process.");
     $iterator->rewind();
     set_error_handler(function ($errno, $errstr, $errfile, $errline) {
         throw new \ErrorException($errstr, $errno, 0, $errfile, $errline);
     });
     $index = 0;
     $errors = [];
     foreach ($iterator as $file) {
         if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
             $output->writeln("Processing file <info>{$file->getRealPath()}</info>");
         }
         $isSuccess = null;
         try {
             // This will trigger creation of cache
             file_get_contents(FilterInjectorTransformer::PHP_FILTER_READ . SourceTransformingLoader::FILTER_IDENTIFIER . '/resource=' . $file->getRealPath());
             $isSuccess = true;
         } catch (\Exception $e) {
             $isSuccess = false;
             $errors[$file->getRealPath()] = $e;
         }
         if ($output->getVerbosity() == OutputInterface::VERBOSITY_NORMAL) {
             $output->write($isSuccess ? '.' : '<error>E</error>');
             if (++$index % 50 == 0) {
                 $output->writeln("({$index}/{$totalFiles})");
             }
         }
     }
     restore_error_handler();
     if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) {
         foreach ($errors as $file => $error) {
             $message = "File {$file} is not processed correctly due to exception: {$error->getMessage()}";
             $output->writeln($message);
         }
     }
     $output->writeln('<info>Done</info>');
 }
Пример #5
0
 public function init(array $options = array())
 {
     $cacheDir = array_key_exists('cacheDir', $options) ? $options['cacheDir'] : null;
     if ($cacheDir && !is_dir($cacheDir)) {
         mkdir($cacheDir, 0777, true);
     }
     return parent::init($options);
 }
 /**
  * Returns an annotation reader
  *
  * @return Reader $reader
  */
 private static function getReader()
 {
     if (!self::$annotationReader) {
         // TODO: ugly global dependecy, decide how to inject it more friendly
         self::$annotationReader = AspectKernel::getInstance()->getContainer()->get('aspect.annotation.reader');
     }
     return self::$annotationReader;
 }
Пример #7
0
 /**
  * {@inheritDoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $output->writeln("Loading aspect kernel for warmup...");
     $loader = $input->getArgument('loader');
     $path = stream_resolve_include_path($loader);
     if (!is_readable($path)) {
         throw new \InvalidArgumentException("Invalid loader path: {$loader}");
     }
     include_once $path;
     if (!class_exists('Go\\Core\\AspectKernel', false)) {
         $message = "Kernel was not initialized yet, please configure it in the {$path}";
         throw new \InvalidArgumentException($message);
     }
     $kernel = AspectKernel::getInstance();
     $options = $kernel->getOptions();
     if (empty($options['cacheDir'])) {
         throw new \InvalidArgumentException("Cache warmer require the `cacheDir` options to be configured");
     }
     $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($options['appDir'], \FilesystemIterator::SKIP_DOTS));
     /** @var \CallbackFilterIterator|\SplFileInfo[] $iterator */
     $iterator = new \CallbackFilterIterator($iterator, $this->getFileFilter($options));
     $totalFiles = iterator_count($iterator);
     $output->writeln("Total <info>{$totalFiles}</info> files to process.");
     $iterator->rewind();
     set_error_handler(function ($errno, $errstr, $errfile, $errline) {
         throw new \ErrorException($errstr, $errno, 0, $errfile, $errline);
     });
     $index = 0;
     $errors = array();
     foreach ($iterator as $file) {
         if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
             $output->writeln("Processing file <info>{$file->getRealPath()}</info>");
         }
         $isSuccess = null;
         try {
             // This will trigger creation of cache
             file_get_contents(FilterInjectorTransformer::PHP_FILTER_READ . SourceTransformingLoader::FILTER_IDENTIFIER . "/resource=" . $file->getRealPath());
             $isSuccess = true;
         } catch (\Exception $e) {
             $isSuccess = false;
             $errors[$file->getRealPath()] = $e;
         }
         if ($output->getVerbosity() == OutputInterface::VERBOSITY_NORMAL) {
             $output->write($isSuccess ? '.' : '<error>E</error>');
             if (++$index % 50 == 0) {
                 $output->writeln("({$index}/{$totalFiles})");
             }
         }
     }
     restore_error_handler();
     if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) {
         foreach ($errors as $file => $error) {
             $message = "File {$file} is not processed correctly due to exception: {$error->getMessage()}";
             $output->writeln($message);
         }
     }
     $output->writeln("<info>Done</info>");
 }
Пример #8
0
 public function init(array $options = array())
 {
     if (!isset($options['excludePaths'])) {
         $options['excludePaths'] = [];
     }
     $options['debug'] = true;
     $options['excludePaths'][] = __DIR__;
     parent::init($options);
 }
Пример #9
0
 public function __construct(AspectKernel $kernel)
 {
     $this->kernel = $kernel;
     $this->options = $kernel->getOptions();
     $this->cacheDir = $this->options['cacheDir'];
     $this->appDir = $this->options['appDir'];
     if ($this->cacheDir) {
         if (!is_dir($this->cacheDir)) {
             $cacheRootDir = dirname($this->cacheDir);
             if (!is_writable($cacheRootDir) || !is_dir($cacheRootDir)) {
                 throw new \InvalidArgumentException("Can not create a directory {$this->cacheDir} for the cache.\n                        Parent directory {$cacheRootDir} is not writable or not exist.");
             }
             mkdir($this->cacheDir, 0770);
         }
         if (!$this->kernel->hasFeature(Features::PREBUILT_CACHE) && !is_writable($this->cacheDir)) {
             throw new \InvalidArgumentException("Cache directory {$this->cacheDir} is not writable");
         }
         if (file_exists($this->cacheDir . self::CACHE_FILE_NAME)) {
             $this->cacheState = (include $this->cacheDir . self::CACHE_FILE_NAME);
         }
     }
 }
 /**
  * Transformer verifies that proxy with static LSB feature is working
  */
 public function testTransformerWithStaticLsbFeature()
 {
     $this->kernel->expects($this->any())->method('hasFeature')->will($this->returnCallback(function ($feature) {
         return $feature === Features::USE_STATIC_FOR_LSB;
     }));
     $this->metadata->source = $this->loadTest('class');
     $this->transformer->transform($this->metadata);
     $actual = $this->normalizeWhitespaces($this->metadata->source);
     $expected = $this->normalizeWhitespaces($this->loadTest('class-woven'));
     // with Features::USE_STATIC_FOR_LSB we expect static::class in the proxy methods
     $expected = str_replace('\\get_called_class()', 'static::class', $expected);
     $this->assertEquals($expected, $actual);
 }
Пример #11
0
 /**
  * Returns a joinpoint for specific function in the namespace
  *
  * @param string $joinPointName Special joinpoint name
  * @param string $namespace Name of the namespace
  *
  * @return FunctionInvocation
  */
 public static function getJoinPoint($joinPointName, $namespace)
 {
     /** @var LazyAdvisorAccessor $accessor */
     static $accessor = null;
     if (!$accessor) {
         $accessor = AspectKernel::getInstance()->getContainer()->get('aspect.advisor.accessor');
     }
     $advices = self::$functionAdvices[$namespace][AspectContainer::FUNCTION_PREFIX][$joinPointName];
     $filledAdvices = array();
     foreach ($advices as $advisorName) {
         $filledAdvices[] = $accessor->{$advisorName};
     }
     return new ReflectionFunctionInvocation($joinPointName, $filledAdvices);
 }
Пример #12
0
 /**
  * {@inheritDoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $loader = $input->getArgument('loader');
     $path = stream_resolve_include_path($loader);
     if (!is_readable($path)) {
         throw new \InvalidArgumentException("Invalid loader path: {$loader}");
     }
     include_once $path;
     if (!class_exists(AspectKernel::class, false)) {
         $message = "Kernel was not initialized yet, please configure it in the {$path}";
         throw new \InvalidArgumentException($message);
     }
     $this->aspectKernel = AspectKernel::getInstance();
 }
 /**
  * Warms up the cache.
  *
  * @param string $cacheDir The cache directory
  */
 public function warmUp($cacheDir)
 {
     $options = $this->aspectKernel->getOptions();
     $oldCacheDir = $this->cachePathManager->getCacheDir();
     $this->cachePathManager->setCacheDir($cacheDir . '/aspect');
     $enumerator = new Enumerator($options['appDir'], $options['includePaths'], $options['excludePaths']);
     $iterator = $enumerator->enumerate();
     set_error_handler(function ($errno, $errstr, $errfile, $errline) {
         throw new \ErrorException($errstr, $errno, 0, $errfile, $errline);
     });
     $errors = array();
     foreach ($iterator as $file) {
         $realPath = $file->getRealPath();
         try {
             // This will trigger creation of cache
             file_get_contents(FilterInjectorTransformer::PHP_FILTER_READ . SourceTransformingLoader::FILTER_IDENTIFIER . "/resource=" . $realPath);
         } catch (\Exception $e) {
             $errors[$realPath] = $e;
         }
     }
     restore_error_handler();
     $this->cachePathManager->flushCacheState();
     $this->cachePathManager->setCacheDir($oldCacheDir);
 }
Пример #14
0
 public static function getJoinPoint($traitName, $className, $joinPointType, $pointName)
 {
     /** @var LazyAdvisorAccessor $accessor */
     static $accessor = null;
     if (!isset($accessor)) {
         $aspectKernel = AspectKernel::getInstance();
         $accessor = $aspectKernel->getContainer()->get('aspect.advisor.accessor');
     }
     $advices = self::$traitAdvices[$traitName][$joinPointType][$pointName];
     $filledAdvices = [];
     foreach ($advices as $advisorName) {
         $filledAdvices[] = $accessor->{$advisorName};
     }
     $joinpoint = new self::$invocationClassMap[$joinPointType]($className, $pointName . '➩', $filledAdvices);
     return $joinpoint;
 }
Пример #15
0
 public static function getJoinPoint($traitName, $className, $joinPointType, $pointName)
 {
     /** @var LazyAdvisorAccessor $accessor */
     static $accessor = null;
     if (!self::$invocationClassMap) {
         $aspectKernel = AspectKernel::getInstance();
         $accessor = $aspectKernel->getContainer()->get('aspect.advisor.accessor');
         self::setMappings($aspectKernel->hasFeature(Features::USE_CLOSURE), $aspectKernel->hasFeature(Features::USE_SPLAT_OPERATOR));
     }
     $advices = self::$traitAdvices[$traitName][$joinPointType][$pointName];
     $filledAdvices = array();
     foreach ($advices as $advisorName) {
         $filledAdvices[] = $accessor->{$advisorName};
     }
     $joinpoint = new self::$invocationClassMap[$joinPointType]($className, $pointName . '➩', $filledAdvices);
     return $joinpoint;
 }
Пример #16
0
 /**
  * {@inheritdoc}
  */
 public function init(array $options = array())
 {
     $file = rtrim($options['cacheDir'], '/') . '/AspectServiceContainer.php';
     $containerConfigCache = new ConfigCache($file, !empty($options['debug']));
     if (!$containerConfigCache->isFresh()) {
         $container = new ContainerBuilder();
         $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/Resources'));
         $loader->load('components.xml');
         $loader->load('aspect.xml');
         $loader->load('demo_aspects.xml');
         // TODO: Remove this hardcoded example
         $container->addCompilerPass(new ComponentScannerPass($options['appDir'] . '/src'));
         $container->addCompilerPass(new AspectCollectorPass());
         $container->addCompilerPass(new InterfaceBinderPass(), PassConfig::TYPE_AFTER_REMOVING);
         $container->setParameter('kernel.interceptFunctions', !empty($options['interceptFunctions']));
         $container->compile();
         $dumper = new PhpDumper($container);
         $containerConfigCache->write($dumper->dump(array('base_class' => 'Warlock\\WarlockContainer', 'class' => static::$containerClass)), $container->getResources());
     }
     require_once $file;
     parent::init($options);
     $this->container->addResource($file);
 }
Пример #17
0
 /**
  * Wrap advices with joinpoint object
  *
  * @param array|Advice[] $classAdvices Advices for specific class
  * @param string $className Name of the original class to use
  *
  * @throws \UnexpectedValueException If joinPoint type is unknown
  *
  * NB: Extension should be responsible for wrapping advice with join point.
  *
  * @return array|Joinpoint[] returns list of joinpoint ready to use
  */
 protected static function wrapWithJoinPoints($classAdvices, $className)
 {
     /** @var LazyAdvisorAccessor $accessor */
     static $accessor = null;
     if (!isset($accessor)) {
         $aspectKernel = AspectKernel::getInstance();
         $accessor = $aspectKernel->getContainer()->get('aspect.advisor.accessor');
     }
     $joinPoints = [];
     foreach ($classAdvices as $joinPointType => $typedAdvices) {
         // if not isset then we don't want to create such invocation for class
         if (!isset(self::$invocationClassMap[$joinPointType])) {
             continue;
         }
         foreach ($typedAdvices as $joinPointName => $advices) {
             $filledAdvices = [];
             foreach ($advices as $advisorName) {
                 $filledAdvices[] = $accessor->{$advisorName};
             }
             $joinpoint = new self::$invocationClassMap[$joinPointType]($className, $joinPointName, $filledAdvices);
             $joinPoints["{$joinPointType}:{$joinPointName}"] = $joinpoint;
         }
     }
     return $joinPoints;
 }
Пример #18
0
 /**
  * Unserialize an advice
  *
  * @param array $adviceData Information about advice
  *
  * @return Closure
  */
 public static function unserializeAdvice(array $adviceData)
 {
     $aspectName = $adviceData['aspect'];
     $methodName = $adviceData['method'];
     if (!isset(static::$localAdvicesCache["{$aspectName}->{$methodName}"])) {
         $refMethod = new ReflectionMethod($aspectName, $methodName);
         $aspect = AspectKernel::getInstance()->getContainer()->getAspect($aspectName);
         $advice = $refMethod->getClosure($aspect);
         static::$localAdvicesCache["{$aspectName}->{$methodName}"] = $advice;
     }
     return static::$localAdvicesCache["{$aspectName}->{$methodName}"];
 }
Пример #19
0
 /**
  * {@inheritdoc}
  */
 public function __wakeup()
 {
     $this->container = AspectKernel::getInstance()->getContainer();
 }
Пример #20
0
 /**
  * Default constructor for transformer
  *
  * @param AspectKernel $kernel Instance of aspect kernel
  * @param array $options Custom options or kernel options
  */
 public function __construct(AspectKernel $kernel, array $options = [])
 {
     $this->kernel = $kernel;
     $this->container = $kernel->getContainer();
     $this->options = $options ?: $kernel->getOptions();
 }
Пример #21
0
 /**
  * Returns an advice from aspect method reflection
  *
  * @param Aspect $aspect Instance of aspect
  * @param ReflectionMethod $refMethod Reflection method of aspect
  *
  * @return callable|object
  */
 public static function fromAspectReflection(Aspect $aspect, ReflectionMethod $refMethod)
 {
     static $useClosure;
     if (!isset($useClosure)) {
         $useClosure = AspectKernel::getInstance()->hasFeature(Features::USE_CLOSURE);
     }
     if ($useClosure) {
         return $refMethod->getClosure($aspect);
     } else {
         return function () use($aspect, $refMethod) {
             return $refMethod->invokeArgs($aspect, func_get_args());
         };
     }
 }