19/06/2016 - SYMFONY
Bildiğimiz gib controller içinde kullanabileceğimiz "Method", "Route" vb. annotationlar var. Bu örneğimizde kendimize özgü kişisel bir tane annotation yaratacağız. Sadece belirtilen kişiler, belirli controller methodlarına ulaşabilecekler. Mesela ben sizin methodlardan birine ulaşmanızı engellemek istersem, isminizi annotation içinde listelemeyeceğim. Örnek bu kadar basit!
parameters:
player_names:
- Pele
- Zico
- Maradona
player_annotation_namespace: "Application\\FrontendBundle\\Annotation\\Player"
namespace Application\FrontendBundle\Annotation;
/**
* @Annotation
*/
class Player
{
/**
* @var array
*/
public $names = [];
/**
* @var string
*/
public $code = 403;
/**
* @var string
*/
public $message = 'Unauthorised player.';
}
Aşağıdaki @Player
annotation ayarlarına göre, ben sadece "Pele" ve "Zico" ismindeki kişilerin indexAction
methoduna ulaşmalarını sağlayacağım. Bununlar birlikte yukarıdaki "Player" classında belirtilen ve varsayılan olarak atanan Unauthorised player.
mesajını, annotation içinde Maradona is unauthorised player.
olarak değiştireceğim ama koda dokunmayacağım.
namespace Application\FrontendBundle\Controller;
use Application\FrontendBundle\Annotation\Player;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("player", service="application_frontend.controller.player")
*/
class PlayerController extends Controller
{
/**
* @@param Request $request
* @@param string $name
*
* @Method({"GET"})
*
* @Route("/{name}", requirements={"name" = "\w+"})
*
* @Player(names={"Pele", "Zico"}, message="Maradona is unauthorised player.")
*
* @return Response
*/
public function indexAction(Request $request, $name)
{
$country = $request->query->get('country', 'none');
return new Response(sprintf('%s is from %s national football team.', $name, $country));
}
}
namespace Application\FrontendBundle\Listener;
use Application\FrontendBundle\Annotation\Player;
use Doctrine\Common\Annotations\Reader;
use ReflectionObject;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
class AnnotationListener
{
private $reader;
private $playerNames;
private $playerAnnotationNamespace;
public function __construct(
Reader $reader,
array $playerNames,
$playerAnnotationNamespace
) {
$this->reader = $reader;
$this->playerNames = $playerNames;
$this->playerAnnotationNamespace = $playerAnnotationNamespace;
}
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
if (!is_array($controller) || !$event->isMasterRequest()) {
return;
}
$player = $this->getPlayer($event->getRequest());
$this->validatePlayer($controller, $player);
}
private function getPlayer(Request $request)
{
$routeParams = $request->attributes->get('_route_params');
if (!is_array($routeParams)) {
throw new BadRequestHttpException('Invalid request.');
}
if (!isset($routeParams['name'])) {
throw new MissingMandatoryParametersException('Missing name parameter.');
}
return $routeParams['name'];
}
private function validatePlayer(array $controller, $player)
{
$controllerReflection = new ReflectionObject($controller[0]);
$methodReflection = $controllerReflection->getMethod($controller[1]);
/** @var Player $playerAnnotation */
$playerAnnotation = $this->reader->getMethodAnnotation($methodReflection, $this->playerAnnotationNamespace);
if (!in_array($player, $playerAnnotation->names)) {
throw new BadRequestHttpException($playerAnnotation->message, null, $playerAnnotation->code);
}
}
}
services:
application_frontend.listener.annotation:
class: Application\FrontendBundle\Listener\AnnotationListener
arguments:
- @annotation_reader
- %player_names%
- %player_annotation_namespace%
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# Request
GET http://football.dev/app_dev.php/player/Pele?country=Brazil
# Response
200 OK
Pele is from Brazil national football team.
# Request
GET http://football.dev/app_dev.php/player/Zico?country=Brazil
# Response
200 OK
Zico is from Brazil national football team.
# Request
GET http://football.dev/app_dev.php/player/Maradona?country=Argentina
# Response
400 Bad Request
Maradona is unauthorised player.
400 Bad Request - BadRequestHttpException