Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
prototypeitemdatamanager.php
1<?php
2
4
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
104 $result = new Main\ORM\EventResult();
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);
176 $result = new Main\ORM\EventResult();
177
178 $isUpdate = (isset($options['isUpdate']) && $options['isUpdate']);
179 $type = static::getType();
180 $userFieldManager = UserFieldHelper::getInstance()->getManager();
181 $connection = Main\Application::getConnection();
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 }
196 elseif($field['USER_TYPE']['BASE_TYPE'] === 'file')
197 {
198 if(is_numeric($oldData[$fieldName]) && array_key_exists($fieldName, $data) && (int) $oldData[$fieldName] !== (int) $data[$fieldName])
199 {
200 \CFile::Delete($oldData[$fieldName]);
201 }
202 }
203 }
204
205 // save multi values
206 foreach ($multiValues as $fieldName => $values)
207 {
208 $utmTableName = $typeDataClass::getMultipleValueTableName($type, $fields[$fieldName]);
209
210 if($isUpdate)
211 {
212 // another clutch to delete files if they had not been deleted before
213 if($fields[$fieldName]['USER_TYPE']['BASE_TYPE'] === 'file')
214 {
215 foreach($oldData[$fieldName] as $fileId)
216 {
217 if(is_numeric($fileId) && !in_array($fileId, $values))
218 {
219 \CFile::Delete($fileId);
220 }
221 }
222 }
223
224 $helper = $connection->getSqlHelper();
225 // first, delete old values
226 $connection->query(sprintf(
227 'DELETE FROM %s WHERE %s = %d',
228 $helper->quote($utmTableName), $helper->quote('ID'), $id
229 ));
230 }
231
232 foreach ($values as $value)
233 {
234 $connection->add($utmTableName, array('ID' => $id, 'VALUE' => $value));
235 }
236 }
237
238 return $result;
239 }
240
241 public static function onBeforeAdd(Event $event): ORM\EventResult
242 {
243 return static::modifyValuesBeforeSave($event->getParameter('id'), $event->getParameter('fields'));
244 }
245
246 public static function onAfterAdd(Event $event): ORM\EventResult
247 {
248 return static::saveMultipleValues($event->getParameter('id'), $event->getParameter('fields'));
249 }
250
251 public static function onBeforeUpdate(Event $event): ORM\EventResult
252 {
253 return static::modifyValuesBeforeSave($event->getParameter('id'), $event->getParameter('fields'), [
254 'isUpdate' => true,
255 ]);
256 }
257
258 public static function onAfterUpdate(Event $event): ORM\EventResult
259 {
260 return static::saveMultipleValues($event->getParameter('id'), $event->getParameter('fields'), [
261 'isUpdate' => true,
262 ]);
263 }
264
265 public static function onBeforeDelete(Event $event): ORM\EventResult
266 {
267 if ($oldData = static::getByPrimary($event->getParameter('id'))->fetch())
268 {
269 static::getTemporaryStorage()->saveData($event->getParameter('id'), $oldData);
270 }
271
272 return new Main\ORM\EventResult();
273 }
274
275 public static function onAfterDelete(Event $event): ORM\EventResult
276 {
277 $result = new Main\ORM\EventResult();
278 $oldData = static::getTemporaryStorage()->getData($event->getParameter('id'));
279 $id = static::getTemporaryStorage()->getIdByPrimary($event->getParameter('id'));
280 $userFieldManager = UserFieldHelper::getInstance()->getManager();
281 $type = static::getType();
282 $connection = Main\Application::getConnection();
283 $helper = $connection->getSqlHelper();
284 [$factory] = UserFieldHelper::getInstance()->parseUserFieldEntityId(static::getItemUserFieldEntityId());
286 $typeDataClass = $factory->getTypeDataClass();
287
288 $fields = $userFieldManager->getUserFields(static::getItemUserFieldEntityId());
289 foreach ($oldData as $k => $v)
290 {
291 $userfield = $fields[$k];
292
293 // remove multi values
294 if ($userfield['MULTIPLE'] == 'Y')
295 {
296 $utmTableName = $typeDataClass::getMultipleValueTableName($type, $userfield);
297
298 try
299 {
300 $connection->query(sprintf(
301 'DELETE FROM %s WHERE %s = %d',
302 $helper->quote($utmTableName), $helper->quote('ID'), $id
303 ));
304 }
305 catch(Main\DB\SqlQueryException $e)
306 {
307 $result->addError(new ORM\EntityError($e->getMessage()));
308 }
309 }
310
311 // remove files
312 if ($userfield["USER_TYPE"]["BASE_TYPE"]=="file")
313 {
314 if(is_array($oldData[$k]))
315 {
316 foreach($oldData[$k] as $value)
317 {
318 \CFile::delete($value);
319 }
320 }
321 else
322 {
323 \CFile::delete($oldData[$k]);
324 }
325 }
326 }
327
328 return $result;
329 }
330
338 protected static function convertValuesBeforeSave(array $data, array $userFields): array
339 {
340 foreach ($data as $k => $v)
341 {
342 if (static::isOwnField($k))
343 {
344 continue;
345 }
346
347 $userField = $userFields[$k];
348
349 if ($userField['MULTIPLE'] == 'N')
350 {
351 $inputValue = [$v];
352 }
353 else
354 {
355 $inputValue = $v;
356 }
357
358 $tmpValue = [];
359
360 foreach ($inputValue as $singleValue)
361 {
362 $tmpValue[] = static::convertSingleValueBeforeSave($singleValue, $userField);
363 }
364
365 // write value back
366 if ($userField['MULTIPLE'] == 'N')
367 {
368 $data[$k] = $tmpValue[0];
369 }
370 else
371 {
372 // remove empty (false) values
373 $tmpValue = array_filter($tmpValue, ['static', 'isNotNull']);
374
375 $data[$k] = $tmpValue;
376 $multiValues[$k] = $tmpValue;
377 }
378 }
379
380 return $data;
381 }
382
389 protected static function convertSingleValueBeforeSave($value, array $userField)
390 {
391 if (!isset($userField['USER_TYPE']) || !is_array($userField['USER_TYPE']))
392 {
393 $userField['USER_TYPE'] = array();
394 }
395 elseif (
396 isset($userField['USER_TYPE']['BASE_TYPE'])
397 && $userField['USER_TYPE']['BASE_TYPE'] === 'datetime'
398 )
399 {
400 $useTimezone = isset($userField['SETTINGS']['USE_TIMEZONE']) && $userField['SETTINGS']['USE_TIMEZONE'] === 'Y';
401
402 if ($useTimezone)
403 {
404 if ($value instanceof Main\Type\DateTime)
405 {
406 $value = $value::createFromUserTime($value->format(Main\Type\DateTime::getFormat()));
407 }
408 elseif (is_string($value) && Main\Type\DateTime::isCorrect($value))
409 {
410 $value = Main\Type\DateTime::createFromUserTime($value);
411 }
412 }
413 else
414 {
415 if (is_string($value) && Main\Type\DateTime::isCorrect($value))
416 {
417 $value = new Main\Type\DateTime($value);
418 }
419 if ($value instanceof Main\Type\DateTime)
420 {
421 $value->disableUserTime();
422 }
423 }
424 }
425
426 if (
427 isset($userField['USER_TYPE']['CLASS_NAME']) &&
428 is_callable(array($userField['USER_TYPE']['CLASS_NAME'], 'onbeforesave'))
429 )
430 {
431 $value = call_user_func_array(
432 array($userField['USER_TYPE']['CLASS_NAME'], 'onbeforesave'), array($userField, $value)
433 );
434 }
435
436 if (static::isNotNull($value))
437 {
438 return $value;
439 }
440 elseif (
441 isset($userField['USER_TYPE']['BASE_TYPE']) &&
442 (
443 $userField['USER_TYPE']['BASE_TYPE'] == 'int' ||
444 $userField['USER_TYPE']['BASE_TYPE'] == 'double'
445 )
446 )
447 {
448 return null;
449 }
450 else
451 {
452 return false;
453 }
454 }
455
456 protected static function isNotNull($value): bool
457 {
458 return !($value === null || $value === false || $value === '');
459 }
460
461 public static function isOwnField(string $fieldName): bool
462 {
463 return array_key_exists($fieldName, static::getOwnFieldNames());
464 }
465
471 public static function getOwnFieldNames(): array
472 {
473 static $fields;
474 if($fields === null)
475 {
476 $fields = [];
477
478 foreach(static::getMap() as $field)
479 {
480 $fields[$field->getName()] = $field->getName();
481 }
482 }
483
484 return $fields;
485 }
486
487 public static function getUserFieldValues(int $id, array $userFields): ?array
488 {
489 $data = static::getList([
490 'select' => array_keys($userFields),
491 'filter' => [
492 '=ID' => $id,
493 ]
494 ])->fetch();
495
496 if (is_array($data))
497 {
498 return $data;
499 }
500
501 return null;
502 }
503
504 public static function updateUserFieldValues(int $id, array $fields): Main\Result
505 {
506 return static::update($id, $fields);
507 }
508
509 public static function deleteUserFieldValues(int $id): Main\Result
510 {
511 $fields = [];
512 $userFields = UserFieldHelper::getInstance()->getManager()->GetUserFields(static::getItemUserFieldEntityId());
513 foreach($userFields as $userField)
514 {
515 $fields[$userField['FIELD_NAME']] = null;
516 }
517
518 return static::update($id, $fields);
519 }
520}
getParameter($key)
Definition event.php:80
static onAfterDelete(Event $event)
static getFormat(Context\Culture $culture=null)
Definition date.php:261
static isCorrect($time, $format=null)
Definition date.php:356
static modifyValuesBeforeSave($id, array $data, array $options=[])
static checkFields(ORM\Data\Result $result, $primary, array $data)