Add support for bundle named entity
[airbundle] / Form / Extension / Type / HiddenEntityType.php
1 <?php
2
3 namespace Rapsys\AirBundle\Form\Extension\Type;
4
5 use Doctrine\Persistence\ManagerRegistry;
6 use Symfony\Component\Form\DataTransformerInterface;
7 use Symfony\Component\Form\Exception\TransformationFailedException;
8 use Symfony\Component\Form\Extension\Core\Type\HiddenType;
9 use Symfony\Component\Form\FormBuilderInterface;
10 use Symfony\Component\OptionsResolver\Options;
11 use Symfony\Component\OptionsResolver\OptionsResolver;
12
13 /**
14 * Hidden Entity Type class definition
15 *
16 * @see https://symfony.com/doc/current/form/create_custom_field_type.html
17 */
18 class HiddenEntityType extends HiddenType implements DataTransformerInterface {
19 /**
20 * @var ManagerRegistry $dm
21 */
22 private $dm;
23
24 /**
25 * @var string $class
26 */
27 private $class;
28
29 /**
30 * Constructor
31 *
32 * @param ManagerRegistry $doctrine
33 */
34 public function __construct(ManagerRegistry $doctrine) {
35 $this->dm = $doctrine;
36 }
37
38 /**
39 * Configure options
40 *
41 * {@inheritdoc}
42 */
43 public function configureOptions(OptionsResolver $resolver) {
44 //Call parent
45 parent::configureOptions($resolver);
46
47 //Derive "data_class" option from passed "data" object
48 $class = function (Options $options) {
49 return isset($options['data']) && \is_object($options['data']) ? \get_class($options['data']) : null;
50 };
51
52 $resolver->setDefaults([
53 #'data_class' => null,
54 'class' => $class
55 ]);
56 }
57
58 /**
59 * Build form
60 *
61 * {@inheritdoc}
62 */
63 public function buildForm(FormBuilderInterface $builder, array $options): void {
64 //Set class from options['class']
65 $this->class = $options['class'];
66
67 //Without class
68 if (empty($this->class)) {
69 //Set class from namespace and field name
70 $this->class = str_replace('Form\\Extension\\Type', 'Entity\\' ,__NAMESPACE__).ucfirst($builder->getName());
71 //With bundle named entity
72 } elseif (
73 ($pos = strpos($this->class, ':')) !== false &&
74 !empty($entity = substr($this->class, $pos + 1))
75 ) {
76 //Set class from namespace and entity name
77 $this->class = str_replace('Form\\Extension\\Type', 'Entity\\' ,__NAMESPACE__).$entity;
78 }
79
80 //Set this as model transformer
81 //XXX: clone the model transformer to allow multiple hiddenentitytype field with different class
82 $builder->addModelTransformer(clone $this);
83 }
84
85 /**
86 * Transform data to string
87 *
88 * @param mixed $data The data object
89 * @return string The object id
90 */
91 public function transform($data): string {
92 //Modified from comments to use instanceof so that base classes or interfaces can be specified
93 if ($data === null || !$data instanceof $this->class) {
94 return '';
95 }
96
97 $res = $data->getId();
98
99 return $res;
100 }
101
102 /**
103 * Reverse transformation from string to data object
104 *
105 * @param string $data The object id
106 * @return mixed The data object
107 */
108 public function reverseTransform($data) {
109 if (!$data) {
110 return null;
111 }
112
113 $res = null;
114 try {
115 $rep = $this->dm->getRepository($this->class);
116 $res = $rep->findOneById($data);
117 } catch (\Exception $e) {
118 throw new TransformationFailedException($e->getMessage());
119 }
120
121 if ($res === null) {
122 throw new TransformationFailedException(sprintf('A %s with id %s does not exist!', $this->class, $data));
123 }
124
125 return $res;
126 }
127 }