ArrayToObjectTransformer.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /*
  3. * This file is part of the Sonata project.
  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\BaseApplicationBundle\Form\ValueTransformer;
  11. use Symfony\Component\Form\ValueTransformer\BaseValueTransformer;
  12. use Symfony\Component\Form\Exception\InvalidPropertyException;
  13. use Symfony\Component\Form\Exception\PropertyAccessDeniedException;
  14. class ArrayToObjectTransformer extends BaseValueTransformer
  15. {
  16. protected function configure()
  17. {
  18. $this->addRequiredOption('em');
  19. $this->addRequiredOption('className');
  20. parent::configure();
  21. }
  22. /**
  23. * @param array $ids
  24. * @param Collection $collection
  25. */
  26. public function reverseTransform($array, $originalValue)
  27. {
  28. $class = $this->getOption('className');
  29. $metadata = $this->getOption('em')->getClassMetadata($class);
  30. // when the object is created the form return an array
  31. // one the object is persited, the edit $array is the user instance
  32. if ($array instanceof $class)
  33. {
  34. return $array;
  35. }
  36. $instance = new $class;
  37. if (!is_array($array)) {
  38. return $instance;
  39. }
  40. $reflClass = $metadata->reflClass;
  41. foreach ($array as $name => $value) {
  42. $reflection_property = false;
  43. // property or association ?
  44. if (array_key_exists($name, $metadata->fieldMappings)) {
  45. $property = $metadata->fieldMappings[$name]['fieldName'];
  46. $reflection_property = $metadata->reflFields[$name];
  47. } else if (array_key_exists($name, $metadata->associationMappings)) {
  48. $property = $metadata->associationMappings[$name]['fieldName'];
  49. } else {
  50. $property = $name;
  51. }
  52. $setter = 'set'.$this->camelize($name);
  53. if ($reflClass->hasMethod($setter)) {
  54. if (!$reflClass->getMethod($setter)->isPublic()) {
  55. throw new PropertyAccessDeniedException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName()));
  56. }
  57. $instance->$setter($value);
  58. } else if ($reflClass->hasMethod('__set')) {
  59. // needed to support magic method __set
  60. $instance->$property = $value;
  61. } else if ($reflClass->hasProperty($property)) {
  62. if (!$reflClass->getProperty($property)->isPublic()) {
  63. throw new PropertyAccessDeniedException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property)));
  64. }
  65. $instance->$property = $value;
  66. } else if ($reflection_property) {
  67. $reflection_property->setValue($instance, $value);
  68. }
  69. }
  70. return $instance;
  71. }
  72. /**
  73. * @param Collection $value
  74. */
  75. public function transform($value)
  76. {
  77. return $value;
  78. }
  79. /**
  80. * method taken from PropertyPath
  81. *
  82. * @param $property
  83. * @return mixed
  84. */
  85. protected function camelize($property)
  86. {
  87. return preg_replace(array('/(^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
  88. }
  89. }