Regrouper des annotations Symfony
<?php | |
namespace App\Controller; | |
use App\Rest\Annotations\PaginationParams; | |
use FOS\RestBundle\Controller\Annotations as FOSRest; | |
use FOS\RestBundle\Request\ParamFetcherInterface; | |
class ArticleListController extends AbstractFOSRestController | |
{ | |
/** | |
* Ancienne méthode | |
* | |
* @FOSRest\QueryParam(name="_page", requirements="\d+", default=1) | |
* @FOSRest\QueryParam(name="_per_page, requirements="(10|20|50|100)", default=50) | |
* @FOSRest\QueryParam(name="_sort", requirements="-?[a-zA-Z_]+(\.[a-zA-Z_]+)?", default="id") | |
*/ | |
public function __invoke(ParamFetcherInterface $paramFetcher) | |
{ | |
$paramFetcher->get('_page'); | |
$paramFetcher->get('_per_page'); | |
$paramFetcher->get('_sort'); | |
} | |
/** | |
* Nouvelle méthode | |
* | |
* @PaginationParams() | |
*/ | |
public function __invoke(ParamFetcherInterface $paramFetcher) | |
{ | |
$paramFetcher->get('_page'); | |
$paramFetcher->get('_per_page'); | |
$paramFetcher->get('_sort'); | |
} | |
} |
<?php | |
namespace App\EventListener; | |
use App\Rest\ParamReader; | |
use FOS\RestBundle\FOSRestBundle; | |
use FOS\RestBundle\Request\ParamFetcherInterface; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
use Symfony\Component\HttpKernel\Event\ControllerEvent; | |
use Symfony\Component\HttpKernel\KernelEvents; | |
class GlobalParamFetcherSubscriber implements EventSubscriberInterface | |
{ | |
private $paramFetcher; | |
private $paramReader; | |
public static function getSubscribedEvents() | |
{ | |
return [ | |
KernelEvents::CONTROLLER => 'onKernelController', | |
]; | |
} | |
public function __construct(ParamFetcherInterface $paramFetcher, ParamReader $paramReader) | |
{ | |
$this->paramFetcher = $paramFetcher; | |
$this->paramReader = $paramReader; | |
} | |
public function onKernelController(ControllerEvent $event) | |
{ | |
$request = $event->getRequest(); | |
if (!$request->attributes->get(FOSRestBundle::ZONE_ATTRIBUTE, true)) { | |
return; | |
} | |
$controller = $event->getController(); | |
if (\is_callable($controller) && method_exists($controller, '__invoke')) { | |
$controller = [$controller, '__invoke']; | |
} | |
$annotations = $this->paramReader->read(new \ReflectionClass($controller[0]), $controller[1]); | |
foreach ($annotations as $annotation) { | |
foreach ($annotation->getAnnotationsInstances() as $fosRestAnnotation) { | |
$this->paramFetcher->addParam($fosRestAnnotation); | |
} | |
} | |
} | |
} |
<?php | |
namespace App\Rest\Annotations; | |
use FOS\RestBundle\Controller\Annotations\QueryParam; | |
/** | |
* @Annotation | |
*/ | |
class PaginationParams implements ParamInterface | |
{ | |
public $defaultSort = 'id'; | |
public function getAnnotationsInstances(): array | |
{ | |
return [ | |
$this->getPageParam(), | |
$this->getPerPageParam(), | |
$this->getSortParam(), | |
]; | |
} | |
public function getName(): string | |
{ | |
return 'pagination'; | |
} | |
private function getPageParam() | |
{ | |
$page = new QueryParam(); | |
$page->name = '_page'; | |
$page->requirements = "\d+"; | |
$page->default = 1; | |
return $page; | |
} | |
private function getPerPageParam() | |
{ | |
$perPage = new QueryParam(); | |
$perPage->name = '_per_page'; | |
$perPage->requirements = '(10|25|50|100)'; | |
$perPage->default = 50; | |
return $perPage; | |
} | |
private function getSortParam() | |
{ | |
$sort = new QueryParam(); | |
$sort->name = '_sort'; | |
$sort->requirements = '(\-)?[a-zA-Z_]+(\.[a-zA-Z_]+)?'; | |
$sort->default = $this->defaultSort; | |
return $sort; | |
} | |
} |
<?php | |
namespace App\Rest\Annotations; | |
use FOS\RestBundle\Controller\Annotations\QueryParam; | |
/** | |
* @Annotation | |
*/ | |
class PaginationParams implements ParamInterface | |
{ | |
public $defaultSort = 'id'; | |
public function getAnnotationsInstances(): array | |
{ | |
return [ | |
$this->getPageParam(), | |
$this->getPerPageParam(), | |
$this->getSortParam(), | |
$this->getLimitParam(), | |
]; | |
} | |
public function getName(): string | |
{ | |
return 'pagination'; | |
} | |
private function getPageParam() | |
{ | |
$page = new QueryParam(); | |
$page->name = '_page'; | |
$page->requirements = "\d+"; | |
$page->default = 1; | |
return $page; | |
} | |
private function getPerPageParam() | |
{ | |
$perPage = new QueryParam(); | |
$perPage->name = '_per_page'; | |
$perPage->requirements = '(10|25|50|100)'; | |
$perPage->default = 50; | |
return $perPage; | |
} | |
private function getSortParam() | |
{ | |
$sort = new QueryParam(); | |
$sort->name = '_sort'; | |
$sort->requirements = '(\-)?[a-zA-Z_]+(\.[a-zA-Z_]+)?'; | |
$sort->default = $this->defaultSort; | |
return $sort; | |
} | |
/** | |
* @deprecated use _per_page parameter instead | |
*/ | |
private function getLimitParam() | |
{ | |
$limit = new QueryParam(); | |
$limit->name = 'limit'; | |
$limit->requirements = '(10|25|50|100)'; | |
$limit->default = 50; | |
return $limit; | |
} | |
} |
<?php | |
namespace App\Rest\Annotations; | |
use FOS\RestBundle\Controller\Annotations\AbstractScalarParam; | |
interface ParamInterface | |
{ | |
/** | |
* @return AbstractScalarParam[] | |
*/ | |
public function getAnnotationsInstances(): array; | |
public function getName(): string; | |
} |
<?php | |
namespace App\Rest; | |
use App\Rest\Annotations\ParamInterface; | |
use Doctrine\Common\Annotations\Reader; | |
use FOS\RestBundle\Request\ParamReaderInterface; | |
class ParamReader implements ParamReaderInterface | |
{ | |
private $annotationReader; | |
public function __construct(Reader $annotationReader) | |
{ | |
$this->annotationReader = $annotationReader; | |
} | |
/** | |
* @return ParamInterface[] | |
*/ | |
public function read(\ReflectionClass $reflection, $method) | |
{ | |
if (!$reflection->hasMethod($method)) { | |
throw new \InvalidArgumentException(sprintf("Class '%s' has no method '%s'.", $reflection->getName(), $method)); | |
} | |
$methodParams = $this->getParamsFromMethod($reflection->getMethod($method)); | |
$classParams = $this->getParamsFromClass($reflection); | |
return array_merge($methodParams, $classParams); | |
} | |
public function getParamsFromMethod(\ReflectionMethod $method) | |
{ | |
$annotations = $this->annotationReader->getMethodAnnotations($method); | |
return $this->getParamsFromAnnotationArray($annotations); | |
} | |
public function getParamsFromClass(\ReflectionClass $class) | |
{ | |
$annotations = $this->annotationReader->getClassAnnotations($class); | |
return $this->getParamsFromAnnotationArray($annotations); | |
} | |
private function getParamsFromAnnotationArray(array $annotations) | |
{ | |
$params = []; | |
foreach ($annotations as $annotation) { | |
if ($annotation instanceof ParamInterface) { | |
$params[$annotation->getName()] = $annotation; | |
} | |
} | |
return $params; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment