AdminHelper.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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\Admin;
  11. use Symfony\Component\Form\FormBuilder;
  12. class AdminHelper
  13. {
  14. protected $pool;
  15. /**
  16. * @param Pool $pool
  17. */
  18. public function __construct(Pool $pool)
  19. {
  20. $this->pool = $pool;
  21. }
  22. /**
  23. * @throws \RuntimeException
  24. * @param \Symfony\Component\Form\FormBuilder $formBuider
  25. * @param $elementId
  26. * @return \Symfony\Component\Form\FormBuilder
  27. */
  28. public function getChildFormBuilder(FormBuilder $formBuider, $elementId)
  29. {
  30. // todo : warning this introduce a bug if the field name = 'field_name',
  31. // add a check to field will always be 'fieldName'
  32. $elements = explode('_', $elementId);
  33. // always remove the first element : form's name
  34. array_shift($elements);
  35. while ($elementName = array_shift($elements)) {
  36. if (!$formBuider->has($elementName)) {
  37. throw new \RuntimeException(sprintf('The element `%s` does not exists', $elementName));
  38. }
  39. $formBuider = $formBuider->get($elementName);
  40. }
  41. return $formBuider;
  42. }
  43. /**
  44. * @param string $code
  45. * @return \Sonata\AdminBundle\Admin\AdminInterface
  46. */
  47. public function getAdmin($code)
  48. {
  49. return $this->pool->getInstance($code);
  50. }
  51. /**
  52. * Note:
  53. * This code is ugly, but there is no better way of doing it.
  54. * For now the append form element action used to add a new row works
  55. * only for direct FieldDescription (not nested one)
  56. *
  57. * @throws \RuntimeException
  58. * @param \Sonata\AdminBundle\Admin\AdminInterface $admin
  59. * @param $elementId
  60. * @return void
  61. */
  62. public function appendFormFieldElement(AdminInterface $admin, $elementId)
  63. {
  64. // retrieve the subject
  65. $formBuilder = $admin->getFormBuilder();
  66. $form = $formBuilder->getForm();
  67. $form->bindRequest($admin->getRequest());
  68. // get the field element
  69. $childFormBuilder = $this->getChildFormBuilder($formBuilder, $elementId);
  70. // retrieve the FieldDescription
  71. $fieldDescription = $admin->getFormFieldDescription($childFormBuilder->getName());
  72. $value = $fieldDescription->getValue($form->getData());
  73. // retrieve the posted data
  74. $data = $admin->getRequest()->get($formBuilder->getName());
  75. if (!isset($data[$childFormBuilder->getName()])) {
  76. $data[$childFormBuilder->getName()] = array();
  77. }
  78. $objectCount = count($value);
  79. $postCount = count($data[$childFormBuilder->getName()]);
  80. $fields = array_keys($fieldDescription->getAssociationAdmin()->getFormFieldDescriptions());
  81. // for now, not sure how to do that
  82. $value = array();
  83. foreach ($fields as $name) {
  84. $value[$name] = '';
  85. }
  86. // add new elements to the subject
  87. while($objectCount < $postCount) {
  88. // append a new instance into the object
  89. $this->addNewInstance($form->getData(), $fieldDescription);
  90. $objectCount++;
  91. }
  92. $this->addNewInstance($form->getData(), $fieldDescription);
  93. $data[$childFormBuilder->getName()][] = $value;
  94. $form = $admin->getFormBuilder($form->getData())->getForm();
  95. // bind the data
  96. $form->bind($data);
  97. $admin->setSubject($form->getData());
  98. return array($fieldDescription, $formBuilder);
  99. }
  100. /**
  101. * Add a new instance to the related FieldDescriptionInterface value
  102. *
  103. * @param object $object
  104. * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription
  105. * @return void
  106. */
  107. public function addNewInstance($object, FieldDescriptionInterface $fieldDescription)
  108. {
  109. $instance = $fieldDescription->getAssociationAdmin()->getNewInstance();
  110. $mapping = $fieldDescription->getAssociationMapping();
  111. $method = sprintf('add%s', $this->camelize($mapping['fieldName']));
  112. $object->$method($instance);
  113. }
  114. /**
  115. * Camelize a string
  116. *
  117. * @static
  118. * @param string $property
  119. * @return string
  120. */
  121. public function camelize($property)
  122. {
  123. return preg_replace(array('/(^|_| )+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
  124. }
  125. }