vendor/symfony/form/Extension/Core/DataMapper/DataMapper.php line 41

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <[email protected]>
  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 Symfony\Component\Form\Extension\Core\DataMapper;
  11. use Symfony\Component\Form\DataAccessorInterface;
  12. use Symfony\Component\Form\DataMapperInterface;
  13. use Symfony\Component\Form\Exception\UnexpectedTypeException;
  14. use Symfony\Component\Form\Extension\Core\DataAccessor\CallbackAccessor;
  15. use Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor;
  16. use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor;
  17. /**
  18. * Maps arrays/objects to/from forms using data accessors.
  19. *
  20. * @author Bernhard Schussek <[email protected]>
  21. */
  22. class DataMapper implements DataMapperInterface
  23. {
  24. private $dataAccessor;
  25. public function __construct(?DataAccessorInterface $dataAccessor = null)
  26. {
  27. $this->dataAccessor = $dataAccessor ?? new ChainAccessor([
  28. new CallbackAccessor(),
  29. new PropertyPathAccessor(),
  30. ]);
  31. }
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function mapDataToForms($data, iterable $forms): void
  36. {
  37. if (\is_array($forms)) {
  38. trigger_deprecation('symfony/form', '5.3', 'Passing an array as the second argument of the "%s()" method is deprecated, pass "\Traversable" instead.', __METHOD__);
  39. }
  40. $empty = null === $data || [] === $data;
  41. if (!$empty && !\is_array($data) && !\is_object($data)) {
  42. throw new UnexpectedTypeException($data, 'object, array or empty');
  43. }
  44. foreach ($forms as $form) {
  45. $config = $form->getConfig();
  46. if (!$empty && $config->getMapped() && $this->dataAccessor->isReadable($data, $form)) {
  47. $form->setData($this->dataAccessor->getValue($data, $form));
  48. } else {
  49. $form->setData($config->getData());
  50. }
  51. }
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public function mapFormsToData(iterable $forms, &$data): void
  57. {
  58. if (\is_array($forms)) {
  59. trigger_deprecation('symfony/form', '5.3', 'Passing an array as the first argument of the "%s()" method is deprecated, pass "\Traversable" instead.', __METHOD__);
  60. }
  61. if (null === $data) {
  62. return;
  63. }
  64. if (!\is_array($data) && !\is_object($data)) {
  65. throw new UnexpectedTypeException($data, 'object, array or empty');
  66. }
  67. foreach ($forms as $form) {
  68. $config = $form->getConfig();
  69. // Write-back is disabled if the form is not synchronized (transformation failed),
  70. // if the form was not submitted and if the form is disabled (modification not allowed)
  71. if ($config->getMapped() && $form->isSubmitted() && $form->isSynchronized() && !$form->isDisabled() && $this->dataAccessor->isWritable($data, $form)) {
  72. $this->dataAccessor->setValue($data, $form->getData(), $form);
  73. }
  74. }
  75. }
  76. /**
  77. * @internal
  78. */
  79. public function getDataAccessor(): DataAccessorInterface
  80. {
  81. return $this->dataAccessor;
  82. }
  83. }