From 1a502bf8d621b74707cf3b1b08de0f1aac098baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Proch=C3=A1zka?= Date: Sun, 18 Aug 2013 12:03:25 +0200 Subject: [PATCH] The extension should be extensible by other extensions using IAspectsProvider --- src/Kdyby/Aop/DI/AopExtension.php | 39 ++++++++++++++ src/Kdyby/Aop/DI/AspectsConfig.php | 76 +++++++++++++++++++++++++++ src/Kdyby/Aop/DI/IAspectsProvider.php | 45 ++++++++++++++++ src/Kdyby/Aop/exceptions.php | 30 +++++++++++ 4 files changed, 190 insertions(+) create mode 100644 src/Kdyby/Aop/DI/AspectsConfig.php create mode 100644 src/Kdyby/Aop/DI/IAspectsProvider.php diff --git a/src/Kdyby/Aop/DI/AopExtension.php b/src/Kdyby/Aop/DI/AopExtension.php index bbdf9d5..577ee62 100644 --- a/src/Kdyby/Aop/DI/AopExtension.php +++ b/src/Kdyby/Aop/DI/AopExtension.php @@ -32,9 +32,36 @@ class_alias('Nette\Config\Configurator', 'Nette\Configurator'); class AopExtension extends Nette\DI\CompilerExtension { + const ASPECT_TAG = 'kdyby.aspect'; + + /** + * @var array + */ public $defaults = array(); + + public function loadConfiguration() + { + $builder = $this->getContainerBuilder(); + + foreach ($this->compiler->getExtensions() as $extension) { + if (!$extension instanceof IAspectsProvider) { + continue; + } + + if (!($config = $extension->getAspectsConfiguration()) || !$config instanceof AspectsConfig) { + $refl = new Nette\Reflection\Method($extension, 'getAspectsConfiguration'); + $given = is_object($config) ? 'instance of ' . get_class($config) : gettype($config); + throw new Kdyby\Aop\UnexpectedValueException("Method $refl is expected to return instance of \\Kdyby\\Aop\\DI\\AspectsConfig, but $given given."); + } + + $config->load($this->compiler, $builder); + } + } + + + public function beforeCompile() { $builder = $this->getContainerBuilder(); @@ -43,6 +70,18 @@ public function beforeCompile() + /** + * @param string $configFile + * @param Nette\DI\CompilerExtension $extension + * @return AspectsConfig + */ + public static function loadAspects($configFile, Nette\DI\CompilerExtension $extension) + { + return new AspectsConfig($extension->loadFromFile($configFile), $extension); + } + + + /** * @param \Nette\Configurator $configurator */ diff --git a/src/Kdyby/Aop/DI/AspectsConfig.php b/src/Kdyby/Aop/DI/AspectsConfig.php new file mode 100644 index 0000000..a5df552 --- /dev/null +++ b/src/Kdyby/Aop/DI/AspectsConfig.php @@ -0,0 +1,76 @@ + + */ +class AspectsConfig extends Nette\Object +{ + + /** + * @var array + */ + private $aspectsList; + + /** + * @var \Nette\DI\CompilerExtension + */ + private $extension; + + /** + * @var bool + */ + private $prefix = TRUE; + + + + public function __construct(array $aspectsList, Nette\DI\CompilerExtension $extension) + { + $this->aspectsList = $aspectsList; + $this->extension = $extension; + } + + + + public function disablePrefixing() + { + $this->prefix = FALSE; + + return $this; + } + + + + public function load(Nette\DI\Compiler $compiler, Nette\DI\ContainerBuilder $containerBuilder) + { + $aspects = array(); + foreach ($this->aspectsList as $def) { + if (!is_array($def)) { + if (!$def instanceof \stdClass || empty($def->entity)) { + $serialised = Nette\Utils\Json::encode($def); + throw new Kdyby\Aop\UnexpectedValueException("The service definition $serialised is expected to be an array or Neon entity."); + } + $def = array('factory' => $def); + } + $def['tags'][] = AopExtension::ASPECT_TAG; + $aspects[] = $def; + } + + $compiler->parseServices($containerBuilder, $aspects, $this->prefix ? substr($this->extension->prefix('self'), 0, -5) : NULL); + } + +} diff --git a/src/Kdyby/Aop/DI/IAspectsProvider.php b/src/Kdyby/Aop/DI/IAspectsProvider.php new file mode 100644 index 0000000..d01c4c1 --- /dev/null +++ b/src/Kdyby/Aop/DI/IAspectsProvider.php @@ -0,0 +1,45 @@ + + * class AclExtension extends Nette\DI\CompilerExtension implements \Kdyby\Aop\DI\IAspectsProvider + * { + * public function getAspectsConfiguration() + * { + * return \Kdyby\Aop\DI\AopExtension::loadAspects(__DIR__ . '/aspects.neon', $this); + * } + * } + * + * + * The `aspects.neon` file should be list of unnamed services + * + * + * @author Filip Procházka + */ +interface IAspectsProvider +{ + + /** + * @return AspectsConfig + */ + function getAspectsConfiguration(); + +} diff --git a/src/Kdyby/Aop/exceptions.php b/src/Kdyby/Aop/exceptions.php index 0e47d6d..c9676fd 100644 --- a/src/Kdyby/Aop/exceptions.php +++ b/src/Kdyby/Aop/exceptions.php @@ -29,3 +29,33 @@ class InvalidStateException extends \RuntimeException implements Exception { } + + + +/** + * @author Filip Procházka + */ +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ + +} + + + +/** + * @author Filip Procházka + */ +class UnexpectedValueException extends \UnexpectedValueException +{ + +} + + + +/** + * @author Filip Procházka + */ +class InvalidAspectExceptions extends \LogicException implements Exception +{ + +}