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); } }
/** * 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; }
/** * 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; }
/** * {@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>'); }
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; }
/** * {@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>"); }
public function init(array $options = array()) { if (!isset($options['excludePaths'])) { $options['excludePaths'] = []; } $options['debug'] = true; $options['excludePaths'][] = __DIR__; parent::init($options); }
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); }
/** * 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); }
/** * {@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); }
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; }
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; }
/** * {@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); }
/** * 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; }
/** * 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}"]; }
/** * {@inheritdoc} */ public function __wakeup() { $this->container = AspectKernel::getInstance()->getContainer(); }
/** * 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(); }
/** * 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()); }; } }