1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
manytomany.php
См. документацию.
1<?php
8
9namespace Bitrix\Main\ORM\Fields\Relations;
10
11use Bitrix\Main\ArgumentException;
12use Bitrix\Main\ORM\Entity;
13use Bitrix\Main\ORM\Fields\FieldTypeMask;
14use Bitrix\Main\ORM\Query\Join;
15use Bitrix\Main\ORM\Query\Query;
16use Bitrix\Main\SystemException;
17use Bitrix\Main\Text\StringHelper;
18
24class ManyToMany extends Relation
25{
28
30 protected $mediatorEntity;
31
34
37
40
43
46
48 protected $joinType = Join::TYPE_LEFT;
49
52
53 protected $cascadeDeletePolicy = CascadePolicy::NO_ACTION; // follow_orphans | no_action
54
61 public function __construct($name, $referenceEntity)
62 {
63 if ($referenceEntity instanceof Entity)
64 {
65 $this->refEntity = $referenceEntity;
66 $this->refEntityName = $referenceEntity->getFullName();
67 }
68 else
69 {
70 // this one could be without leading backslash and/or with Table-postfix
71 $this->refEntityName = Entity::normalizeName($referenceEntity);
72 }
73
74 parent::__construct($name);
75 }
76
77 public function getTypeMask()
78 {
80 }
81
90 {
91 if ($entity instanceof Entity)
92 {
93 $this->mediatorEntity = $entity;
94 $this->mediatorEntityName = $entity->getFullName();
95 }
96 else
97 {
98 // this one could be without leading backslash and/or with Table-postfix
99 $this->mediatorEntityName = Entity::normalizeName($entity);
100 }
101
102 return $this;
103 }
104
113 {
114 $this->mediatorTableName = $name;
115
116 return $this;
117 }
118
126 public function configureTableName($name)
127 {
128 return $this->configureMediatorTableName($name);
129 }
130
139 public function configureLocalPrimary($fieldName, $mediatorFieldName)
140 {
141 $this->localPrimaryNames[$fieldName] = $mediatorFieldName;
142
143 return $this;
144 }
145
154 {
155 $this->localReferenceName = $name;
156
157 return $this;
158 }
159
168 public function configureRemotePrimary($fieldName, $mediatorFieldName)
169 {
170 $this->remotePrimaryNames[$fieldName] = $mediatorFieldName;
171
172 return $this;
173 }
174
183 {
184 $this->remoteReferenceName = $name;
185
186 return $this;
187 }
188
194 public function getRemoteEntity()
195 {
196 return $this->getRefEntity();
197 }
198
204 public function getMediatorEntity()
205 {
206 if ($this->mediatorEntity === null)
207 {
208 if (!empty($this->mediatorEntityName) && Entity::has($this->mediatorEntityName))
209 {
210 $this->mediatorEntity = Entity::getInstance($this->mediatorEntityName);
211 }
212 else
213 {
214 // there is no described mediator entity
215 // check table_name first, entity can not exist without it
216 if (empty($this->mediatorTableName))
217 {
218 throw new ArgumentException(sprintf(
219 'Table Name for mediator entity of relation `%s` between %s and %s was not found',
220 $this->name, $this->getEntity()->getObjectClass(), $this->getRefEntity()->getObjectClass()
221 ));
222 }
223
224 // generate mediator entity runtime
225 if (empty($this->mediatorEntityName))
226 {
227 $localEntityName = $this->getEntity()->getName();
228 $remoteEntityName = $this->getRefEntity()->getName();
229 $fieldToClassName = StringHelper::snake2camel($this->name);
230
231 // each field has its own entity in case of ManyToMany definitions will be different
232 $this->mediatorEntityName = "MediatorFrom{$localEntityName}To{$remoteEntityName}Via{$fieldToClassName}Table";
233 }
234
235 // fields of mediator entity
236 $fields = [];
237
238 // local entity primary
239 $localReferenceConditions = Query::filter();
240
241 foreach ($this->getEntity()->getPrimaryArray() as $primaryName)
242 {
243 $mediatorPrimaryName = $this->localPrimaryNames[$primaryName] ?? $this->getLocalReferenceName().'_'.$primaryName;
244
245 $fieldType = get_class($this->getEntity()->getField($primaryName));
246
248 $mediatorPrimary = new $fieldType($mediatorPrimaryName);
249 $mediatorPrimary->configurePrimary(true);
250
251 $fields[] = $mediatorPrimary;
252
253 // save join condition for reference
254 $localReferenceConditions->whereColumn('this.'.$mediatorPrimaryName, 'ref.'.$primaryName);
255 }
256
257 // local reference
258 $localReference = (new Reference($this->getLocalReferenceName(), $this->getEntity(), $localReferenceConditions))
259 ->configureJoinType($this->joinType);
260 $fields[] = $localReference;
261
262 // remote entity primary
263 $remoteReferenceConditions = Query::filter();
264
265 foreach ($this->getRefEntity()->getPrimaryArray() as $primaryName)
266 {
267 $mediatorPrimaryName = $this->remotePrimaryNames[$primaryName] ?? $this->getRemoteReferenceName().'_'.$primaryName;
268
269 $fieldType = get_class($this->getRefEntity()->getField($primaryName));
270
272 $mediatorPrimary = new $fieldType($mediatorPrimaryName);
273 $mediatorPrimary->configurePrimary(true);
274
275 $fields[] = $mediatorPrimary;
276
277 // save join condition for reference
278 $remoteReferenceConditions->whereColumn('this.'.$mediatorPrimaryName, 'ref.'.$primaryName);
279 }
280
281 // remote reference
282 $remoteReference = (new Reference($this->getRemoteReferenceName(), $this->getRefEntity(), $remoteReferenceConditions))
283 ->configureJoinType($this->joinType);
284 $fields[] = $remoteReference;
285
286 // set table name
287 $parameters = ['table_name' => $this->mediatorTableName];
288
289 // finalize
290 $this->mediatorEntity = Entity::compileEntity($this->mediatorEntityName, $fields, $parameters);
291 }
292 }
293
295 }
296
300 public function getLocalReferenceName()
301 {
302 if (empty($this->localReferenceName))
303 {
304 $this->localReferenceName = strtoupper(StringHelper::camel2snake($this->getEntity()->getName()));
305 }
306
308 }
309
317 public function getLocalReference()
318 {
319 return $this->getMediatorEntity()->getField($this->getLocalReferenceName());
320 }
321
327 public function getRemoteReferenceName()
328 {
329 if (empty($this->remoteReferenceName))
330 {
331 $this->remoteReferenceName = strtoupper(StringHelper::camel2snake($this->getRefEntity()->getName()));
332 }
333
335 }
336
344 public function getRemoteReference()
345 {
346 return $this->getMediatorEntity()->getField($this->getRemoteReferenceName());
347 }
348}
static normalizeName($entityName)
Определения entity.php:877
static getInstance($entityName)
Определения entity.php:104
static has($entityName)
Определения entity.php:89
getEntity()
Определения field.php:614
__construct($name, $referenceEntity)
Определения manytomany.php:61
configureLocalPrimary($fieldName, $mediatorFieldName)
Определения manytomany.php:139
configureRemotePrimary($fieldName, $mediatorFieldName)
Определения manytomany.php:168
Определения ufield.php:9
$fields
Определения yandex_run.php:501