CRUDController.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace WorkflowBundle\Controller;
  3. use Base\AdminBundle\Controller\CRUDController as BaseCRUDController;
  4. use Doctrine\Common\Inflector\Inflector;
  5. use Symfony\Component\HttpFoundation\RedirectResponse;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  8. use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
  9. use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
  10. class CRUDController extends BaseCRUDController
  11. {
  12. /**
  13. * Batch action.
  14. *
  15. * @return Response|RedirectResponse
  16. *
  17. * @throws NotFoundHttpException If the HTTP method is not POST
  18. * @throws \RuntimeException If the batch action is not defined
  19. */
  20. public function batchAction()
  21. {
  22. $request = $this->getRequest();
  23. $restMethod = $this->getRestMethod();
  24. if ('POST' !== $restMethod) {
  25. throw $this->createNotFoundException(sprintf('Invalid request type "%s", POST expected', $restMethod));
  26. }
  27. // check the csrf token
  28. $this->validateCsrfToken('sonata.batch');
  29. $confirmation = $request->get('confirmation', false);
  30. if ($data = json_decode($request->get('data'), true)) {
  31. $action = $data['action'];
  32. $idx = $data['idx'];
  33. $allElements = $data['all_elements'];
  34. $request->request->replace(array_merge($request->request->all(), $data));
  35. } else {
  36. $request->request->set('idx', $request->get('idx', array()));
  37. $request->request->set('all_elements', $request->get('all_elements', false));
  38. $action = $request->get('action');
  39. $idx = $request->get('idx');
  40. $allElements = $request->get('all_elements');
  41. $data = $request->request->all();
  42. unset($data['_sonata_csrf_token']);
  43. }
  44. // NEXT_MAJOR: Remove reflection check.
  45. $reflector = new \ReflectionMethod($this->admin, 'getBatchActions');
  46. if ($reflector->getDeclaringClass()->getName() === get_class($this->admin)) {
  47. @trigger_error('Override Sonata\AdminBundle\Admin\AbstractAdmin::getBatchActions method'
  48. . ' is deprecated since version 3.2.'
  49. . ' Use Sonata\AdminBundle\Admin\AbstractAdmin::configureBatchActions instead.'
  50. . ' The method will be final in 4.0.', E_USER_DEPRECATED
  51. );
  52. }
  53. $batchActions = $this->admin->getBatchActions();
  54. if (!array_key_exists($action, $batchActions)) {
  55. // ahora cheque los groups
  56. $actionGroup = $this->batchActionGroup($batchActions, $action);
  57. if ($actionGroup == null) {
  58. throw new \RuntimeException(sprintf('The `%s` batch action is not defined', $action));
  59. }
  60. } else {
  61. $actionGroup = null;
  62. }
  63. $camelizedAction = Inflector::classify($action);
  64. $isRelevantAction = sprintf('batchAction%sIsRelevant', $camelizedAction);
  65. if (method_exists($this, $isRelevantAction)) {
  66. $nonRelevantMessage = call_user_func(array($this, $isRelevantAction), $idx, $allElements, $request);
  67. } else {
  68. $nonRelevantMessage = count($idx) != 0 || $allElements; // at least one item is selected
  69. }
  70. if (!$nonRelevantMessage) { // default non relevant message (if false of null)
  71. $nonRelevantMessage = 'flash_batch_empty';
  72. }
  73. $datagrid = $this->admin->getDatagrid();
  74. $datagrid->buildPager();
  75. if (true !== $nonRelevantMessage) {
  76. $this->addFlash('sonata_flash_info', $nonRelevantMessage);
  77. return new RedirectResponse(
  78. $this->admin->generateUrl(
  79. 'list', array('filter' => $this->admin->getFilterParameters())
  80. )
  81. );
  82. }
  83. if ($actionGroup == null) {
  84. $askConfirmation = isset($batchActions[$action]['ask_confirmation']) ?
  85. $batchActions[$action]['ask_confirmation'] :
  86. true;
  87. } else {
  88. $askConfirmation = isset($actionGroup['ask_confirmation']) ?
  89. $actionGroup['ask_confirmation'] :
  90. true;
  91. }
  92. if ($askConfirmation && $confirmation != 'ok') {
  93. if ($actionGroup == null) {
  94. $actionLabel = $batchActions[$action]['label'];
  95. $batchTranslationDomain = isset($batchActions[$action]['translation_domain']) ?
  96. $batchActions[$action]['translation_domain'] :
  97. $this->admin->getTranslationDomain();
  98. } else {
  99. $actionLabel = $actionGroup['label'];
  100. $batchTranslationDomain = isset($actionGroup['translation_domain']) ?
  101. $actionGroup['translation_domain'] :
  102. $this->admin->getTranslationDomain();
  103. }
  104. $formView = $datagrid->getForm()->createView();
  105. $this->setFormTheme($formView, $this->admin->getFilterTheme());
  106. return $this->render($this->admin->getTemplate('batch_confirmation'), array(
  107. 'action' => 'list',
  108. 'action_label' => $actionLabel,
  109. 'batch_translation_domain' => $batchTranslationDomain,
  110. 'datagrid' => $datagrid,
  111. 'form' => $formView,
  112. 'data' => $data,
  113. 'csrf_token' => $this->getCsrfToken('sonata.batch'),
  114. ), null);
  115. }
  116. // execute the action, batchActionXxxxx
  117. $actionsParse = preg_split("/:/", $action);
  118. $workflowBatchAction = count($actionsParse) > 0 && $actionsParse[0] == 'workflow';
  119. if ($workflowBatchAction) {
  120. // es una transicion de workflow
  121. } else {
  122. $finalAction = sprintf('batchAction%s', $camelizedAction);
  123. if (!is_callable(array($this, $finalAction))) {
  124. throw new \RuntimeException(sprintf('A `%s::%s` method must be callable', get_class($this), $finalAction));
  125. }
  126. }
  127. $query = $datagrid->getQuery();
  128. $query->setFirstResult(null);
  129. $query->setMaxResults(null);
  130. $this->allElementsBatch = $allElements;
  131. $this->admin->preBatchAction($action, $query, $idx, $allElements);
  132. if (count($idx) > 0) {
  133. $this->admin->getModelManager()->addIdentifiersToQuery($this->admin->getClass(), $query, $idx);
  134. } elseif (!$allElements) {
  135. $query = null;
  136. }
  137. if ($workflowBatchAction) {
  138. return $this->runWorkflowBatchAction($actionsParse, $query);
  139. }
  140. return call_user_func(array($this, $finalAction), $query, $request);
  141. }
  142. /**
  143. * @param array $workflow
  144. * @param ProxyQueryInterface $selectedModelQuery
  145. *
  146. * @return RedirectResponse
  147. */
  148. public function runWorkflowBatchAction($workflow, ProxyQueryInterface $selectedModelQuery)
  149. {
  150. if ($this->isGranted('ROLE_SUPER_ADMIN') === false &&
  151. $this->admin->isGranted('EDIT') === false &&
  152. $this->admin->isGranted('DELETE') === false) {
  153. throw $this->createAccessDeniedException('You cannot access this page!');
  154. }
  155. $session = $this->get('session')->getFlashBag();
  156. $translator = $this->get('translator');
  157. try {
  158. $workflowRegistry = $this->get('workflow.registry');
  159. $em = $this->get('doctrine.orm.entity_manager');
  160. $selectedModels = $selectedModelQuery->execute();
  161. foreach ($selectedModels as $selectedModel) {
  162. if ($workflowRegistry->get($selectedModel, $workflow[1])->can($selectedModel, $workflow[2])) {
  163. $workflowName = "{$selectedModel->getWorkflowType()}.{$selectedModel->getWorkflowName()}";
  164. $this->get($workflowName)->apply($selectedModel, $workflow[2]);
  165. $em->persist($selectedModel);
  166. $em->flush($selectedModel);
  167. }
  168. }
  169. $session->add('sonata_flash_success', $translator->trans('flash_workflow_batch_success', array(), 'WorkflowBundle'));
  170. } catch (\Exception $e) {
  171. $session->add('sonata_flash_error', $translator->trans('flash_workflow_batch_error', array(), 'WorkflowBundle'));
  172. $session->add('sonata_flash_error', $e->getMessage());
  173. }
  174. return new RedirectResponse($this->admin->generateUrl('list', array('filter' => $this->admin->getFilterParameters())));
  175. }
  176. }