HelperController.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Controller;
  11. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  12. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\HttpFoundation\JsonResponse;
  15. use Symfony\Component\PropertyAccess\PropertyAccess;
  16. use Symfony\Component\PropertyAccess\PropertyPath;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\Validator\ValidatorInterface;
  19. use Sonata\AdminBundle\Admin\Pool;
  20. use Sonata\AdminBundle\Admin\AdminHelper;
  21. class HelperController
  22. {
  23. /**
  24. * @var \Twig_Environment
  25. */
  26. protected $twig;
  27. /**
  28. * @var \Sonata\AdminBundle\Admin\AdminHelper
  29. */
  30. protected $helper;
  31. /**
  32. * @var \Sonata\AdminBundle\Admin\Pool
  33. */
  34. protected $pool;
  35. /**
  36. * @var \Symfony\Component\Validator\ValidatorInterface
  37. */
  38. protected $validator;
  39. /**
  40. * @param \Twig_Environment $twig
  41. * @param \Sonata\AdminBundle\Admin\Pool $pool
  42. * @param \Sonata\AdminBundle\Admin\AdminHelper $helper
  43. * @param \Symfony\Component\Validator\ValidatorInterface $validator
  44. */
  45. public function __construct(\Twig_Environment $twig, Pool $pool, AdminHelper $helper, ValidatorInterface $validator)
  46. {
  47. $this->twig = $twig;
  48. $this->pool = $pool;
  49. $this->helper = $helper;
  50. $this->validator = $validator;
  51. }
  52. /**
  53. * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  54. *
  55. * @param \Symfony\Component\HttpFoundation\Request $request
  56. *
  57. * @return \Symfony\Component\HttpFoundation\Response
  58. */
  59. public function appendFormFieldElementAction(Request $request)
  60. {
  61. $code = $request->get('code');
  62. $elementId = $request->get('elementId');
  63. $objectId = $request->get('objectId');
  64. $uniqid = $request->get('uniqid');
  65. $admin = $this->pool->getInstance($code);
  66. $admin->setRequest($request);
  67. if ($uniqid) {
  68. $admin->setUniqid($uniqid);
  69. }
  70. $subject = $admin->getModelManager()->find($admin->getClass(), $objectId);
  71. if ($objectId && !$subject) {
  72. throw new NotFoundHttpException;
  73. }
  74. if (!$subject) {
  75. $subject = $admin->getNewInstance();
  76. }
  77. $admin->setSubject($subject);
  78. list($fieldDescription, $form) = $this->helper->appendFormFieldElement($admin, $subject, $elementId);
  79. /** @var $form \Symfony\Component\Form\Form */
  80. $view = $this->helper->getChildFormView($form->createView(), $elementId);
  81. // render the widget
  82. // todo : fix this, the twig environment variable is not set inside the extension ...
  83. $extension = $this->twig->getExtension('form');
  84. $extension->initRuntime($this->twig);
  85. $extension->renderer->setTheme($view, $admin->getFormTheme());
  86. return new Response($extension->renderer->searchAndRenderBlock($view, 'widget'));
  87. }
  88. /**
  89. * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  90. *
  91. * @param \Symfony\Component\HttpFoundation\Request $request
  92. *
  93. * @return \Symfony\Component\HttpFoundation\Response
  94. */
  95. public function retrieveFormFieldElementAction(Request $request)
  96. {
  97. $code = $request->get('code');
  98. $elementId = $request->get('elementId');
  99. $objectId = $request->get('objectId');
  100. $uniqid = $request->get('uniqid');
  101. $admin = $this->pool->getInstance($code);
  102. $admin->setRequest($request);
  103. if ($uniqid) {
  104. $admin->setUniqid($uniqid);
  105. }
  106. if ($objectId) {
  107. $subject = $admin->getModelManager()->find($admin->getClass(), $objectId);
  108. if (!$subject) {
  109. throw new NotFoundHttpException(sprintf('Unable to find the object id: %s, class: %s', $objectId, $admin->getClass()));
  110. }
  111. } else {
  112. $subject = $admin->getNewInstance();
  113. }
  114. $admin->setSubject($subject);
  115. $formBuilder = $admin->getFormBuilder($subject);
  116. $form = $formBuilder->getForm();
  117. $form->submit($request);
  118. $view = $this->helper->getChildFormView($form->createView(), $elementId);
  119. // render the widget
  120. // todo : fix this, the twig environment variable is not set inside the extension ...
  121. $extension = $this->twig->getExtension('form');
  122. $extension->initRuntime($this->twig);
  123. $extension->renderer->setTheme($view, $admin->getFormTheme());
  124. return new Response($extension->renderer->searchAndRenderBlock($view, 'widget'));
  125. }
  126. /**
  127. * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException|\RuntimeException
  128. *
  129. * @param \Symfony\Component\HttpFoundation\Request $request
  130. *
  131. * @return \Symfony\Component\HttpFoundation\Response
  132. */
  133. public function getShortObjectDescriptionAction(Request $request)
  134. {
  135. $code = $request->get('code');
  136. $objectId = $request->get('objectId');
  137. $uniqid = $request->get('uniqid');
  138. $linkParameters = $request->get('linkParameters', array());
  139. $admin = $this->pool->getInstance($code);
  140. if (!$admin) {
  141. throw new NotFoundHttpException();
  142. }
  143. $admin->setRequest($request);
  144. if ($uniqid) {
  145. $admin->setUniqid($uniqid);
  146. }
  147. $object = $admin->getObject($objectId);
  148. if (!$object && 'html' == $request->get('_format')) {
  149. return new Response();
  150. }
  151. if ('json' == $request->get('_format')) {
  152. return new JsonResponse(array('result' => array(
  153. 'id' => $admin->id($object),
  154. 'label' => $admin->toString($object)
  155. )));
  156. } elseif ('html' == $request->get('_format')) {
  157. return new Response($this->twig->render($admin->getTemplate('short_object_description'), array(
  158. 'admin' => $admin,
  159. 'description' => $admin->toString($object),
  160. 'object' => $object,
  161. 'link_parameters' => $linkParameters
  162. )));
  163. } else {
  164. throw new \RuntimeException('Invalid format');
  165. }
  166. }
  167. /**
  168. * @param \Symfony\Component\HttpFoundation\Request $request
  169. *
  170. * @return \Symfony\Component\HttpFoundation\Response
  171. */
  172. public function setObjectFieldValueAction(Request $request)
  173. {
  174. $field = $request->get('field');
  175. $code = $request->get('code');
  176. $objectId = $request->get('objectId');
  177. $value = $request->get('value');
  178. $context = $request->get('context');
  179. $admin = $this->pool->getInstance($code);
  180. $admin->setRequest($request);
  181. // alter should be done by using a post method
  182. if (!$request->isXmlHttpRequest()) {
  183. return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a XmlHttpRequest request header'));
  184. }
  185. if ($request->getMethod() != 'POST') {
  186. return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a POST Request'));
  187. }
  188. $rootObject = $object = $admin->getObject($objectId);
  189. if (!$object) {
  190. return new JsonResponse(array('status' => 'KO', 'message' => 'Object does not exist'));
  191. }
  192. // check user permission
  193. if (false === $admin->isGranted('EDIT', $object)) {
  194. return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid permissions'));
  195. }
  196. if ($context == 'list') {
  197. $fieldDescription = $admin->getListFieldDescription($field);
  198. } else {
  199. return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid context'));
  200. }
  201. if (!$fieldDescription) {
  202. return new JsonResponse(array('status' => 'KO', 'message' => 'The field does not exist'));
  203. }
  204. if (!$fieldDescription->getOption('editable')) {
  205. return new JsonResponse(array('status' => 'KO', 'message' => 'The field cannot be edit, editable option must be set to true'));
  206. }
  207. $propertyAccessor = PropertyAccess::createPropertyAccessor();
  208. $propertyPath = new PropertyPath($field);
  209. // If property path has more than 1 element, take the last object in order to validate it
  210. if ($propertyPath->getLength() > 1) {
  211. $object = $propertyAccessor->getValue($object, $propertyPath->getParent());
  212. $elements = $propertyPath->getElements();
  213. $field = end($elements);
  214. $propertyPath = new PropertyPath($field);
  215. }
  216. $propertyAccessor->setValue($object, $propertyPath, '' !== $value ? $value : null);
  217. $violations = $this->validator->validateProperty($object, $field);
  218. if (count($violations)) {
  219. $messages = array();
  220. foreach ($violations as $violation) {
  221. $messages[] = $violation->getMessage();
  222. }
  223. return new JsonResponse(array('status' => 'KO', 'message' => implode("\n", $messages)));
  224. }
  225. $admin->update($object);
  226. // render the widget
  227. // todo : fix this, the twig environment variable is not set inside the extension ...
  228. $extension = $this->twig->getExtension('sonata_admin');
  229. $extension->initRuntime($this->twig);
  230. $content = $extension->renderListElement($rootObject, $fieldDescription);
  231. return new JsonResponse(array('status' => 'OK', 'content' => $content));
  232. }
  233. }