Browse Source

Add confirmation to batch action

Thomas Rabaix 13 years ago
parent
commit
8117c8d223

+ 4 - 1
Admin/Admin.php

@@ -765,7 +765,10 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
         $actions = array();
         $actions = array();
 
 
         if ($this->isGranted('DELETE')) {
         if ($this->isGranted('DELETE')) {
-            $actions['delete'] = $this->trans('action_delete', array(), 'SonataAdminBundle');
+            $actions['delete'] = array(
+                'label' => $this->trans('action_delete', array(), 'SonataAdminBundle'),
+                'ask_confirmation' => true, // by default always true
+            );
         }
         }
 
 
         return $actions;
         return $actions;

+ 36 - 7
Controller/CRUDController.php

@@ -148,14 +148,15 @@ class CRUDController extends Controller
         return $this->render($this->admin->getListTemplate(), array(
         return $this->render($this->admin->getListTemplate(), array(
             'action'   => 'list',
             'action'   => 'list',
             'form'     => $formView,
             'form'     => $formView,
-            'datagrid' => $this->admin->getDatagrid()
+            'datagrid' => $datagrid
         ));
         ));
     }
     }
 
 
     /**
     /**
      * execute a batch delete
      * execute a batch delete
      *
      *
-     * @param array $idx
+     * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException
+     * @param $query
      * @return \Symfony\Component\HttpFoundation\RedirectResponse
      * @return \Symfony\Component\HttpFoundation\RedirectResponse
      */
      */
     public function batchActionDelete($query)
     public function batchActionDelete($query)
@@ -296,9 +297,20 @@ class CRUDController extends Controller
            throw new \RuntimeException('invalid request type, POST expected');
            throw new \RuntimeException('invalid request type, POST expected');
         }
         }
 
 
-        $action       = $this->get('request')->get('action');
-        $idx          = $this->get('request')->get('idx');
-        $all_elements = $this->get('request')->get('all_elements', false);
+        if ($data = json_decode($this->get('request')->get('data'), true)) {
+            $action = $data['action'];
+            $idx    = $data['idx'];
+            $all_elements = $data['all_elements'];
+        } else {
+            $action       = $this->get('request')->get('action');
+            $idx          = $this->get('request')->get('idx');
+            $all_elements = $this->get('request')->get('all_elements', false);
+        }
+
+        $batchActions = $this->admin->getBatchActions();
+        if (!array_key_exists($action, $batchActions)) {
+            throw new \RuntimeException(sprintf('The `%s` batch action is not defined', $action));
+        }
 
 
         if (count($idx) == 0 && !$all_elements) { // no item selected
         if (count($idx) == 0 && !$all_elements) { // no item selected
             $this->get('session')->setFlash('sonata_flash_notice', 'flash_batch_empty');
             $this->get('session')->setFlash('sonata_flash_notice', 'flash_batch_empty');
@@ -306,8 +318,24 @@ class CRUDController extends Controller
             return new RedirectResponse($this->admin->generateUrl('list', $this->admin->getFilterParameters()));
             return new RedirectResponse($this->admin->generateUrl('list', $this->admin->getFilterParameters()));
         }
         }
 
 
-        if (!array_key_exists($action, $this->admin->getBatchActions())) {
-            throw new \RuntimeException(sprintf('The `%s` batch action is not defined', $action));
+        $askConfirmation = isset($batchActions[$action]['ask_confirmation']) ? $batchActions[$action]['ask_confirmation'] : true;
+
+        if ($askConfirmation && $this->get('request')->get('confirmation') != 'ok') {
+            $data = json_encode(array(
+                'action' => $action,
+                'idx'    => $idx,
+                'all_elements' => $all_elements,
+            ));
+
+            $datagrid = $this->admin->getDatagrid();
+            $formView = $datagrid->getForm()->createView();
+
+            return $this->render('SonataAdminBundle:CRUD:batch_confirmation.html.twig', array(
+                'action'   => 'list',
+                'datagrid' => $datagrid,
+                'form'     => $formView,
+                'data'     => $data,
+            ));
         }
         }
 
 
         // execute the action, batchActionXxxxx
         // execute the action, batchActionXxxxx
@@ -328,6 +356,7 @@ class CRUDController extends Controller
         if (count($idx) > 0) {
         if (count($idx) > 0) {
             $this->admin->getModelManager()->addIdentifiersToQuery($this->admin->getClass(), $query, $idx);
             $this->admin->getModelManager()->addIdentifiersToQuery($this->admin->getClass(), $query, $idx);
         }
         }
+
         return call_user_func(array($this, $final_action), $query);
         return call_user_func(array($this, $final_action), $query);
     }
     }
 
 

+ 2 - 2
Resources/views/CRUD/base_list.html.twig

@@ -115,8 +115,8 @@ file that was distributed with this source code.
 
 
                 <div class="sonata-ba-list-actions">
                 <div class="sonata-ba-list-actions">
                     <select name="action">
                     <select name="action">
-                        {% for action, label in batchactions %}
-                            <option value="{{ action }}">{{ label }}</option>
+                        {% for action, options in batchactions %}
+                            <option value="{{ action }}">{{ options.label }}</option>
                         {% endfor %}
                         {% endfor %}
                     </select>
                     </select>
                     <input type="checkbox" name="all_elements" id="execute_on_matching"  />
                     <input type="checkbox" name="all_elements" id="execute_on_matching"  />

+ 49 - 0
Resources/views/CRUD/batch_confirmation.html.twig

@@ -0,0 +1,49 @@
+{#
+
+This file is part of the Sonata package.
+
+(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+
+For the full copyright and license information, please view the LICENSE
+file that was distributed with this source code.
+
+#}
+
+{% extends base_template %}
+
+{% block actions %}
+    <div class="sonata-actions">
+        <ul>
+            {% if admin.hasRoute('list') and admin.isGranted('LIST')%}
+                <li class="sonata-action-element"><a href="{{ admin.generateUrl('list') }}">{% trans from 'SonataAdminBundle' %}link_action_list{% endtrans %}</a></li>
+            {% endif %}
+
+            {% if admin.hasRoute('create') and admin.isGranted('CREATE')%}
+                <li class="sonata-action-element"><a href="{{ admin.generateUrl('create') }}">{% trans from 'SonataAdminBundle' %}link_action_create{% endtrans %}</a></li>
+            {% endif %}
+        </ul>
+    </div>
+{% endblock %}
+
+{% block side_menu %}{{ admin.sidemenu(action)|knp_menu_render('list') }}{% endblock %}
+
+{% block content %}
+    <div class="sonata-ba-delete">
+
+        <h1>{% trans from 'SonataAdminBundle' %}title_batch_confirmation{% endtrans %}</h1>
+
+        {% trans from 'SonataAdminBundle' %}message_batch_confirmation{% endtrans %}
+
+        <form action="{{ admin.generateUrl('batch', admin.filterParameters) }}" method="POST" >
+            <input type="hidden" name="confirmation" value="ok" />
+            <input type="hidden" name="data" value="{{ data }}" />
+
+            <div style="display: none">
+                {{ form_rest(form) }}
+            </div>
+
+            <input type="submit" value="{% trans from 'SonataAdminBundle' %}btn_execute_batch_action{% endtrans %}" />
+        </form>
+
+    </div>
+{% endblock %}