getRequest(); $restMethod = $this->getRestMethod(); if ('POST' !== $restMethod) { throw $this->createNotFoundException(sprintf('Invalid request type "%s", POST expected', $restMethod)); } // check the csrf token $this->validateCsrfToken('sonata.batch'); $confirmation = $request->get('confirmation', false); if ($data = json_decode($request->get('data'), true)) { $action = $data['action']; $idx = $data['idx']; $allElements = $data['all_elements']; $request->request->replace(array_merge($request->request->all(), $data)); } else { $request->request->set('idx', $request->get('idx', array())); $request->request->set('all_elements', $request->get('all_elements', false)); $action = $request->get('action'); $idx = $request->get('idx'); $allElements = $request->get('all_elements'); $data = $request->request->all(); unset($data['_sonata_csrf_token']); } // NEXT_MAJOR: Remove reflection check. $reflector = new \ReflectionMethod($this->admin, 'getBatchActions'); if ($reflector->getDeclaringClass()->getName() === get_class($this->admin)) { @trigger_error('Override Sonata\AdminBundle\Admin\AbstractAdmin::getBatchActions method' . ' is deprecated since version 3.2.' . ' Use Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions instead.' . ' The method will be final in 4.0.', E_USER_DEPRECATED ); } $batchActions = $this->admin->getBatchActions(); if (!array_key_exists($action, $batchActions)) { throw new \RuntimeException(sprintf('The `%s` batch action is not defined', $action)); } $camelizedAction = Inflector::classify($action); $isRelevantAction = sprintf('batchAction%sIsRelevant', $camelizedAction); if (method_exists($this, $isRelevantAction)) { $nonRelevantMessage = call_user_func(array($this, $isRelevantAction), $idx, $allElements, $request); } else { $nonRelevantMessage = count($idx) != 0 || $allElements; // at least one item is selected } if (!$nonRelevantMessage) { // default non relevant message (if false of null) $nonRelevantMessage = 'flash_batch_empty'; } $datagrid = $this->admin->getDatagrid(); $datagrid->buildPager(); if (true !== $nonRelevantMessage) { $this->addFlash('sonata_flash_info', $nonRelevantMessage); return new RedirectResponse( $this->admin->generateUrl( 'list', array('filter' => $this->admin->getFilterParameters()) ) ); } $askConfirmation = isset($batchActions[$action]['ask_confirmation']) ? $batchActions[$action]['ask_confirmation'] : true; if ($askConfirmation && $confirmation != 'ok') { $actionLabel = $batchActions[$action]['label']; $batchTranslationDomain = isset($batchActions[$action]['translation_domain']) ? $batchActions[$action]['translation_domain'] : $this->admin->getTranslationDomain(); $formView = $datagrid->getForm()->createView(); $this->setFormTheme($formView, $this->admin->getFilterTheme()); return $this->render($this->admin->getTemplate('batch_confirmation'), array( 'action' => 'list', 'action_label' => $actionLabel, 'batch_translation_domain' => $batchTranslationDomain, 'datagrid' => $datagrid, 'form' => $formView, 'data' => $data, 'csrf_token' => $this->getCsrfToken('sonata.batch'), ), null); } $workflowBatchAction = isset($batchActions[$action]['workflow']) ?: false; // execute the action, batchActionXxxxx $finalAction = sprintf('batchAction%s', $camelizedAction); if (!is_callable(array($this, $finalAction)) && !$workflowBatchAction) { throw new \RuntimeException(sprintf('A `%s::%s` method must be callable', get_class($this), $finalAction)); } $query = $datagrid->getQuery(); $query->setFirstResult(null); $query->setMaxResults(null); $this->allElementsBatch = $allElements; $this->admin->preBatchAction($action, $query, $idx, $allElements); if (count($idx) > 0) { $this->admin->getModelManager()->addIdentifiersToQuery($this->admin->getClass(), $query, $idx); } elseif (!$allElements) { $query = null; } if ($workflowBatchAction) { return $this->runWorkflowBatchAction($batchActions[$action]['workflow'], $query); } return call_user_func(array($this, $finalAction), $query, $request); } /** * @param array $workflow * @param ProxyQueryInterface $selectedModelQuery * * @return RedirectResponse */ public function runWorkflowBatchAction($workflow, ProxyQueryInterface $selectedModelQuery) { if ($this->admin->isGranted('EDIT') === false || $this->admin->isGranted('DELETE') === false) { throw new AccessDeniedException(); } $session = $this->get('session')->getFlashBag(); $translator = $this->get('translator'); try { $workflowRegistry = $this->get('workflow.registry'); $em = $this->get('doctrine.orm.entity_manager'); $selectedModels = $selectedModelQuery->execute(); foreach ($selectedModels as $selectedModel) { if ($workflowRegistry->get($selectedModel, $workflow['name'])->can($selectedModel, $workflow['transition'])) { $workflowName = "{$selectedModel->getWorkflowType()}.{$selectedModel->getWorkflowName()}"; $this->get($workflowName)->apply($selectedModel, $workflow['transition']); $em->persist($selectedModel); $em->flush($selectedModel); } } $session->add('sonata_flash_success', $translator->trans('flash_workflow_batch_success', array(), 'WorkflowBundle')); } catch (\Exception $e) { $session->add('sonata_flash_error', $translator->trans('flash_workflow_batch_error', array(), 'WorkflowBundle')); $session->add('sonata_flash_error', $e->getMessage()); } return new RedirectResponse($this->admin->generateUrl('list', array('filter' => $this->admin->getFilterParameters()))); } }