SHARE
TWEET

Symfony2 article: AOP pointcut & interceptor

kutny May 23rd, 2013 215 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // V pointcutu definujeme, jaké třídy a metody má chceme naším aspektem "obalit". Obalení probíhá následně automaticky na úrovni DI containeru
  2. class LayoutFillerPointcut implements PointcutInterface {
  3.  
  4.         private $annotationReader;
  5.  
  6.         public function __construct(Reader $annotationReader) {
  7.                 $this->annotationReader = $annotationReader;
  8.         }
  9.  
  10.         /*
  11.          * Třídou LayoutFillerInterceptor obalujeme pouze třídy, jejich název končí na "Controller"
  12.          */
  13.         public function matchesClass(ReflectionClass $class) {
  14.                 return preg_match('~Controller$~', $class->getName());
  15.         }
  16.  
  17.         /*
  18.          * U "Controller" tříd aplikujeme metodu LayoutFillerInterceptor::intercept() na výstup:
  19.          * 1) všech veřejných metod
  20.          * 2) a zároveň metod, které mají v PHPDocs anotaci @FillLayout
  21.          */
  22.         public function matchesMethod(ReflectionMethod $method) {
  23.                 return
  24.                         $method->isPublic() &&
  25.                         $this->annotationReader->getMethodAnnotation(
  26.                                 $method,
  27.                                 'Templating\Annotation\FillLayout'
  28.                         ) !== null;
  29.         }
  30. }
  31.  
  32. // LayoutFillerInterceptor obaluje třídy, u jejichž metod použijeme anotaci
  33. class LayoutFillerInterceptor implements MethodInterceptorInterface {
  34.  
  35.         private $annotationReader;
  36.         private $container;
  37.  
  38.         public function __construct(Reader $annotationReader, ContainerInterface $container) {
  39.                 $this->annotationReader = $annotationReader;
  40.                 $this->container = $container;
  41.         }
  42.  
  43.         /*
  44.          * Metoda intercept() se aplikuje na výstup všech metod controllerů,
  45.          * které obsahují @FillLayout anotaci (viz LayoutFillerPointcut)
  46.          */
  47.         public function intercept(MethodInvocation $controllerInvocation) {
  48.                 $templateVariables = $controllerInvocation->proceed();
  49.  
  50.                 // přečteme anotaci, abychom získali název služby,
  51.                 // do které máme poslat výstup z volané metody controlleru
  52.                 /** @var FillLayout $annotation */
  53.                 $annotation = $this->annotationReader->getMethodAnnotation(
  54.                         $invocation->reflection,
  55.                         'Templating\Annotation\FillLayout'
  56.                 );
  57.  
  58.                 // v našem příkladu např. layout_filler.front
  59.                 $layoutFillerServiceName = $annotation->getServiceId();
  60.  
  61.                 /** @var ILayoutFiller $layoutFiller */
  62.                 $layoutFiller = $this->container->get($layoutFillerServiceName);
  63.                 return $layoutFiller->setDefaultVariables($templateVariables);
  64.         }
  65. }
  66.  
  67.  
  68. // Na závěr samotná jednoduchá definice anotace @FillLayout
  69. namespace Templating\Annotation;
  70.  
  71. /**
  72.  * @Annotation
  73.  */
  74. class FillLayout {
  75.  
  76.         private $serviceId;
  77.  
  78.         public function __construct($options) {
  79.                 $this->serviceId = $options['service'];
  80.         }
  81.  
  82.         public function getServiceId() {
  83.                 return $this->serviceId;
  84.         }
  85. }
RAW Paste Data
Top