1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ActiveRecordImplementation.php
См. документацию.
1<?php
2
4
18
23{
25 protected $dataObject;
26
27 // Object changed flag
28 protected bool $isChanged = true;
29
30 // Object marked to drop
31 protected bool $markedDrop = false;
32
37 protected static function mirrorDataEntityFields(): array
38 {
40 return [];
41 }
42
46 public function getDataEntity(): EntityObject
47 {
48 if ($this->dataObject === null)
49 {
54 $dataClass = static::getDataClass();
55 $entityObjectClass = $dataClass::getObjectClass();
56 $this->dataObject = new $entityObjectClass;
57 }
58
59 return $this->dataObject;
60 }
61
66 protected function setDataEntity(EntityObject $dataObject): self
67 {
68 $this->dataObject = $dataObject;
69 return $this;
70 }
71
72 protected function resetDataEntity(array $preselectedFields = []): self
73 {
74 $fields = $preselectedFields;
75 if ($this->dataObject)
76 {
77 $fields += $this->dataObject->collectValues(Values::ACTUAL);
78 }
79
80 $this->dataObject = static::getDataClass()::getObjectClass()::wakeUp($fields);
81
82 return $this;
83 }
84
88 public function load($source): Result
89 {
90 $result = new Result;
91
92 if (is_numeric($source))
93 {
94 $source = (int)$source;
99 $dataClass = static::getDataClass();
100 $dataObject = $dataClass::getByPrimary($source)->fetchObject();
101
102 if (
103 $dataObject instanceof EntityObject
104 && $dataObject->hasId()
105 )
106 {
107 $result = $this->initByDataEntity($dataObject);
108 }
109 else
110 {
111 $result->addError(new Error(Error::NOT_FOUND));
112 }
113 }
114
115 elseif ($source instanceof EntityObject)
116 {
117 $result = $this->initByDataEntity($source);
118 }
119
120 elseif (is_array($source))
121 {
122 $result = $this->initByArray($source);
123 }
124 else
125 {
126 $result->addError(new Error(Error::NOT_FOUND));
127 }
128
129 if ($result->isSuccess() && $this->getPrimaryId())
130 {
131 $this->markChanged(false);
132
133 if (
134 $this instanceof RegistryEntry
135 && $this->getRegistry()
136 )
137 {
138 $this->getRegistry()[$this->getPrimaryId()] = $this;
139 }
140 }
141
142 return $result;
143 }
144
148 protected function initByDefault(): void
149 {
150 foreach (static::mirrorDataEntityFields() as $field)
151 {
152 if (
153 !isset($field['primary'])
154 && !isset($field['alias'])
155 && isset($field['field'], $field['default'])
156 && !isset($this->{$field['field']})
157 && ($default = $field['default'])
158 && is_string($default)
159 && is_callable([$this, $default])
160 )
161 {
162 $this->{$field['field']} = $this->$default();
163 }
164 }
165 }
166
171 protected function initByDataEntity(EntityObject $dataObject, ?array $fieldsMask = null): Result
172 {
173 $result = new Result;
174
175 $this->setDataEntity($dataObject);
176 $entityFields = $dataObject->collectValues();
177
178 foreach (static::mirrorDataEntityFields() as $offset => $field)
179 {
180 if (isset($field['alias']) || !isset($field['field']))
181 {
182 continue;
183 }
184
185 if (!empty($fieldsMask) && !in_array($offset, $fieldsMask, true))
186 {
187 continue;
188 }
189
190 if (isset($entityFields[$offset]))
191 {
192 if (
193 isset($field['loadFilter'])
194 && ($loadFilter = $field['loadFilter'])
195 && is_string($loadFilter)
196 && is_callable([$this, $loadFilter])
197 )
198 {
199 $this->{$field['field']} = $this->$loadFilter($entityFields[$offset]);
200 }
201 else
202 {
203 $this->{$field['field']} = $entityFields[$offset];
204 }
205 }
206 }
207
208 if ($result->isSuccess() && $this->getPrimaryId())
209 {
210 $this->markChanged(false);
211 }
212
213 return $result;
214 }
215
220 protected function initByArray(array $source): Result
221 {
222 $result = new Result;
223 $fieldsToFill = $source;
224
225 if ($this->hasPrimary($source))
226 {
227 [$ormFields, $fieldsToFill] = $this->separateFieldsOrmAndOther($source);
228 $result = $this->initByDataEntity(static::getDataClass()::getObjectClass()::wakeUp($ormFields));
229 if (!$result->isSuccess())
230 {
231 return $result;
232 }
233 }
234
235 if (!empty($fieldsToFill))
236 {
237 $this->fill($fieldsToFill);
238 }
239
240 if ($result->isSuccess() && $this->getPrimaryId())
241 {
242 $this->markChanged(false);
243 }
244
245 return $result;
246 }
247
248 protected function hasPrimary(array $source): bool
249 {
250 $fields = static::mirrorDataEntityFields();
251
252 foreach ($source as $key => $value)
253 {
254 if (!isset($fields[$key]))
255 {
256 continue;
257 }
258
259 $field = isset($fields[$key]['alias']) ? $fields[$fields[$key]['alias']] : $fields[$key];
260
261 if (isset($field['primary']) && $field['primary'])
262 {
263 return true;
264 }
265 }
266
267 return false;
268 }
269
270 protected function separateFieldsOrmAndOther(array $source): array
271 {
272 $fields = static::mirrorDataEntityFields();
274 $entity = static::getDataClass()::getEntity();
275 $ormFields = [];
276 $otherFields = [];
277
278 foreach ($source as $key => $value)
279 {
280 if (!isset($fields[$key]))
281 {
282 continue;
283 }
284
285 $fieldName = $fields[$key]['alias'] ?? $key;
286
287 if ($entity->hasField($fieldName) && !($entity->getField($fieldName) instanceof Relation))
288 {
289 if (
290 $value !== null
291 && $entity->getField($fieldName) instanceof \Bitrix\Main\ORM\Fields\DatetimeField
292 && is_string($value)
293 )
294 {
295 if (is_string($value) && !is_numeric($value))
296 {
297 $value = DateTime::tryParse($value) ?? DateTime::tryParse($value, 'Y-m-d H:i:s') ?? $value;
298 }
299 if (is_numeric($value))
300 {
301 $value = DateTime::createFromTimestamp((int)$value);
302 }
303 }
304 $ormFields[$fieldName] = $value;
305 }
306 else
307 {
308 $otherFields[$key] = $value;
309 }
310 }
311
312 return [$ormFields, $otherFields];
313 }
314
315 public function prepareFields(): Result
316 {
317 $result = new Result;
318
319 foreach (static::mirrorDataEntityFields() as $offset => $field)
320 {
321 if (isset($field['primary']) || isset($field['alias']) || (isset($field['skipSave']) && $field['skipSave'] === true))
322 {
323 continue;
324 }
325
326 if (
327 isset($field['beforeSave'])
328 && ($beforeSave = $field['beforeSave'])
329 && is_string($beforeSave)
330 && is_callable([$this, $beforeSave])
331 )
332 {
334 $check = $this->$beforeSave();
335 if (!$check->isSuccess())
336 {
337 $result->addErrors($check->getErrors());
338 continue;
339 }
340 }
341
342 if (
343 isset($field['field'])
344 && (isset($this->{$field['field']}) || $field['nullable'] === true)
345 )
346 {
347 if (
348 isset($field['saveFilter'])
349 && ($saveFilter = $field['saveFilter'])
350 && is_string($saveFilter)
351 && is_callable([$this, $saveFilter])
352 )
353 {
354 $this->getDataEntity()->set($offset, $this->$saveFilter($this->{$field['field']}));
355 }
356 else
357 {
358 $this->getDataEntity()->set($offset, $this->{$field['field']});
359 }
360
361 $this->markChanged($this->isChanged || $this->getDataEntity()->isChanged($offset));
362 }
363 }
364
365 return $result;
366 }
367
371 public function save(): Result
372 {
373 $result = $this->prepareFields();
374 if (!$result->isSuccess())
375 {
376 return $result;
377 }
378 if (!$this->isChanged())
379 {
380 return $result->setResult(['IS_CHANGES' => false]);
381 }
382 if ($result->getData()['SKIP_SAVE'] ?? false)
383 {
384 return $result;
385 }
386
387 $saveResult = $this->getDataEntity()->save();
388 if ($saveResult->isSuccess())
389 {
390 $this->updateState();
391
392 $this->setPrimaryId((int)$saveResult->getId());
393
394 if (
395 $this instanceof RegistryEntry
396 && $this->getRegistry()
397 )
398 {
399 $this->getRegistry()[$this->getPrimaryId()] = $this;
400 }
401
402 $this->markChanged(false);
403 }
404 else
405 {
406 $result->addErrors($saveResult->getErrors());
407 }
408
409 return $result;
410 }
411
412 protected function updateState(?array $fieldsToFill = null): Result
413 {
414 return $this->initByDataEntity($this->getDataEntity(), $fieldsToFill);
415 }
416
420 public function delete(): Result
421 {
422 $this->markDrop();
423 $result = new Result;
424 if ($this->getDataEntity()->hasId())
425 {
426 $deleteResult = $this->getDataEntity()->delete();
427 if (!$deleteResult->isSuccess())
428 {
429 return $result->addErrors($deleteResult->getErrors());
430 }
431 }
432
433 if (
434 $this instanceof RegistryEntry
435 && $this->getRegistry()
436 )
437 {
438 unset($this->getRegistry()[$this->getPrimaryId()]);
439 }
440
441 return $result;
442 }
443
448 public function markChanged(?bool $state = null): self
449 {
450 if ($state === null)
451 {
452 $this->isChanged = true;
453 }
454 else
455 {
456 $this->isChanged = $state;
457 }
458 if ($this->isChanged)
459 {
460 $this->markedDrop = false;
461 }
462 return $this;
463 }
464
469 public function isChanged(): bool
470 {
471 return $this->isChanged;
472 }
473
478 public function markDrop(): self
479 {
480 $this->isChanged = false;
481 $this->markedDrop = true;
482 return $this;
483 }
484
489 public function isDeleted(): bool
490 {
491 return $this->markedDrop;
492 }
493
494 public function fillActual(array $fieldsToFill): self
495 {
496 foreach ($fieldsToFill as $fieldName)
497 {
498 if ($this->getDataEntity()->entity->hasField($fieldName))
499 {
500 $this->getDataEntity()->unset($fieldName);
501 }
502 }
503 $this->getDataEntity()->fill($fieldsToFill);
504
505 $this->updateState($fieldsToFill);
506
507 return $this;
508 }
509
515 public function fill(array $source): self
516 {
517 $fields = static::mirrorDataEntityFields();
518
519 foreach ($fields as $offset => $field)
520 {
521 if (isset($source[$offset]))
522 {
523 if (isset($field['primary']))
524 {
525 continue;
526 }
527 if (isset($field['alias']))
528 {
529 $field = $fields[$field['alias']];
530 }
531 if (
532 isset($field['set'])
533 && ($setter = $field['set'])
534 && is_string($setter)
535 && is_callable([$this, $setter])
536 )
537 {
538 $this->$setter($source[$offset]);
539 }
540 elseif (isset($field['field']))
541 {
542 $this->{$field['field']} = $source[$offset];
543 }
544 }
545 }
546
547 return $this;
548 }
549
550 public function onAfterOrmUpdate(array $fields): self
551 {
552 $this->resetDataEntity($fields);
553 $this->updateState(array_keys($fields));
554
555 return $this;
556 }
557
562 public function toArray(bool $recursive = false): array
563 {
564 $result = [];
565 $fields = static::mirrorDataEntityFields();
566
567 foreach ($fields as $offset => $field)
568 {
569 if (isset($field['alias']))
570 {
571 continue;
572 }
573 if (
574 isset($field['get'])
575 && ($getter = $field['get'])
576 && is_string($getter)
577 && is_callable([$this, $getter])
578 )
579 {
580 $value = $this->$getter();
581 }
582 else
583 {
584 $value = $this->{$field['field']};
585 }
586
587 if (is_object($value) && !($value instanceof DateTime))
588 {
589 if ($recursive && method_exists($value, 'toArray'))
590 {
591 $value = $value->toArray($recursive);
592 }
593 else
594 {
595 continue;
596 }
597 }
598
599 $result[$offset] = $value;
600 }
601
602 return $result;
603 }
604}
const NOT_FOUND
Определения Error.php:9
Определения result.php:20
Определения error.php:15
collectValues($valuesType=Values::ALL, $fieldsMask=FieldTypeMask::ALL, $recursive=false)
Определения entityobject.php:220
$value
Определения date.php:11
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$entity
Определения RegistryEntry.php:6
onAfterOrmUpdate(array $fields)
Определения ActiveRecordImplementation.php:550
toArray(bool $recursive=false)
Определения ActiveRecordImplementation.php:562
updateState(?array $fieldsToFill=null)
Определения ActiveRecordImplementation.php:412
fillActual(array $fieldsToFill)
Определения ActiveRecordImplementation.php:494
resetDataEntity(array $preselectedFields=[])
Определения ActiveRecordImplementation.php:72
setDataEntity(EntityObject $dataObject)
Определения ActiveRecordImplementation.php:66
initByDataEntity(EntityObject $dataObject, ?array $fieldsMask=null)
Определения ActiveRecordImplementation.php:171
markChanged(?bool $state=null)
Определения ActiveRecordImplementation.php:448
trait ActiveRecordImplementation
Определения ActiveRecordImplementation.php:23
fill(array $source)
Определения ActiveRecordImplementation.php:515
hasPrimary(array $source)
Определения ActiveRecordImplementation.php:248
initByArray(array $source)
Определения ActiveRecordImplementation.php:220
Определения ufield.php:9
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$fields
Определения yandex_run.php:501