|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* TEntityContainer.php |
|
4
|
|
|
* |
|
5
|
|
|
* @copyright More in license.md |
|
6
|
|
|
* @license http://www.ipublikuj.eu |
|
7
|
|
|
* @author Adam Kadlec http://www.ipublikuj.eu |
|
8
|
|
|
* @package iPublikuj:Forms! |
|
9
|
|
|
* @subpackage Forms |
|
10
|
|
|
* @since 1.0.0 |
|
11
|
|
|
* |
|
12
|
|
|
* @date 10.01.16 |
|
13
|
|
|
*/ |
|
14
|
|
|
|
|
15
|
|
|
declare(strict_types = 1); |
|
16
|
|
|
|
|
17
|
|
|
namespace IPub\Forms\Forms; |
|
18
|
|
|
|
|
19
|
|
|
use Doctrine\ORM; |
|
20
|
|
|
|
|
21
|
|
|
use Nette; |
|
22
|
|
|
use Nette\Forms; |
|
23
|
|
|
|
|
24
|
|
|
use IPub; |
|
25
|
|
|
use IPub\Forms\Exceptions; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* Class TEntity |
|
29
|
|
|
* @package IPub\Forms\Application\UI |
|
30
|
|
|
* |
|
31
|
|
|
* @property ORM\EntityManager $entityManager |
|
32
|
|
|
* |
|
33
|
|
|
* @method Nette\Application\UI\Form getForm($need = TRUE) |
|
34
|
|
|
* @method setValues($values, $erase = FALSE) |
|
35
|
|
|
*/ |
|
36
|
|
|
trait TEntityContainer |
|
37
|
|
|
{ |
|
38
|
|
|
/** |
|
39
|
|
|
* @var mixed |
|
40
|
|
|
*/ |
|
41
|
|
|
private $entity; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @param ORM\EntityManager $entityManager |
|
45
|
|
|
* |
|
46
|
|
|
* @return $this |
|
47
|
|
|
*/ |
|
48
|
|
|
public function injectEntityManager(ORM\EntityManager $entityManager) |
|
|
|
|
|
|
49
|
|
|
{ |
|
50
|
|
|
$this->entityManager = $entityManager; |
|
51
|
|
|
|
|
52
|
|
|
return $this; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* @param array|\Traversable $values |
|
57
|
|
|
* @param bool $erase |
|
58
|
|
|
*/ |
|
59
|
|
|
public function setDefaults($values, $erase = FALSE) |
|
60
|
|
|
{ |
|
61
|
|
|
$form = $this->getForm(FALSE); |
|
62
|
|
|
|
|
63
|
|
|
if (!$form || !$form->isAnchored() || !$form->isSubmitted()) { |
|
64
|
|
|
if ($this->isEntity($values)) { |
|
65
|
|
|
$this->bindEntity($this, $values, $erase); |
|
|
|
|
|
|
66
|
|
|
|
|
67
|
|
|
} else { |
|
68
|
|
|
$this->setValues($values, $erase); |
|
69
|
|
|
} |
|
70
|
|
|
} |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* @param mixed $entity |
|
75
|
|
|
*/ |
|
76
|
|
|
public function setEntity($entity) |
|
77
|
|
|
{ |
|
78
|
|
|
$this->entity = $entity; |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
/** |
|
82
|
|
|
* @return mixed |
|
83
|
|
|
*/ |
|
84
|
|
|
public function getEntity() |
|
85
|
|
|
{ |
|
86
|
|
|
return $this->entity; |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
/** |
|
90
|
|
|
* @param Nette\ComponentModel\Component $formElement |
|
91
|
|
|
* @param object $entity |
|
92
|
|
|
* @param bool $erase |
|
93
|
|
|
* |
|
94
|
|
|
* @throws Exceptions\InvalidArgumentException |
|
95
|
|
|
*/ |
|
96
|
|
|
private function bindEntity($formElement, $entity, $erase) |
|
97
|
|
|
{ |
|
98
|
|
|
$classMetadata = $this->getMetadata($entity); |
|
99
|
|
|
|
|
100
|
|
|
foreach (self::iterate($formElement) as $name => $component) { |
|
|
|
|
|
|
101
|
|
|
if ($component instanceof Forms\IControl) { |
|
102
|
|
|
if (($classMetadata->hasField($name) || $classMetadata->hasAssociation($name)) && $value = $classMetadata->getFieldValue($entity, $name)) { |
|
103
|
|
View Code Duplication |
if (is_object($value) && $this->isEntity($value)) { |
|
|
|
|
|
|
104
|
|
|
$UoW = $this->entityManager->getUnitOfWork(); |
|
105
|
|
|
$value = $UoW->getSingleIdentifierValue($value); |
|
106
|
|
|
|
|
107
|
|
|
$component->setValue($value); |
|
108
|
|
|
|
|
109
|
|
|
} else { |
|
110
|
|
|
$component->setValue($value); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
} else { |
|
114
|
|
|
$methodName = 'get' . ucfirst($name); |
|
115
|
|
|
|
|
116
|
|
|
if (method_exists($entity, $methodName) && $value = call_user_func([$entity, $methodName])) { |
|
117
|
|
View Code Duplication |
if (is_object($value) && $this->isEntity($value)) { |
|
|
|
|
|
|
118
|
|
|
$UoW = $this->entityManager->getUnitOfWork(); |
|
119
|
|
|
$value = $UoW->getSingleIdentifierValue($value); |
|
120
|
|
|
|
|
121
|
|
|
$component->setValue($value); |
|
122
|
|
|
|
|
123
|
|
|
} else { |
|
124
|
|
|
$component->setValue($value); |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
} else { |
|
128
|
|
|
if ($erase) { |
|
129
|
|
|
$component->setValue(NULL); |
|
130
|
|
|
} |
|
131
|
|
|
} |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
} else if ($component instanceof Forms\Container) { |
|
135
|
|
|
if (($classMetadata->hasField($name) || $classMetadata->hasAssociation($name)) && $value = $classMetadata->getFieldValue($entity, $name)) { |
|
136
|
|
View Code Duplication |
if (is_object($value) && $this->isEntity($value)) { |
|
|
|
|
|
|
137
|
|
|
$this->bindEntity($component, $value, $erase); |
|
138
|
|
|
|
|
139
|
|
|
} else { |
|
140
|
|
|
$component->setValues($value, $erase); |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
} else { |
|
144
|
|
|
$methodName = 'get' . ucfirst($name); |
|
145
|
|
|
|
|
146
|
|
|
if (method_exists($entity, $methodName) && $value = call_user_func([$entity, $methodName])) { |
|
147
|
|
View Code Duplication |
if (is_object($value) && $this->isEntity($value)) { |
|
|
|
|
|
|
148
|
|
|
$this->bindEntity($component, $value, $erase); |
|
149
|
|
|
|
|
150
|
|
|
} else { |
|
151
|
|
|
$component->setValues($value, $erase); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
} else { |
|
155
|
|
|
if ($erase) { |
|
156
|
|
|
$component->setValues([], $erase); |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
} |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* @param object $entity |
|
166
|
|
|
* |
|
167
|
|
|
* @return ORM\Mapping\ClassMetadata |
|
168
|
|
|
* |
|
169
|
|
|
* @throws Exceptions\InvalidArgumentException |
|
170
|
|
|
*/ |
|
171
|
|
|
private function getMetadata($entity) |
|
172
|
|
|
{ |
|
173
|
|
|
if (!$this->isEntity($entity)) { |
|
174
|
|
|
throw new Exceptions\InvalidArgumentException('Expected object, ' . gettype($entity) . ' given.'); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
return $this->entityManager->getClassMetadata(get_class($entity)); |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
/** |
|
181
|
|
|
* @param mixed $entity |
|
182
|
|
|
* |
|
183
|
|
|
* @return bool |
|
184
|
|
|
*/ |
|
185
|
|
|
private function isEntity($entity) |
|
186
|
|
|
{ |
|
187
|
|
|
return is_object($entity) && $this->entityManager->getMetadataFactory()->hasMetadataFor(get_class($entity)); |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
/** |
|
191
|
|
|
* @param Nette\Forms\Controls\BaseControl|Nette\Forms\Container $formElement |
|
192
|
|
|
* |
|
193
|
|
|
* @return array|\ArrayIterator |
|
194
|
|
|
* |
|
195
|
|
|
* @throws Exceptions\InvalidArgumentException |
|
196
|
|
|
*/ |
|
197
|
|
|
private static function iterate($formElement) |
|
198
|
|
|
{ |
|
199
|
|
|
if ($formElement instanceof Forms\Container) { |
|
200
|
|
|
return $formElement->getComponents(); |
|
201
|
|
|
|
|
202
|
|
|
} elseif ($formElement instanceof Forms\IControl) { |
|
203
|
|
|
return [$formElement]; |
|
204
|
|
|
|
|
205
|
|
|
} else { |
|
206
|
|
|
throw new Exceptions\InvalidArgumentException('Expected Nette\Forms\Container or Nette\Forms\IControl, but ' . get_class($formElement) . ' given'); |
|
207
|
|
|
} |
|
208
|
|
|
} |
|
209
|
|
|
} |
|
210
|
|
|
|
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.