diff --git a/CRUD/Controller/CRUDController.php b/CRUD/Controller/CRUDController.php index 5e18cc47b..8df566f0d 100644 --- a/CRUD/Controller/CRUDController.php +++ b/CRUD/Controller/CRUDController.php @@ -28,6 +28,9 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Symfony\Component\Form\FormInterface; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Chill\MainBundle\Security\Authorization\AuthorizationHelper; +use Symfony\Component\Security\Core\Role\Role; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * @@ -129,9 +132,42 @@ class CRUDController extends AbstractController return $this->formEditAction('edit', $request, $id); } - protected function formEditAction($action, Request $request, $id, $formClass = null): Response + public function view(Request $request, $id): Response { - $entity = $this->getEntity($id, $request); + return $this->viewAction('view', $request, $id); + } + + protected function viewAction($action, Request $request, $id) + { + $entity = $this->getEntity($action, $id, $request); + + $postFetch = $this->onPostFetchEntity($action, $request, $entity); + + if ($postFetch instanceof Response) { + return $postFetch; + } + + $this->checkACL($action, $entity); + + $postCheckACL = $this->onPostCheckACL($action, $request, $entity); + + if ($postCheckACL instanceof Response) { + return $postCheckACL; + } + + $defaultTemplateParameters = [ + 'entity' => $entity + ]; + + return $this->render( + $this->getTemplateFor($action, $entity, $request), + $this->generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters) + ); + } + + protected function formEditAction($action, Request $request, $id, $formClass = null, $formOptions = []): Response + { + $entity = $this->getEntity($action, $id, $request); if (NULL === $entity) { throw $this->createNotFoundException(sprintf("The %s with id %s " @@ -140,7 +176,7 @@ class CRUDController extends AbstractController $this->checkACL($action, $entity); - $form = $this->createFormFor($action, $entity, $formClass); + $form = $this->createFormFor($action, $entity, $formClass, $formOptions); $form->handleRequest($request); @@ -165,7 +201,7 @@ class CRUDController extends AbstractController ]); } elseif ($form->isSubmitted()) { - $this->addFlash('error', $this->generateFormErrorMessage($form)); + $this->addFlash('error', $this->generateFormErrorMessage($action, $form)); } $defaultTemplateParameters = [ @@ -213,7 +249,7 @@ class CRUDController extends AbstractController return $this->redirectToRoute('chill_crud_'.$this->get, ['id' => $entity->getId()]); } elseif ($form->isSubmitted()) { - $this->addFlash('error', $this->generateFormErrorMessage($form)); + $this->addFlash('error', $this->generateFormErrorMessage($action, $form)); } $defaultTemplateParameters = [ @@ -233,11 +269,14 @@ class CRUDController extends AbstractController * @param string $id * @return object */ - protected function getEntity($id, Request $request): ?object + protected function getEntity($action, $id, Request $request): ?object { return $this->getDoctrine() ->getRepository($this->getEntityClass()) ->find($id); + + + } protected function getEntityClass(): string @@ -279,18 +318,29 @@ class CRUDController extends AbstractController ?? $this->crudConfig['form_class']; } - protected function createFormFor($action, $entity, $formClass = null) + protected function createFormFor($action, $entity, $formClass = null, $formOptions = []) { $formClass = $formClass ?? $this->getFormClassFor($action); - $form = $this->createForm($formClass, $entity); - $form->add('submit', SubmitType::class, [ - 'label' => $action - ]); + $form = $this->createForm($formClass, $entity, $formOptions); + + $this->addDefaultButtons($action, $form); return $form; } + protected function addDefaultButtons($action, FormInterface $form) + { + $form->add('submit', SubmitType::class, [ + 'label' => $this->generateLabelForButton($action, 'submit', $form) + ]); + } + + protected function generateLabelForButton($action, $formName, $form) + { + return $action; + } + protected function generateFormErrorMessage($action, FormInterface $form): string { $msg = 'This form contains errors'; @@ -365,6 +415,16 @@ class CRUDController extends AbstractController { } + protected function onPostFetchEntity($action, Request $request, $entity): ?Response + { + return null; + } + + protected function onPostCheckACL($action, Request $request, $entity): ?Response + { + return null; + } + protected function onFormValid(object $entity, FormInterface $form, Request $request) { } @@ -383,6 +443,23 @@ class CRUDController extends AbstractController return $this->container->get('translator'); } + protected function getAuthorizationHelper(): AuthorizationHelper + { + return $this->container->get(AuthorizationHelper::class); + } + + protected function getReachableCenters(Role $role, Scope $scope = null) + { + return $this->getAuthorizationHelper() + ->getReachableCenters($this->getUser(), $role, $scope) + ; + } + + protected function getEventDispatcher(): EventDispatcherInterface + { + return $this->get(EventDispatcherInterface::class); + } + public static function getSubscribedServices() { return \array_merge( @@ -390,7 +467,9 @@ class CRUDController extends AbstractController [ PaginatorFactory::class => PaginatorFactory::class, 'translator' => TranslatorInterface::class, + AuthorizationHelper::class => AuthorizationHelper::class, + EventDispatcherInterface::class => EventDispatcherInterface::class, ] - ); + ); } } diff --git a/CRUD/Routing/CRUDRoutesLoader.php b/CRUD/Routing/CRUDRoutesLoader.php index adc5d6420..3ff7959d3 100644 --- a/CRUD/Routing/CRUDRoutesLoader.php +++ b/CRUD/Routing/CRUDRoutesLoader.php @@ -51,7 +51,7 @@ class CRUDRoutesLoader public function load() { $collection = new RouteCollection(); - + foreach ($this->config as $config) { $collection->addCollection($this->loadConfig($config)); } @@ -63,23 +63,23 @@ class CRUDRoutesLoader { $collection = new RouteCollection(); - foreach ($config['actions'] as $action) { + foreach ($config['actions'] as $name => $action) { $defaults = [ - '_controller' => $config['controller'].'::'.$action + '_controller' => $action['controller'] ?? $config['controller'].'::'.$name ]; if ($action === 'index') { $path = "{_locale}".$config['base_path']; $route = new Route($path, $defaults); } else { - $path = "{_locale}".$config['base_path'].'/{id}/'.$action; - $requirements = [ + $path = "{_locale}".$config['base_path'].($action['path'] ?? '/{id}/'.$name); + $requirements = $action['requirements'] ?? [ '{id}' => '\d+' ]; $route = new Route($path, $defaults, $requirements); } - $collection->add('chill_crud_'.$config['name'].'_'.$action, $route); + $collection->add('chill_crud_'.$config['name'].'_'.$name, $route); } return $collection; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 089ed42dc..1e4d410ce 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -127,9 +127,32 @@ class Configuration implements ConfigurationInterface ->scalarNode('base_role')->defaultNull()->end() ->scalarNode('form_class')->defaultNull()->end() ->arrayNode('actions') - ->scalarPrototype()->end() - ->defaultValue(['index', 'new', 'edit', 'show', 'delete']) + ->defaultValue([ + 'edit' => [], + 'new' => [] + ]) + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('controller') + ->defaultValue('') + ->info('the method name to call in the route. Will be set to the action name if left empty.') + ->example("'MyBundle\Controller\MyCrudController::action'") + ->end() + ->scalarNode('path') + ->defaultValue('') + ->info('the path that will be **appended** after the base path. Do not forget to add ' + . 'arguments for the method. Will be set to the action name, including an `{id}` ' + . 'parameter if left empty.') + ->example('/{id}/my-action') + ->end() + ->arrayNode('requirements') + ->ignoreExtraKeys(false) + ->info('the requirements for the route. Will be set to `[ \'id\' => \'\d+\' ]` if left empty.') + ->end() + ->end() ->end() + ->end() ->end() ->end() diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 6b7cda525..b8990fca0 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -34,6 +34,7 @@ Save: Enregistrer This form contains errors: Ce formulaire contient des erreurs Choose an user: Choisir un utilisateur 'You are going to leave a page with unsubmitted data. Are you sure you want to leave ?': "Vous allez quitter la page alors que des données n'ont pas été enregistrées. Êtes vous sûr de vouloir partir ?" +No value: Aucune information Edit: Modifier Update: Mettre à jour diff --git a/Resources/views/CRUD/_edit_content.html.twig b/Resources/views/CRUD/_edit_content.html.twig index f8afadcba..9dcb7820a 100644 --- a/Resources/views/CRUD/_edit_content.html.twig +++ b/Resources/views/CRUD/_edit_content.html.twig @@ -5,22 +5,24 @@ {% block crud_content_form %} {{ form_start(form) }} + + {% block crud_content_form_rows %} {% for f in form if f.vars.name != 'submit' %} {{ form_row(f) }} {% endfor %} + {% endblock crud_content_form_rows %} {% block crud_content_form_actions %} -
+ {% endblock %} {{ form_end(form) }}