From d4b498e2be13d19cafdd567884395c8d6d165c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 26 Mar 2020 13:14:48 +0100 Subject: [PATCH] [crud] add step "delete" --- CHANGELOG.md | 3 +- CRUD/Controller/CRUDController.php | 103 ++++++++++++++++++ CRUD/Form/CRUDDeleteEntityForm.php | 33 ++++++ Resources/translations/messages.fr.yml | 3 + .../views/CRUD/_delete_content.html.twig | 37 +++++++ Resources/views/CRUD/_edit_content.html.twig | 13 ++- Resources/views/CRUD/_view_content.html.twig | 15 ++- Resources/views/CRUD/delete.html.twig | 8 ++ 8 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 CRUD/Form/CRUDDeleteEntityForm.php create mode 100644 Resources/views/CRUD/_delete_content.html.twig create mode 100644 Resources/views/CRUD/delete.html.twig diff --git a/CHANGELOG.md b/CHANGELOG.md index ec47315d6..b44316453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,5 +110,6 @@ Master branch ============= - [translation] in french, replace "Modifier" by "Enregistrer" in the edit form -- [chill entity render] fix error when fallback to default entity render (usage of __toString()) +- [chill entity render] fix error when fallback to default entity render (usage of `__toString()`) +- [CRUD] add step delete diff --git a/CRUD/Controller/CRUDController.php b/CRUD/Controller/CRUDController.php index e9dfc3845..c7d4586d4 100644 --- a/CRUD/Controller/CRUDController.php +++ b/CRUD/Controller/CRUDController.php @@ -33,6 +33,7 @@ use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Chill\MainBundle\CRUD\Resolver\Resolver; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\CRUD\Form\CRUDDeleteEntityForm; /** * @@ -54,6 +55,93 @@ class CRUDController extends AbstractController $this->crudConfig = $config; } + public function delete(Request $request, $id) + { + return $this->deleteAction('delete', $request, $id); + } + + protected function deleteAction(string $action, Request $request, $id, $formClass = null) + { + $this->onPreDelete($action, $request, $id); + + $entity = $this->getEntity($action, $id, $request); + + $postFetch = $this->onPostFetchEntity($action, $request, $entity); + + 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, $entity); + if ($response instanceof Response) { + return $response; + } + + $response = $this->onPostCheckACL($action, $request, $entity); + if ($response instanceof Response) { + return $response; + } + + $form = $this->createFormFor($action, $entity, $formClass); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->onFormValid($entity, $form, $request); + $em = $this->getDoctrine()->getManager(); + + $this->onPreRemove($action, $entity, $form, $request); + $this->removeEntity($action, $entity, $form, $request); + $this->onPostRemove($action, $entity, $form, $request); + + $this->onPreFlush($action, $entity, $form, $request); + $em->flush(); + $this->onPostFlush($action, $entity, $form, $request); + + $this->addFlash('success', $this->generateFormSuccessMessage($action, $entity)); + + $result = $this->onBeforeRedirectAfterSubmission($action, $entity, $form, $request); + + if ($result instanceof Response) { + return $result; + } + + return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_view', ['id' => $entity->getId()]); + + } elseif ($form->isSubmitted()) { + $this->addFlash('error', $this->generateFormErrorMessage($action, $form)); + } + + $defaultTemplateParameters = [ + 'form' => $form->createView(), + 'entity' => $entity, + 'crud_name' => $this->getCrudName() + ]; + + return $this->render( + $this->getTemplateFor($action, $entity, $request), + $this->generateTemplateParameter($action, $entity, $request, $defaultTemplateParameters) + ); + } + + protected function onPreDelete(string $action, Request $request) {} + + protected function onPreRemove(string $action, $entity, FormInterface $form, Request $request) {} + + protected function onPostRemove(string $action, $entity, FormInterface $form, Request $request) {} + + protected function removeEntity(string $action, $entity, FormInterface $form, Request $request) + { + $this->getDoctrine() + ->getManager() + ->remove($entity); + } + /** * Base method called by index action. * @@ -673,10 +761,20 @@ class CRUDController extends AbstractController */ protected function getFormClassFor($action) { + if ($action === 'delete') { + return $this->crudConfig[$action]['form_class'] + ?? $this->getDefaultDeleteFormClass($action); + } + return $this->crudConfig[$action]['form_class'] ?? $this->crudConfig['form_class']; } + protected function getDefaultDeleteFormClass($action) + { + return CRUDDeleteEntityForm::class; + } + /** * Create a form * @@ -748,6 +846,9 @@ class CRUDController extends AbstractController case 'new': $msg = "crud.new.success"; break; + case 'delete': + $msg = "crud.delete.success"; + break; default: $msg = "crud.default.success"; } @@ -815,6 +916,8 @@ class CRUDController extends AbstractController return '@ChillMain/CRUD/index.html.twig'; case 'view': return '@ChillMain/CRUD/view.html.twig'; + case 'delete': + return '@ChillMain/CRUD/delete.html.twig'; default: throw new \LogicException("the view for action $action is not " . "defined. You should override ".__METHOD__." to add this " diff --git a/CRUD/Form/CRUDDeleteEntityForm.php b/CRUD/Form/CRUDDeleteEntityForm.php new file mode 100644 index 000000000..609b56f58 --- /dev/null +++ b/CRUD/Form/CRUDDeleteEntityForm.php @@ -0,0 +1,33 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +namespace Chill\MainBundle\CRUD\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; + + +/** + * + * + */ +class CRUDDeleteEntityForm extends AbstractType +{ +} diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 7f96e0d24..de70316fe 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -246,6 +246,9 @@ crud: save_and_close: Enregistrer & fermer save_and_show: Enregistrer & voir success: Les données ont été modifiées + delete: + success: Les données ont été supprimées + link_to_form: Supprimer default: success: Les données ont été enregistrées view: diff --git a/Resources/views/CRUD/_delete_content.html.twig b/Resources/views/CRUD/_delete_content.html.twig new file mode 100644 index 000000000..5baba11ea --- /dev/null +++ b/Resources/views/CRUD/_delete_content.html.twig @@ -0,0 +1,37 @@ +
+ {% block crud_content_header %} +

{{ ('crud.'~crud_name~'.title_delete')|trans({ '%as_string%': entity|chill_entity_render_string }) }}

+ {% endblock crud_content_header %} + +

{{ ('crud.'~crud_name~'.confirm_message_delete')|trans({ '%as_string%': entity|chill_entity_render_string }) }}

+ + {{ form_start(form) }} + +
    + {% block content_form_actions_back %} +
  • + + {{ 'Cancel'|trans }} + +
  • + {% endblock %} + {% block content_form_actions_before %}{% endblock %} + {% block content_form_actions_view %} + {% if is_granted(chill_crud_config('role', crud_name, 'view'), entity) %} +
  • + + {{ 'crud.edit.back_to_view'|trans }} + +
  • + {% endif %} + {% endblock %} + {% block content_form_actions_confirm_delete %} +
  • + +
  • + {% endblock content_form_actions_confirm_delete %} + {% block content_form_actions_after %}{% endblock %} +
+ + {{ form_end(form) }} +
diff --git a/Resources/views/CRUD/_edit_content.html.twig b/Resources/views/CRUD/_edit_content.html.twig index ce8aa87c4..c1a1c0052 100644 --- a/Resources/views/CRUD/_edit_content.html.twig +++ b/Resources/views/CRUD/_edit_content.html.twig @@ -22,15 +22,20 @@ {% endblock %} {% block content_form_actions_before %}{% endblock %} + {% block content_form_actions_delete %} + {% if is_granted(chill_crud_config('role', crud_name, 'delete'), entity) %} +
  • + +
  • + {% endif %} + {% endblock content_form_actions_delete %} {% block content_form_actions_view %} {% if is_granted(chill_crud_config('role', crud_name, 'view'), entity) %}
  • - - {{ 'crud.edit.back_to_view'|trans }} - +
  • {% endif %} - {% endblock %} + {% endblock content_form_actions_view %} {% block content_form_actions_save_and_close %}
  • {% endblock %} {% block content_view_actions_before %}{% endblock %} + {% block content_form_actions_delete %} + {% if is_granted(chill_crud_config('role', crud_name, 'delete'), entity) %} +
  • + + {{ 'crud.delete.link_to_form'|trans }} + +
  • + {% endif %} + {% endblock content_form_actions_delete %} {% block content_view_actions_duplicate_link %} {% if is_granted(chill_crud_config('role', crud_name, 'new'), entity) %}
  • - + {{ 'crud.view.link_duplicate'|trans }}
  • {% endif %} {% endblock content_view_actions_duplicate_link %} {% block content_view_actions_edit_link %} - {% if is_granted(chill_crud_config('role', crud_name, 'view'), entity) %} + {% if is_granted(chill_crud_config('role', crud_name, 'edit'), entity) %}
  • - + {{ 'crud.new.link_edit'|trans }}
  • diff --git a/Resources/views/CRUD/delete.html.twig b/Resources/views/CRUD/delete.html.twig new file mode 100644 index 000000000..ab440a602 --- /dev/null +++ b/Resources/views/CRUD/delete.html.twig @@ -0,0 +1,8 @@ +{% extends '@ChillMain/layout.html.twig' %} + +{% block title %}{{ ('crud.' ~ crud_name ~ '.delete.title')|trans({'%crud_name%': crud_name}) }}{% endblock %} + +{% block content %} + {% embed '@ChillMain/CRUD/_delete_content.html.twig' %} + {% endembed %} +{% endblock content %} \ No newline at end of file