mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
221 lines
7.5 KiB
PHP
221 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace Chill\MainBundle\CRUD\Controller;
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
use Symfony\Component\Serializer\SerializerInterface;
|
|
use Chill\MainBundle\Serializer\Model\Collection;
|
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
|
|
class ApiController extends AbstractCRUDController
|
|
{
|
|
/**
|
|
* The view action.
|
|
*
|
|
* Some steps may be overriden during this process of rendering:
|
|
*
|
|
* This method:
|
|
*
|
|
* 1. fetch the entity, using `getEntity`
|
|
* 2. launch `onPostFetchEntity`. If postfetch is an instance of Response,
|
|
* this response is returned.
|
|
* 2. throw an HttpNotFoundException if entity is null
|
|
* 3. check ACL using `checkACL` ;
|
|
* 4. launch `onPostCheckACL`. If the result is an instance of Response,
|
|
* this response is returned ;
|
|
* 5. Serialize the entity and return the result. The serialization context is given by `getSerializationContext`
|
|
*
|
|
*/
|
|
protected function entityGet(string $action, Request $request, $id, $_format = 'html'): Response
|
|
{
|
|
$entity = $this->getEntity($action, $id, $request, $_format);
|
|
|
|
$postFetch = $this->onPostFetchEntity($action, $request, $entity, $_format);
|
|
|
|
if ($postFetch instanceof Response) {
|
|
return $postFetch;
|
|
}
|
|
|
|
if (NULL === $entity) {
|
|
throw $this->createNotFoundException(sprintf("The %s with id %s "
|
|
. "is not found", $this->getCrudName(), $id));
|
|
}
|
|
|
|
$response = $this->checkACL($action, $request, $_format, $entity);
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
$response = $this->onPostCheckACL($action, $request, $_format, $entity);
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
$response = $this->onBeforeSerialize($action, $request, $_format, $entity);
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
if ($_format === 'json') {
|
|
$context = $this->getContextForSerialization($action, $request, $_format, $entity);
|
|
|
|
return $this->json($entity, Response::HTTP_OK, [], $context);
|
|
} else {
|
|
throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This format is not implemented");
|
|
}
|
|
}
|
|
|
|
public function onBeforeSerialize(string $action, Request $request, $_format, $entity): ?Response
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Base method for handling api action
|
|
*
|
|
* @return void
|
|
*/
|
|
public function entityApi(Request $request, $id, $_format): Response
|
|
{
|
|
switch ($request->getMethod()) {
|
|
case Request::METHOD_GET:
|
|
case REQUEST::METHOD_HEAD:
|
|
return $this->entityGet('_entity', $request, $id, $_format);
|
|
default:
|
|
throw new \Symfony\Component\HttpFoundation\Exception\BadRequestException("This method is not implemented");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base action for indexing entities
|
|
*/
|
|
public function indexApi(Request $request, string $_format)
|
|
{
|
|
switch ($request->getMethod()) {
|
|
case Request::METHOD_GET:
|
|
case REQUEST::METHOD_HEAD:
|
|
return $this->indexApiAction('_index', $request, $_format);
|
|
default:
|
|
throw $this->createNotFoundException("This method is not supported");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build an index page.
|
|
*
|
|
* Some steps may be overriden during this process of rendering.
|
|
*
|
|
* This method:
|
|
*
|
|
* 1. Launch `onPreIndex`
|
|
* x. check acl. If it does return a response instance, return it
|
|
* x. launch `onPostCheckACL`. If it does return a response instance, return it
|
|
* 1. count the items, using `countEntities`
|
|
* 2. build a paginator element from the the number of entities ;
|
|
* 3. Launch `onPreIndexQuery`. If it does return a response instance, return it
|
|
* 3. build a query, using `queryEntities`
|
|
* x. fetch the results, using `getQueryResult`
|
|
* x. Launch `onPostIndexFetchQuery`. If it does return a response instance, return it
|
|
* 4. Serialize the entities in a Collection, using `SerializeCollection`
|
|
*
|
|
* @param string $action
|
|
* @param Request $request
|
|
* @return type
|
|
*/
|
|
protected function indexApiAction($action, Request $request, $_format)
|
|
{
|
|
$this->onPreIndex($action, $request, $_format);
|
|
|
|
$response = $this->checkACL($action, $request, $_format);
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
if (!isset($entity)) {
|
|
$entity = '';
|
|
}
|
|
|
|
$response = $this->onPostCheckACL($action, $request, $_format, $entity);
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
$totalItems = $this->countEntities($action, $request, $_format);
|
|
$paginator = $this->getPaginatorFactory()->create($totalItems);
|
|
|
|
$response = $this->onPreIndexBuildQuery($action, $request, $_format, $totalItems,
|
|
$paginator);
|
|
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
$query = $this->queryEntities($action, $request, $_format, $paginator);
|
|
|
|
$response = $this->onPostIndexBuildQuery($action, $request, $_format, $totalItems,
|
|
$paginator, $query);
|
|
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
$entities = $this->getQueryResult($action, $request, $_format, $totalItems, $paginator, $query);
|
|
|
|
$response = $this->onPostIndexFetchQuery($action, $request, $_format, $totalItems,
|
|
$paginator, $entities);
|
|
|
|
if ($response instanceof Response) {
|
|
return $response;
|
|
}
|
|
|
|
return $this->serializeCollection($action, $request, $_format, $paginator, $entities);
|
|
}
|
|
|
|
/**
|
|
* Serialize collections
|
|
*
|
|
*/
|
|
protected function serializeCollection(string $action, Request $request, string $_format, PaginatorInterface $paginator, $entities): Response
|
|
{
|
|
$model = new Collection($entities, $paginator);
|
|
|
|
$context = $this->getContextForSerialization($action, $request, $_format, $entities);
|
|
|
|
return $this->json($model, Response::HTTP_OK, [], $context);
|
|
}
|
|
|
|
|
|
protected function getContextForSerialization(string $action, Request $request, string $_format, $entity): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* get the role given from the config.
|
|
*/
|
|
protected function getRoleFor(string $action, Request $request, $entity, $_format): string
|
|
{
|
|
$actionConfig = $this->getActionConfig($action);
|
|
|
|
if (NULL !== $actionConfig['roles'][$request->getMethod()]) {
|
|
return $actionConfig['roles'][$request->getMethod()];
|
|
}
|
|
|
|
if ($this->crudConfig['base_role']) {
|
|
return $this->crudConfig['base_role'];
|
|
}
|
|
|
|
throw new \RuntimeException(sprintf("the config does not have any role for the ".
|
|
"method %s nor a global role for the whole action. Add those to your ".
|
|
"configuration or override the required method", $request->getMethod()));
|
|
|
|
}
|
|
|
|
protected function getSerializer(): SerializerInterface
|
|
{
|
|
return $this->get('serializer');
|
|
}
|
|
}
|