<?php
namespace Flagception\Bundle\FlagceptionBundle\Listener;
use Flagception\Bundle\FlagceptionBundle\Annotations\Feature;
use Flagception\Manager\FeatureManagerInterface;
use Doctrine\Common\Annotations\Reader;
use ReflectionClass;
use ReflectionException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Class AnnotationSubscriber
*
* @author Michel Chowanski <michel.chowanski@bestit-online.de>
* @package Flagception\Bundle\FlagceptionBundle\Listener
*/
class AnnotationSubscriber implements EventSubscriberInterface
{
/**
* Annotation reader
*
* @var Reader
*/
private $reader;
/**
* The feature manager
*
* @var FeatureManagerInterface
*/
private $manager;
/**
* FeatureListener constructor.
*
* @param Reader $reader
* @param FeatureManagerInterface $manager
*/
public function __construct(Reader $reader, FeatureManagerInterface $manager)
{
$this->reader = $reader;
$this->manager = $manager;
}
/**
* Filter on controller / method
*
* @param ControllerEvent $event
*
* @return void
*
* @throws NotFoundHttpException
* @throws ReflectionException
*/
public function onKernelController(ControllerEvent $event)
{
$eventController = $event->getController();
$controller = is_array($eventController) === false && method_exists($eventController, '__invoke')
? [$eventController, '__invoke']
: $eventController;
/*
* $controller passed can be either a class or a Closure.
* This is not usual in Symfony2 but it may happen.
* If it is a class, it comes in array format
*/
if (!is_array($controller)) {
return;
}
$object = new ReflectionClass($controller[0]);
foreach ($this->reader->getClassAnnotations($object) as $annotation) {
if ($annotation instanceof Feature) {
if (!$this->manager->isActive($annotation->name)) {
throw new NotFoundHttpException('Feature for this class is not active.');
}
}
}
$method = $object->getMethod($controller[1]);
foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
if ($annotation instanceof Feature) {
if (!$this->manager->isActive($annotation->name)) {
throw new NotFoundHttpException('Feature for this method is not active.');
}
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
}