1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
prototypeitemdatamanager.php
См. документацию.
1<?php
2
3namespace Bitrix\Main\UserField\Internal;
4
5use Bitrix\Main;
6use Bitrix\Main\ORM;
7use Bitrix\Main\ORM\Event;
8use Bitrix\Main\ORM\Fields\IntegerField;
9use Bitrix\Main\ORM\Fields\ScalarField;
10
15{
16 protected static $temporaryStorage;
17 protected static $isCheckUserFields = true;
18
24 public static function disableUserFieldsCheck(): void
25 {
26 static::$isCheckUserFields = false;
27 }
28
29 public static function getType(): ?array
30 {
31 return Registry::getInstance()->getTypeByEntity(static::getEntity());
32 }
33
34 public static function getMap(): array
35 {
36 return [
37 (new IntegerField('ID'))
38 ->configurePrimary()
39 ->configureAutocomplete(),
40 ];
41 }
42
43 protected static function getTemporaryStorage(): TemporaryStorage
44 {
45 if(!static::$temporaryStorage)
46 {
47 static::$temporaryStorage = new TemporaryStorage();
48 }
49
50 return static::$temporaryStorage;
51 }
52
53 public static function checkFields(ORM\Data\Result $result, $primary, array $data)
54 {
55 // check for unknown fields
56 foreach ($data as $k => $v)
57 {
58 if (!(static::getEntity()->hasField($k) && static::getEntity()->getField($k) instanceof ScalarField))
59 {
60 throw new Main\SystemException(sprintf(
61 'Field `%s` not found in entity when trying to query %s row.',
62 $k, static::getEntity()->getName()
63 ));
64 }
65 }
66
67 parent::checkFields($result, $primary, $data);
68 }
69
70 public static function getItemUserFieldEntityId(): ?string
71 {
72 return Registry::getInstance()->getUserFieldEntityIdByItemEntity(static::getEntity());
73 }
74
75 protected static function getErrorFromException(): ORM\EntityError
76 {
77 $application = UserFieldHelper::getInstance()->getApplication();
78
79 if(is_object($application) && $application->getException())
80 {
81 $e = $application->getException();
82 $error = new Main\ORM\EntityError($e->getString());
83 $application->resetException();
84 }
85 else
86 {
87 $error = new Main\ORM\EntityError("Unknown error while checking userfields");
88 }
89
90 return $error;
91 }
92
99 protected static function modifyValuesBeforeSave($id, array $data, array $options = []): ORM\EventResult
100 {
101 $userFieldManager = UserFieldHelper::getInstance()->getManager();
102 $isUpdate = (isset($options['isUpdate']) && $options['isUpdate'] === true);
103
105 if (!$userFieldManager)
106 {
107 static::$isCheckUserFields = true;
108 return $result;
109 }
110
111 if($isUpdate)
112 {
113 $oldData = static::getByPrimary($id)->fetch();
114 static::getTemporaryStorage()->saveData($id, $oldData);
115 if (
116 static::$isCheckUserFields
117 && !$userFieldManager->checkFieldsWithOldData(
118 static::getItemUserFieldEntityId(),
119 $oldData,
120 $data
121 )
122 )
123 {
124 $result->addError(static::getErrorFromException());
125 }
126
127 $fields = $userFieldManager->getUserFieldsWithReadyData(
128 static::getItemUserFieldEntityId(),
129 $oldData,
130 LANGUAGE_ID,
131 false,
132 'ID'
133 );
134 }
135 else
136 {
137 $fields = $userFieldManager->getUserFields(static::getItemUserFieldEntityId());
138
139 if(
140 static::$isCheckUserFields
141 && !$userFieldManager->checkFields(
142 static::getItemUserFieldEntityId(),
143 null,
144 $data,
145 false,
146 true
147 )
148 )
149 {
150 $result->addError(static::getErrorFromException());
151 }
152 }
153
154 if(!$result->getErrors())
155 {
156 $data = static::convertValuesBeforeSave($data, $fields);
157 $result->modifyFields($data);
158 }
159
160 static::$isCheckUserFields = true;
161
162 return $result;
163 }
164
173 protected static function saveMultipleValues($id, array $data, array $options = []): ORM\EventResult
174 {
175 $id = static::getTemporaryStorage()->getIdByPrimary($id);
177
178 $isUpdate = (isset($options['isUpdate']) && $options['isUpdate']);
179 $type = static::getType();
180 $userFieldManager = UserFieldHelper::getInstance()->getManager();
182 [$factory] = UserFieldHelper::getInstance()->parseUserFieldEntityId(static::getItemUserFieldEntityId());
184 $typeDataClass = $factory->getTypeDataClass();
185
186 $fields = $userFieldManager->getUserFields(static::getItemUserFieldEntityId());
187 $oldData = static::getTemporaryStorage()->getData($id);
188
189 $multiValues = [];
190 foreach($fields as $fieldName => $field)
191 {
192 if(is_array($data[$fieldName]) && $field['MULTIPLE'] === 'Y')
193 {
194 $multiValues[$fieldName] = array_filter($data[$fieldName], array('static', 'isNotNull'));
195 $multiValues[$fieldName] = array_filter($multiValues[$fieldName], static fn($item) => !is_array($item));
196 }
197 elseif($field['USER_TYPE']['BASE_TYPE'] === 'file')
198 {
199 if(is_numeric($oldData[$fieldName]) && array_key_exists($fieldName, $data) && (int) $oldData[$fieldName] !== (int) $data[$fieldName])
200 {
201 \CFile::Delete($oldData[$fieldName]);
202 }
203 }
204 }
205
206 // save multi values
207 foreach ($multiValues as $fieldName => $values)
208 {
209 $utmTableName = $typeDataClass::getMultipleValueTableName($type, $fields[$fieldName]);
210
211 if($isUpdate)
212 {
213 // another clutch to delete files if they had not been deleted before
214 if($fields[$fieldName]['USER_TYPE']['BASE_TYPE'] === 'file')
215 {
216 foreach($oldData[$fieldName] as $fileId)
217 {
218 if(is_numeric($fileId) && !in_array($fileId, $values))
219 {
220 \CFile::Delete($fileId);
221 }
222 }
223 }
224
225 $helper = $connection->getSqlHelper();
226 // first, delete old values
227 $connection->query(sprintf(
228 'DELETE FROM %s WHERE %s = %d',
229 $helper->quote($utmTableName), $helper->quote('ID'), $id
230 ));
231 }
232
233 foreach ($values as $value)
234 {
235 $connection->add($utmTableName, array('ID' => $id, 'VALUE' => $value));
236 }
237 }
238
239 return $result;
240 }
241
242 public static function onBeforeAdd(Event $event): ORM\EventResult
243 {
244 return static::modifyValuesBeforeSave($event->getParameter('id'), $event->getParameter('fields'));
245 }
246
247 public static function onAfterAdd(Event $event): ORM\EventResult
248 {
249 return static::saveMultipleValues($event->getParameter('id'), $event->getParameter('fields'));
250 }
251
252 public static function onBeforeUpdate(Event $event): ORM\EventResult
253 {
254 return static::modifyValuesBeforeSave($event->getParameter('id'), $event->getParameter('fields'), [
255 'isUpdate' => true,
256 ]);
257 }
258
259 public static function onAfterUpdate(Event $event): ORM\EventResult
260 {
261 return static::saveMultipleValues($event->getParameter('id'), $event->getParameter('fields'), [
262 'isUpdate' => true,
263 ]);
264 }
265
266 public static function onBeforeDelete(Event $event): ORM\EventResult
267 {
268 if ($oldData = static::getByPrimary($event->getParameter('id'))->fetch())
269 {
270 static::getTemporaryStorage()->saveData($event->getParameter('id'), $oldData);
271 }
272
273 return new Main\ORM\EventResult();
274 }
275
276 public static function onAfterDelete(Event $event): ORM\EventResult
277 {
279 $oldData = static::getTemporaryStorage()->getData($event->getParameter('id'));
280 $id = static::getTemporaryStorage()->getIdByPrimary($event->getParameter('id'));
281 $userFieldManager = UserFieldHelper::getInstance()->getManager();
282 $type = static::getType();
284 $helper = $connection->getSqlHelper();
285 [$factory] = UserFieldHelper::getInstance()->parseUserFieldEntityId(static::getItemUserFieldEntityId());
287 $typeDataClass = $factory->getTypeDataClass();
288
289 $fields = $userFieldManager->getUserFields(static::getItemUserFieldEntityId());
290 foreach ($oldData as $k => $v)
291 {
292 $userfield = $fields[$k];
293
294 // remove multi values
295 if ($userfield['MULTIPLE'] == 'Y')
296 {
297 $utmTableName = $typeDataClass::getMultipleValueTableName($type, $userfield);
298
299 try
300 {
301 $connection->query(sprintf(
302 'DELETE FROM %s WHERE %s = %d',
303 $helper->quote($utmTableName), $helper->quote('ID'), $id
304 ));
305 }
306 catch(Main\DB\SqlQueryException $e)
307 {
308 $result->addError(new ORM\EntityError($e->getMessage()));
309 }
310 }
311
312 // remove files
313 if ($userfield["USER_TYPE"]["BASE_TYPE"]=="file")
314 {
315 if(is_array($oldData[$k]))
316 {
317 foreach($oldData[$k] as $value)
318 {
319 \CFile::delete($value);
320 }
321 }
322 else
323 {
324 \CFile::delete($oldData[$k]);
325 }
326 }
327 }
328
329 return $result;
330 }
331
339 protected static function convertValuesBeforeSave(array $data, array $userFields): array
340 {
341 foreach ($data as $k => $v)
342 {
343 if (static::isOwnField($k))
344 {
345 continue;
346 }
347
348 $userField = $userFields[$k];
349
350 if ($userField['MULTIPLE'] == 'N')
351 {
352 $inputValue = [$v];
353 }
354 else
355 {
356 $inputValue = $v;
357 }
358
359 $tmpValue = [];
360
361 foreach ($inputValue as $singleValue)
362 {
363 $tmpValue[] = static::convertSingleValueBeforeSave($singleValue, $userField);
364 }
365
366 // write value back
367 if ($userField['MULTIPLE'] == 'N')
368 {
369 $data[$k] = $tmpValue[0];
370 }
371 else
372 {
373 // remove empty (false) values
374 $tmpValue = array_filter($tmpValue, ['static', 'isNotNull']);
375
376 $data[$k] = $tmpValue;
377 $multiValues[$k] = $tmpValue;
378 }
379 }
380
381 return $data;
382 }
383
390 protected static function convertSingleValueBeforeSave($value, array $userField)
391 {
392 if (!isset($userField['USER_TYPE']) || !is_array($userField['USER_TYPE']))
393 {
394 $userField['USER_TYPE'] = array();
395 }
396 elseif (
397 isset($userField['USER_TYPE']['BASE_TYPE'])
398 && $userField['USER_TYPE']['BASE_TYPE'] === 'datetime'
399 )
400 {
401 $useTimezone = isset($userField['SETTINGS']['USE_TIMEZONE']) && $userField['SETTINGS']['USE_TIMEZONE'] === 'Y';
402
403 if ($useTimezone)
404 {
405 if ($value instanceof Main\Type\DateTime)
406 {
407 $value = $value::createFromUserTime($value->format(Main\Type\DateTime::getFormat()));
408 }
409 elseif (is_string($value) && Main\Type\DateTime::isCorrect($value))
410 {
412 }
413 }
414 else
415 {
416 if (is_string($value) && Main\Type\DateTime::isCorrect($value))
417 {
418 $value = new Main\Type\DateTime($value);
419 }
420 if ($value instanceof Main\Type\DateTime)
421 {
422 $value->disableUserTime();
423 }
424 }
425 }
426
427 if (
428 isset($userField['USER_TYPE']['CLASS_NAME']) &&
429 is_callable(array($userField['USER_TYPE']['CLASS_NAME'], 'onbeforesave'))
430 )
431 {
432 $value = call_user_func_array(
433 array($userField['USER_TYPE']['CLASS_NAME'], 'onbeforesave'), array($userField, $value)
434 );
435 }
436
437 if (static::isNotNull($value))
438 {
439 return $value;
440 }
441 elseif (
442 isset($userField['USER_TYPE']['BASE_TYPE']) &&
443 (
444 $userField['USER_TYPE']['BASE_TYPE'] == 'int' ||
445 $userField['USER_TYPE']['BASE_TYPE'] == 'double'
446 )
447 )
448 {
449 return null;
450 }
451 else
452 {
453 return false;
454 }
455 }
456
457 protected static function isNotNull($value): bool
458 {
459 return !($value === null || $value === false || $value === '');
460 }
461
462 public static function isOwnField(string $fieldName): bool
463 {
464 return array_key_exists($fieldName, static::getOwnFieldNames());
465 }
466
472 public static function getOwnFieldNames(): array
473 {
474 static $fields;
475 if($fields === null)
476 {
477 $fields = [];
478
479 foreach(static::getMap() as $field)
480 {
481 $fields[$field->getName()] = $field->getName();
482 }
483 }
484
485 return $fields;
486 }
487
488 public static function getUserFieldValues(int $id, array $userFields): ?array
489 {
490 $data = static::getList([
491 'select' => array_keys($userFields),
492 'filter' => [
493 '=ID' => $id,
494 ]
495 ])->fetch();
496
497 if (is_array($data))
498 {
499 return $data;
500 }
501
502 return null;
503 }
504
505 public static function updateUserFieldValues(int $id, array $fields): Main\Result
506 {
507 return static::update($id, $fields);
508 }
509
510 public static function deleteUserFieldValues(int $id): Main\Result
511 {
512 $fields = [];
513 $userFields = UserFieldHelper::getInstance()->getManager()->GetUserFields(static::getItemUserFieldEntityId());
514 foreach($userFields as $userField)
515 {
516 $fields[$userField['FIELD_NAME']] = null;
517 }
518
519 return static::update($id, $fields);
520 }
521}
$connection
Определения actionsdefinitions.php:38
$type
Определения options.php:106
static getConnection($name="")
Определения application.php:638
Определения event.php:5
static onAfterDelete(Event $event)
Определения datamanager.php:2015
static createFromUserTime($timeString)
Определения datetime.php:180
static modifyValuesBeforeSave($id, array $data, array $options=[])
Определения prototypeitemdatamanager.php:99
static checkFields(ORM\Data\Result $result, $primary, array $data)
Определения prototypeitemdatamanager.php:53
static getUserFieldValues(int $id, array $userFields)
Определения prototypeitemdatamanager.php:488
static updateUserFieldValues(int $id, array $fields)
Определения prototypeitemdatamanager.php:505
static convertValuesBeforeSave(array $data, array $userFields)
Определения prototypeitemdatamanager.php:339
static convertSingleValueBeforeSave($value, array $userField)
Определения prototypeitemdatamanager.php:390
$options
Определения commerceml2.php:49
$data['IS_AVAILABLE']
Определения .description.php:13
</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
$application
Определения bitrix.php:23
Определения arrayresult.php:2
Определения aliases.php:105
Определения collection.php:2
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$error
Определения subscription_card_product.php:20
$k
Определения template_pdf.php:567
$fields
Определения yandex_run.php:501