Create a gist now

Instantly share code, notes, and snippets.

Custom annotations in Symfony2 (http://habrahabr.ru/blogs/symfony/133270/)
<?php
class DefaultController extends Controller
{
/**
* Dashboard page.
* @Permissions(perm="dashboard_view")
* @Route("/", name="ITEDashboardBundle_index")
* @Template()
* @return array
*/
public function indexAction()
{.......
<?php
namespace SomeNameSpace\SomeBundle\Annotations;
/**
* @Annotation
*/
class Permissions
{
public $perm;
}
<?php
namespace SomeNamespace\SomeBundle\Annotations\Driver;
use Doctrine\Common\Annotations\Reader;//This thing read annotations
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;//Use essential kernel component
use SomeNamespace\SomeBundle\Annotations;//Use our annotation
use SomeNamespace\SomeBundle\Security\Permission;//In this class I check correspondence permission to user
use Symfony\Component\HttpFoundation\Response;// For example I will throw 403, if access denied
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class AnnotationDriver{
private $reader;
public function __construct($reader)
{
$this->reader = $reader;//get annotations reader
}
/**
* This event will fire during any controller call
*/
public function onKernelController(FilterControllerEvent $event)
{
if (!is_array($controller = $event->getController())) { //return if no controller
return;
}
$object = new \ReflectionObject($controller[0]);// get controller
$method = $object->getMethod($controller[1]);// get method
foreach ($this->reader->getMethodAnnotations($method) as $configuration) { //Start of annotations reading
if(isset($configuration->perm)){//Found our annotation
$perm = new Permission($controller[0]->get('doctrine.odm.mongodb.document_manager'));
$userName = $controller[0]->get('security.context')->getToken()->getUser()->getUserName();
if(!$perm->isAccess($userName,$configuration->perm)){
//if any throw 403
throw new AccessDeniedHttpException();
}
}
}
}
}
# SomeBundle\config\services.yml
services:
some_annotation_driver:
class: SomeNamespace\SomeBundle\Annotations\Driver\AnnotationDriver #Point class
tags: [{name: kernel.event_listener, event: kernel.controller, method: onKernelController}] #Point event
arguments: [@annotation_reader] # Pass annotation_reader into constructor of our service
namespace SomeNamespace\SomeBundle\Controller;
use SomeNamespace\SomeBundle\Annotations\Permissions;
<?php
/**
* Dashboard controller.
*
* @Route("/dashboard")
*/
class DefaultController extends Controller
{
/**
* Dashboard page.
* @Permissions(perm="dashboard_view")
* @Route("/", name="ITEDashboardBundle_index")
* @Template()
* @return array
*/
public function indexAction()
{...}
}
@arcanis
arcanis commented Nov 30, 2012

Is there a way to make a redirection inside onKernelController ?

@Korpch
Korpch commented Feb 8, 2013

Try:

$event->setResponse($response);
@tgallice

Nice tips, have you an idea to list all IDs ?

@GeoffreyHervet

@tgallice all event ids ?

@dextervip

I am followed all steps but I put the annotation on method. I get this error:

FileLoaderImportCircularReferenceException in FileLoader.php line 97:
Circular reference detected in "C:\htdocs\pronaturalis\app/config/routing_dev.yml" ("C:\htdocs\pronaturalis\app/config/routing_dev.yml" > "C:\htdocs\pronaturalis\app/config\routing.yml" > "C:\htdocs\pronaturalis\src\MLM\Bundle\MLMBundle/Controller/" > "C:\htdocs\pronaturalis\app/config/routing_dev.yml").

Any idea what could be wrong? I am using Symfony 2.6

@Rezequiel

@dextervip I had the same error when I tried to create a service that provide me the annotation reader object to pass as an argument in the annotation driver service (all this because the service; @annotation_reader its not reconized) I solve this creating a class (AnnotationReaderSon) that extends Annotation Reader (from Doctrine Common), and then creating a service from the new class 'AnnotationReaderSon'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment