Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
userfieldproxy.php
1<?
2namespace Bitrix\Rest;
6
7abstract class UserFieldProxy
8{
9 protected $entityID = '';
11 protected $user = null;
12 protected $isAdminUser = null;
13 protected $isAuthorizedUser = null;
14 protected $namePrefix = '';
15 private static $langs = null;
16 private static $fieldsInfo = null;
17 private static $langIncluded = false;
18
19 function __construct($entityID, \CUser $user = null)
20 {
21 if(!is_string($entityID))
22 {
23 throw new Main\ArgumentTypeException('entityID', 'string');
24 }
25
26 $this->entityID = $entityID;
27 $this->user = $user !== null ? $user : $this->getCurrentUser();
28 }
29 public function getEntityID()
30 {
31 return $this->entityID;
32 }
33
34 public function getNamePrefix()
35 {
36 return $this->namePrefix;
37 }
38 public function setNamePrefix($prefix)
39 {
40 if(!is_string($prefix))
41 {
42 throw new Main\ArgumentTypeException('prefix', 'string');
43 }
44
45 $this->namePrefix = $prefix !== ''? mb_strtoupper($prefix) : '';
46 }
47 public static function getFields()
48 {
49 if(self::$fieldsInfo === null)
50 {
51 //isReadOnly - Can not be defined by user. Read only access.
52 //isImmutable - Can be defined by user during creation. It can not be changed.
53 //isMultiple - It is multiple (array will be returned).
54
55 self::includeLangFile();
56 self::$fieldsInfo = array(
57 'ID' => array('type' => 'int', 'title' => GetMessage('REST_UF_ID'), 'isReadOnly'=> true),
58 'ENTITY_ID' => array('type' => 'string', 'title' => GetMessage('REST_UF_ENTITY_ID'), 'isImmutable' => true),
59 'FIELD_NAME' => array('type' => 'string', 'title' => GetMessage('REST_UF_FIELD_NAME'), 'isImmutable' => true),
60 'USER_TYPE_ID' => array('type' => 'string', 'title' => GetMessage('REST_UF_USER_TYPE_ID'), 'isImmutable' => true),
61 'XML_ID' => array('type' => 'string', 'title' => GetMessage('REST_UF_XML_ID')),
62 'SORT' => array('type' => 'int', 'title' => GetMessage('REST_UF_SORT')),
63 'MULTIPLE' => array('type' => 'char', 'title' => GetMessage('REST_UF_MULTIPLE')),
64 'MANDATORY' => array('type' => 'char', 'title' => GetMessage('REST_UF_MANDATORY')),
65 'SHOW_FILTER' => array('type' => 'char', 'title' => GetMessage('REST_UF_SHOW_FILTER')),
66 'SHOW_IN_LIST' => array('type' => 'char', 'title' => GetMessage('REST_UF_SHOW_IN_LIST')),
67 'EDIT_IN_LIST' => array('type' => 'char', 'title' => GetMessage('REST_UF_EDIT_IN_LIST')),
68 'IS_SEARCHABLE' => array('type' => 'char', 'title' => GetMessage('REST_UF_IS_SEARCHABLE')),
69 'EDIT_FORM_LABEL' => array('type' => 'string', 'title' => GetMessage('REST_UF_EDIT_FORM_LABEL')),
70 'LIST_COLUMN_LABEL' => array('type' => 'string', 'title' => GetMessage('REST_UF_LIST_COLUMN_LABEL')),
71 'LIST_FILTER_LABEL' => array('type' => 'string', 'title' => GetMessage('REST_UF_LIST_FILTER_LABEL')),
72 'ERROR_MESSAGE' => array('type' => 'string', 'title' => GetMessage('REST_UF_ERROR_MESSAGE')),
73 'HELP_MESSAGE' => array('type' => 'string', 'title' => GetMessage('REST_UF_HELP_MESSAGE')),
74 'LIST' => array('type' => 'uf_enum_element', 'title' => GetMessage('REST_UF_LIST'), 'isMultiple'=> true),
75 'SETTINGS' => array('type' => 'object', 'title' => GetMessage('REST_UF_SETTINGS'))
76 );
77 }
78
79 return self::$fieldsInfo;
80 }
81 public static function getEnumerationElementFields()
82 {
83 self::includeLangFile();
84 return array(
85 'ID' => array('type' => 'int', 'title' => GetMessage('REST_UF_ID'), 'isReadOnly'=> true),
86 'SORT' => array('type' => 'int', 'title' => GetMessage('REST_UF_SORT')),
87 'VALUE' => array('type' => 'string', 'title' => GetMessage('REST_UF_VALUE')),
88 'DEF' => array('type' => 'string', 'title' => GetMessage('REST_UF_IS_DEF')),
89 'DEL' => array('type' => 'string', 'title' => GetMessage('REST_UF_DEL')),
90 );
91 }
92 public static function getSettingsFields($typeID)
93 {
94 if(!is_string($typeID))
95 {
96 throw new Main\ArgumentTypeException('typeID', 'string');
97 }
98
99 if($typeID === '')
100 {
101 throw new Main\ArgumentException('Empty string is specified', 'typeID');
102 }
103
104
105 self::includeLangFile();
106 switch($typeID)
107 {
108 case 'string':
109 {
110 return array(
111 'DEFAULT_VALUE' => array('type' => 'string', 'title' => GetMessage('REST_UF_DEFAULT_VALUE')),
112 'ROWS' => array('type' => 'int', 'title' => GetMessage('REST_UF_ROWS'))
113 );
114 }
115 case 'integer':
116 {
117 return array(
118 'DEFAULT_VALUE' => array('type' => 'int', 'title' => GetMessage('REST_UF_DEFAULT_VALUE'))
119 );
120 }
121 case 'double':
122 {
123 return array(
124 'DEFAULT_VALUE' => array('type' => 'double', 'title' => GetMessage('REST_UF_DEFAULT_VALUE')),
125 'PRECISION' => array('type' => 'int', 'title' => GetMessage('REST_UF_PRECISION'))
126 );
127 }
128 case 'boolean':
129 {
130 return array(
131 'DEFAULT_VALUE' => array('type' => 'int', 'title' => GetMessage('REST_UF_DEFAULT_VALUE')),
132 'DISPLAY' => array('type' => 'string', 'title' => GetMessage('REST_UF_DISPLAY'))
133 );
134 }
135 case 'datetime':
136 {
137 return array(
138 'DEFAULT_VALUE' => array('type' => 'datetime', 'title' => GetMessage('REST_UF_DEFAULT_VALUE'))
139 );
140 }
141 case 'enumeration':
142 {
143 return array(
144 'DISPLAY' => array('type' => 'string', 'title' => GetMessage('REST_UF_DISPLAY')),
145 'LIST_HEIGHT' => array('type' => 'int', 'title' => GetMessage('REST_UF_LIST_HEIGHT')),
146 );
147 }
148 case 'iblock_section':
149 case 'iblock_element':
150 {
151 return array(
152 'DEFAULT_VALUE' => array('type' => 'int', 'title' => GetMessage('REST_UF_DEFAULT_VALUE')),
153 'IBLOCK_ID' => array('type' => 'int', 'title' => GetMessage('REST_UF_IBLOCK_ID')),
154 'IBLOCK_TYPE_ID' => array('type' => 'string', 'title' => GetMessage('REST_UF_IBLOCK_TYPE_ID')),
155 'DISPLAY' => array('type' => 'string', 'title' => GetMessage('REST_UF_DISPLAY')),
156 'LIST_HEIGHT' => array('type' => 'int', 'title' => GetMessage('REST_UF_LIST_HEIGHT')),
157 'ACTIVE_FILTER' => array('type' => 'char', 'title' => GetMessage('REST_UF_ACTIVE_FILTER'))
158 );
159 }
160 case 'crm_status':
161 {
162 return array(
163 'ENTITY_TYPE' => array('type' => 'string', 'title' => GetMessage('REST_UF_ENTITY_TYPE'))
164 );
165 }
166 case 'crm':
167 {
168 return array(
169 'LEAD' => array('type' => 'char', 'title' => GetMessage('REST_UF_CRM_LEAD')),
170 'CONTACT' => array('type' => 'char', 'title' => GetMessage('REST_UF_CRM_CONTACT')),
171 'COMPANY' => array('type' => 'char', 'title' => GetMessage('REST_UF_CRM_COMPANY')),
172 'DEAL' => array('type' => 'char', 'title' => GetMessage('REST_UF_CRM_DEAL'))
173 );
174 }
175 default:
176 {
177 return array();
178 }
179 }
180 }
181 public static function getTypes(\CRestServer $server = null)
182 {
183 self::includeLangFile();
184 $result = array(
185 array('ID' => 'string', 'title' => GetMessage('REST_UF_TYPE_STRING')),
186 array('ID' => 'integer', 'title' => GetMessage('REST_UF_TYPE_INTEGER')),
187 array('ID' => 'double', 'title' => GetMessage('REST_UF_TYPE_DOUBLE')),
188 array('ID' => 'boolean', 'title' => GetMessage('REST_UF_TYPE_BOOLEAN')),
189 array('ID' => 'enumeration', 'title' => GetMessage('REST_UF_TYPE_ENUMERATION')),
190 array('ID' => 'datetime', 'title' => GetMessage('REST_UF_TYPE_DATETIME')),
191 array('ID' => 'date', 'title' => GetMessage('REST_UF_TYPE_DATE')),
192 array('ID' => 'money', 'title' => GetMessage('REST_UF_TYPE_MONEY')),
193 array('ID' => 'url', 'title' => GetMessage('REST_UF_TYPE_URL')),
194 array('ID' => 'address', 'title' => GetMessage('REST_UF_TYPE_ADDRESS')),
195 array('ID' => 'file', 'title' => GetMessage('REST_UF_TYPE_FILE')),
196 array('ID' => 'employee', 'title' => GetMessage('REST_UF_TYPE_EMPLOYEE')),
197 array('ID' => 'crm_status', 'title' => GetMessage('REST_UF_TYPE_CRM_STATUS')),
198 array('ID' => 'iblock_section', 'title' => GetMessage('REST_UF_TYPE_IBLOCK_SECTION')),
199 array('ID' => 'iblock_element', 'title' => GetMessage('REST_UF_TYPE_IBLOCK_ELEMENT')),
200 array('ID' => 'crm', 'title' => GetMessage('REST_UF_TYPE_CRM'))
201 );
202
203 if($server !== null && $server->getAuthType() === OAuth\Auth::AUTH_TYPE)
204 {
205 $clientInfo = AppTable::getByClientId($server->getClientId());
206 $placementHandlerList = PlacementTable::getHandlersList(UserFieldType::PLACEMENT_UF_TYPE);
207
208 foreach($placementHandlerList as $handler)
209 {
210 if($handler['APP_ID'] === $clientInfo['ID'])
211 {
212 $result[] = array(
213 'ID' => $handler['ADDITIONAL'],
214 'title' => $handler['TITLE']
215 );
216 }
217 }
218 }
219
220 return $result;
221 }
222 public function add(array $fields)
223 {
224 global $APPLICATION;
225 if(!$this->checkCreatePermission())
226 {
227 throw new RestException('Access denied.');
228 }
229
230 if($this->entityID === '')
231 {
232 throw new RestException('Operation is not allowed. Entity ID is not defined.');
233 }
234
235 //Try get default field label
236 $defaultLabel = isset($fields['LABEL']) ? trim($fields['LABEL']) : '';
237
238 self::sanitizeFields($fields);
239 $fields['ENTITY_ID'] = $this->entityID;
240 $errors = array();
241
242 $userTypeID = isset($fields['USER_TYPE_ID']) ? trim($fields['USER_TYPE_ID']) : '';
243 if($userTypeID === '')
244 {
245 $errors[] = "The 'USER_TYPE_ID' field is not found.";
246 }
247 $fields['USER_TYPE_ID'] = $userTypeID;
248
249 $fieldName = isset($fields['FIELD_NAME']) ? trim($fields['FIELD_NAME']) : '';
250 if($fieldName === '')
251 {
252 $errors[] = "The 'FIELD_NAME' field is not found.";
253 }
254
255 $fieldName = mb_strtoupper($fieldName);
256 $prefix = $this->namePrefix;
257 if($prefix !== '')
258 {
259 $fullPrefix = 'UF_'.$prefix.'_';
260 $fullPrefixLen = mb_strlen($fullPrefix);
261 if(strncmp($fieldName, $fullPrefix, $fullPrefixLen) !== 0)
262 {
263 $fieldName = strncmp($fieldName, 'UF_', 3) === 0
264 ? $fullPrefix.mb_substr($fieldName, 3)
265 : $fullPrefix.$fieldName;
266 }
267 }
268 else
269 {
270 $fullPrefix = 'UF_';
271 $fullPrefixLen = 3;
272 if(strncmp($fieldName, $fullPrefix, $fullPrefixLen) !== 0)
273 {
274 $fieldName = 'UF_'. $fieldName;
275 }
276 }
277
278 $fields['FIELD_NAME'] = $fieldName;
279
280 if(!empty($errors))
281 {
282 throw new RestException(implode("\n", $errors));
283 }
284
285 if($defaultLabel === '')
286 {
287 $defaultLabel = $fieldName;
288 }
289
290 self::prepareLabels($fields, 'LIST_FILTER_LABEL', $defaultLabel);
291 self::prepareLabels($fields, 'LIST_COLUMN_LABEL', $defaultLabel);
292 self::prepareLabels($fields, 'EDIT_FORM_LABEL', $defaultLabel);
293 self::prepareLabels($fields, 'ERROR_MESSAGE', $defaultLabel);
294 self::prepareLabels($fields, 'HELP_MESSAGE', $defaultLabel);
295
296 $fields['MULTIPLE'] = isset($fields['MULTIPLE']) && mb_strtoupper($fields['MULTIPLE']) === 'Y' ? 'Y' : 'N';
297 $fields['MANDATORY'] = isset($fields['MANDATORY']) && mb_strtoupper($fields['MANDATORY']) === 'Y' ? 'Y' : 'N';
298 $fields['SHOW_FILTER'] = isset($fields['SHOW_FILTER']) && mb_strtoupper($fields['SHOW_FILTER']) === 'Y' ? 'E' : 'N'; // E - 'By mask' is default
299
300 $isMultiple = isset($fields['MULTIPLE']) && $fields['MULTIPLE'] === 'Y';
301
302 $settings = isset($fields['SETTINGS']) && is_array($fields['SETTINGS']) ? $fields['SETTINGS'] : array();
303 $effectiveSettings = array();
304 switch ($userTypeID)
305 {
306 case 'string':
307 {
308 $effectiveSettings['DEFAULT_VALUE'] = isset($settings['DEFAULT_VALUE'])
309 ? $settings['DEFAULT_VALUE'] : '';
310
311 $effectiveSettings['ROWS'] = $settings['ROWS'] > 0
312 ? $settings['ROWS'] : 1;
313 break;
314 }
315 case 'integer':
316 {
317 $effectiveSettings['DEFAULT_VALUE'] = isset($settings['DEFAULT_VALUE'])
318 ? $settings['DEFAULT_VALUE'] : '';
319 break;
320 }
321 case 'double':
322 {
323 $effectiveSettings['DEFAULT_VALUE'] = isset($settings['DEFAULT_VALUE'])
324 ? $settings['DEFAULT_VALUE'] : '';
325
326 $effectiveSettings['PRECISION'] = $settings['PRECISION'] >= 0
327 ? $settings['PRECISION'] : 2;
328 break;
329 }
330 case 'boolean':
331 {
332 $effectiveSettings['DEFAULT_VALUE'] = isset($settings['DEFAULT_VALUE'])
333 && $settings['DEFAULT_VALUE'] > 0 ? 1 : 0;
334
335 $display = isset($settings['DISPLAY']) ? $settings['DISPLAY'] : '';
336 $effectiveSettings['DISPLAY'] = $display !== ''? mb_strtoupper($display) : 'CHECKBOX';
337
338 $fields['MULTIPLE'] = 'N';
339 break;
340 }
341 case 'date':
342 case 'datetime':
343 {
344 $defaultValue = isset($settings['DEFAULT_VALUE']) ? $settings['DEFAULT_VALUE'] : array();
345 if(!is_array($defaultValue))
346 {
347 $defaultValue = array('VALUE' => $defaultValue, 'TYPE' => 'NONE');
348 }
349
350 $effectiveSettings['DEFAULT_VALUE'] = array(
351 'VALUE' => isset($defaultValue['VALUE'])
352 ? \CRestUtil::unConvertDateTime($defaultValue['VALUE']) : '',
353 'TYPE' => isset($defaultValue['TYPE']) && $defaultValue['TYPE'] !== ''
354 ? mb_strtoupper($defaultValue['TYPE']) : 'NONE'
355 );
356 break;
357 }
358 case 'enumeration':
359 {
360 $display = isset($settings['DISPLAY']) ? $settings['DISPLAY'] : '';
361 $effectiveSettings['DISPLAY'] = $display !== ''? mb_strtoupper($display) : 'LIST';
362
363 $height = isset($settings['LIST_HEIGHT']) ? (int)$settings['LIST_HEIGHT'] : 0;
364 $effectiveSettings['LIST_HEIGHT'] = $height > 0 ? $height : 1;
365
366 $listItems = isset($fields['LIST']) && is_array($fields['LIST']) ? $fields['LIST'] : array();
367 $effectiveListItems = array();
368
369 $counter = 0;
370 $defaultItemKey = '';
371 foreach($listItems as $item)
372 {
373 $itemValue = isset($item['VALUE']) ? trim($item['VALUE'], " \t\n\r") : '';
374 if($itemValue === '')
375 {
376 continue;
377 }
378
379 $effectiveItem = array('VALUE' => $itemValue);
380 $itemSort = isset($item['SORT']) && is_numeric($item['SORT']) ? (int)$item['SORT'] : 0;
381 if($itemSort > 0)
382 {
383 $effectiveItem['SORT'] = $itemSort;
384 }
385
386 if($itemSort > 0)
387 {
388 $effectiveItem['SORT'] = $itemSort;
389 }
390
391 $itemKey = "n{$counter}";
392 $counter++;
393
394 if(isset($item['DEF']))
395 {
396 $isDefault = mb_strtoupper($item['DEF']) === 'Y';
397 if($isMultiple)
398 {
399 $effectiveItem['DEF'] = $isDefault ? 'Y' : 'N';
400 }
401 elseif($isDefault && $defaultItemKey === '')
402 {
403 $defaultItemKey = $itemKey;
404 }
405 }
406
407 $effectiveListItems[$itemKey] = &$effectiveItem;
408 unset($effectiveItem);
409 }
410
411 if(!$isMultiple && $defaultItemKey !== '')
412 {
413 foreach($effectiveListItems as $key => &$item)
414 {
415 $item['DEF'] = $key === $defaultItemKey ? 'Y' : 'N';
416 }
417 unset($item);
418 }
419 $fields['LIST'] = $effectiveListItems;
420 break;
421 }
422 case 'iblock_section':
423 case 'iblock_element':
424 {
425 $effectiveSettings['IBLOCK_TYPE_ID'] = isset($settings['IBLOCK_TYPE_ID']) ? $settings['IBLOCK_TYPE_ID'] : '';
426 $effectiveSettings['IBLOCK_ID'] = isset($settings['IBLOCK_ID']) ? (int)$settings['IBLOCK_ID'] : 0;
427 $effectiveSettings['DEFAULT_VALUE'] = isset($settings['DEFAULT_VALUE']) ? $settings['DEFAULT_VALUE'] : '';
428
429 $display = isset($settings['DISPLAY']) ? $settings['DISPLAY'] : '';
430 $effectiveSettings['DISPLAY'] = $display !== ''? mb_strtoupper($display) : 'LIST';
431
432 $height = isset($settings['LIST_HEIGHT']) ? (int)$settings['LIST_HEIGHT'] : 0;
433 $effectiveSettings['LIST_HEIGHT'] = $height > 0 ? $height : 1;
434 $effectiveSettings['ACTIVE_FILTER'] = isset($settings['ACTIVE_FILTER'])
435 && mb_strtoupper($settings['ACTIVE_FILTER']) === 'Y' ? 'Y' : 'N';
436 break;
437 }
438 case 'crm_status':
439 {
440 $effectiveSettings['ENTITY_TYPE'] = isset($settings['ENTITY_TYPE']) ? $settings['ENTITY_TYPE'] : '';
441 break;
442 }
443 case 'crm':
444 {
445 $effectiveSettings['LEAD'] = isset($settings['LEAD']) && mb_strtoupper($settings['LEAD']) === 'Y' ? 'Y' : 'N';
446 $effectiveSettings['CONTACT'] = isset($settings['CONTACT']) && mb_strtoupper($settings['CONTACT']) === 'Y' ? 'Y' : 'N';
447 $effectiveSettings['COMPANY'] = isset($settings['COMPANY']) && mb_strtoupper($settings['COMPANY']) === 'Y' ? 'Y' : 'N';
448 $effectiveSettings['DEAL'] = isset($settings['DEAL']) && mb_strtoupper($settings['DEAL']) === 'Y' ? 'Y' : 'N';
449 break;
450 }
451 case 'employee':
452 {
453 if($fields['SHOW_FILTER'] !== 'N')
454 {
455 $fields['SHOW_FILTER'] = 'I'; // Force exact match for 'USER' field type
456 }
457 break;
458 }
459 default:
460 {
461 $userTypeList = PlacementTable::getHandlersList(UserFieldType::PLACEMENT_UF_TYPE);
462
463 foreach($userTypeList as $userType)
464 {
465 if($userType['ADDITIONAL'] === $userTypeID)
466 {
467 $fields['USER_TYPE_ID'] = UserField\Callback::getUserTypeId($userType);
468 }
469 }
470
471 $fields['SHOW_FILTER'] = 'N';
472 }
473 }
474
475 $fields['SETTINGS'] = $effectiveSettings;
476
477 $entity = new \CUserTypeEntity();
478 $ID = $entity->Add($fields);
479 if($ID <= 0)
480 {
481 $exc = $APPLICATION->GetException();
482 $errors[] = $exc !== false ? $exc->GetString() : 'Fail to create new user field.';
483 }
484 elseif ($userTypeID === 'enumeration' && isset($fields['LIST']) && is_array($fields['LIST']))
485 {
486 $enum = new \CUserFieldEnum();
487 if(!$enum->SetEnumValues($ID, $fields['LIST']))
488 {
489 $exc = $APPLICATION->GetException();
490 $errors[] = $exc !== false ? $exc->GetString() : 'Fail to save enumumeration field values.';
491 }
492 }
493
494 if(!empty($errors))
495 {
496 throw new RestException(implode("\n", $errors), RestException::ERROR_CORE);
497 }
498
499 return $ID;
500 }
501 public function get($ID)
502 {
503 if(!is_int($ID))
504 {
505 $ID = (int)$ID;
506 }
507
508 if($ID <= 0)
509 {
510 throw new RestException('ID is not defined or invalid.');
511 }
512
513 if(!$this->checkReadPermission())
514 {
515 throw new RestException('Access denied.');
516 }
517
518 if($this->entityID === '')
519 {
520 throw new RestException('Operation is not allowed. Entity ID is not defined.');
521 }
522
523 $entity = new \CUserTypeEntity();
524 $result = $entity->GetByID($ID);
525 if(!is_array($result))
526 {
527 throw new RestException("The entity with ID '{$ID}' is not found.", RestException::ERROR_NOT_FOUND);
528 }
529
530 $entityID = isset($result['ENTITY_ID']) ? $result['ENTITY_ID'] : '';
531 if($entityID !== $this->entityID)
532 {
533 throw new RestException('Access denied.');
534 }
535
536 if($result['USER_TYPE_ID'] === 'enumeration')
537 {
538 $result['LIST'] = array();
539
540 $enumEntity = new \CUserFieldEnum();
541 $dbResultEnum = $enumEntity->GetList(array('SORT' => 'ASC'), array('USER_FIELD_ID' => $ID));
542 while($enum = $dbResultEnum->Fetch())
543 {
544 $result['LIST'][] = array(
545 'ID' => $enum['ID'],
546 'SORT' => $enum['SORT'],
547 'VALUE' => $enum['VALUE'],
548 'DEF' => $enum['DEF']
549 );
550 }
551 }
552 elseif(preg_match("/^".UserField\Callback::USER_TYPE_ID_PREFIX."_([\d]+)_/", $result['USER_TYPE_ID'], $matches))
553 {
554 $result['USER_TYPE_ID'] = str_replace($matches[0], '', $result['USER_TYPE_ID']);
555
556 $appInfo = AppTable::getByClientId($matches[1]);
557 $result['USER_TYPE_OWNER'] = $appInfo['CLIENT_ID'];
558 }
559
560 return $result;
561 }
562 public function getList(array $order, array $filter)
563 {
564 if(!$this->checkReadPermission())
565 {
566 throw new RestException('Access denied.');
567 }
568
569 if($this->entityID === '')
570 {
571 throw new RestException('Operation is not allowed. Entity ID is not defined.');
572 }
573 $filter['ENTITY_ID'] = $this->entityID;
574
575 if(isset($filter['USER_TYPE_ID']))
576 {
577 $handlerList = PlacementTable::getHandlersList(UserFieldType::PLACEMENT_UF_TYPE);
578 foreach($handlerList as $handler)
579 {
580 if($handler['ADDITIONAL'] === $filter['USER_TYPE_ID'])
581 {
582 $filter['USER_TYPE_ID'] = Callback::getUserTypeId($handler);
583 }
584 }
585 }
586
587 $entity = new \CUserTypeEntity();
588 $dbResult = $entity->GetList($order, $filter);
589 $result = array();
590 while($fields = $dbResult->Fetch())
591 {
592 $userTypeID = isset($fields['USER_TYPE_ID']) ? $fields['USER_TYPE_ID'] : '';
593 if($userTypeID === 'datetime'
594 && isset($fields['SETTINGS'])
595 && isset($fields['SETTINGS']['DEFAULT_VALUE'])
596 && isset($fields['SETTINGS']['DEFAULT_VALUE']['VALUE'])
597 && $fields['SETTINGS']['DEFAULT_VALUE']['VALUE'] !== '')
598 {
599 $fields['SETTINGS']['DEFAULT_VALUE']['VALUE'] = \CRestUtil::ConvertDateTime($fields['SETTINGS']['DEFAULT_VALUE']['VALUE']);
600 }
601
602 if($userTypeID === 'enumeration')
603 {
604 $fields['LIST'] = array();
605
606 $enumEntity = new \CUserFieldEnum();
607 $dbResultEnum = $enumEntity->GetList(array('SORT' => 'ASC'), array('USER_FIELD_ID' => $fields['ID']));
608 while($enum = $dbResultEnum->Fetch())
609 {
610 $fields['LIST'][] = array(
611 'ID' => $enum['ID'],
612 'SORT' => $enum['SORT'],
613 'VALUE' => $enum['VALUE'],
614 'DEF' => $enum['DEF']
615 );
616 }
617 }
618 elseif(preg_match("/^".UserField\Callback::USER_TYPE_ID_PREFIX."_([\d]+)_/", $userTypeID, $matches))
619 {
620 $fields['USER_TYPE_ID'] = str_replace($matches[0], '', $fields['USER_TYPE_ID']);
621
622 $appInfo = AppTable::getByClientId($matches[1]);
623 $fields['USER_TYPE_OWNER'] = $appInfo['CLIENT_ID'];
624 }
625
626 $result[] = $fields;
627 }
628
629 $result['total'] = count($result);
630 return $result;
631 }
632 public function update($ID, array $fields)
633 {
634 global $APPLICATION;
635
636 if(!is_int($ID))
637 {
638 $ID = (int)$ID;
639 }
640
641 if($ID <= 0)
642 {
643 throw new RestException('ID is not defined or invalid.');
644 }
645
646 if(!$this->checkUpdatePermission())
647 {
648 throw new RestException('Access denied.');
649 }
650
651 if($this->entityID === '')
652 {
653 throw new RestException('Operation is not allowed. Entity ID is not defined.');
654 }
655
656 $entity = new \CUserTypeEntity();
657
658 $persistedFields = $entity->GetByID($ID);
659 if(!is_array($persistedFields))
660 {
661 throw new RestException("The entity with ID '{$ID}' is not found.", RestException::ERROR_NOT_FOUND);
662 }
663
664 $entityID = isset($persistedFields['ENTITY_ID']) ? $persistedFields['ENTITY_ID'] : '';
665 if($entityID !== $this->entityID)
666 {
667 throw new RestException('Access denied.');
668 }
669
670 //User type ID can't be changed.
671 $userTypeID = isset($persistedFields['USER_TYPE_ID']) ? $persistedFields['USER_TYPE_ID'] : '';
672 if($userTypeID === '')
673 {
674 throw new RestException("Could not find 'USER_TYPE_ID' in persisted entity with ID '{$ID}'.");
675 }
676
677 $isMultiple = isset($persistedFields['MULTIPLE']) && $persistedFields['MULTIPLE'] === 'Y';
678
679 self::sanitizeFields($fields);
680
681 if(isset($fields['LIST_FILTER_LABEL']))
682 {
683 self::prepareLabels($fields, 'LIST_FILTER_LABEL', '');
684 }
685 elseif(isset($persistedFields['LIST_FILTER_LABEL']))
686 {
687 $fields['LIST_FILTER_LABEL'] = $persistedFields['LIST_FILTER_LABEL'];
688 }
689
690 if(isset($fields['LIST_COLUMN_LABEL']))
691 {
692 self::prepareLabels($fields, 'LIST_COLUMN_LABEL', '');
693 }
694 elseif(isset($persistedFields['LIST_COLUMN_LABEL']))
695 {
696 $fields['LIST_COLUMN_LABEL'] = $persistedFields['LIST_COLUMN_LABEL'];
697 }
698
699 if(isset($fields['EDIT_FORM_LABEL']))
700 {
701 self::prepareLabels($fields, 'EDIT_FORM_LABEL', '');
702 }
703 elseif(isset($persistedFields['EDIT_FORM_LABEL']))
704 {
705 $fields['EDIT_FORM_LABEL'] = $persistedFields['EDIT_FORM_LABEL'];
706 }
707
708 if(isset($fields['ERROR_MESSAGE']))
709 {
710 self::prepareLabels($fields, 'ERROR_MESSAGE', '');
711 }
712 elseif(isset($persistedFields['ERROR_MESSAGE']))
713 {
714 $fields['ERROR_MESSAGE'] = $persistedFields['ERROR_MESSAGE'];
715 }
716
717 if(isset($fields['HELP_MESSAGE']))
718 {
719 self::prepareLabels($fields, 'HELP_MESSAGE', '');
720 }
721 elseif(isset($persistedFields['HELP_MESSAGE']))
722 {
723 $fields['HELP_MESSAGE'] = $persistedFields['HELP_MESSAGE'];
724 }
725
726 $settings = isset($fields['SETTINGS']) && is_array($fields['SETTINGS']) ? $fields['SETTINGS'] : array();
727 $effectiveSettings = isset($persistedFields['SETTINGS']) && is_array($persistedFields['SETTINGS'])
728 ? $persistedFields['SETTINGS'] : array();
729
730 if(isset($fields['SHOW_FILTER']))
731 {
732 $fields['SHOW_FILTER'] = mb_strtoupper($fields['SHOW_FILTER']) === 'Y' ? 'E' : 'N'; // E - 'By mask' is default
733 }
734
735 switch ($userTypeID)
736 {
737 case 'string':
738 {
739 if(isset($settings['DEFAULT_VALUE']))
740 {
741 $effectiveSettings['DEFAULT_VALUE'] = $settings['DEFAULT_VALUE'];
742 }
743
744 if(isset($settings['ROWS']))
745 {
746 $effectiveSettings['ROWS'] = min(max($settings['ROWS'], 1), 50);
747 }
748 break;
749 }
750 case 'integer':
751 {
752 if(isset($settings['DEFAULT_VALUE']))
753 {
754 $effectiveSettings['DEFAULT_VALUE'] = $settings['DEFAULT_VALUE'];
755 }
756 break;
757 }
758 case 'double':
759 {
760 if(isset($settings['DEFAULT_VALUE']))
761 {
762 $effectiveSettings['DEFAULT_VALUE'] = $settings['DEFAULT_VALUE'];
763 }
764
765 if(isset($settings['PRECISION']))
766 {
767 $effectiveSettings['PRECISION'] = $settings['PRECISION'] >= 0
768 ? $settings['PRECISION'] : 2;
769 }
770 break;
771 }
772 case 'boolean':
773 {
774 if(isset($settings['DEFAULT_VALUE']))
775 {
776 $effectiveSettings['DEFAULT_VALUE'] = $settings['DEFAULT_VALUE'] > 0 ? 1 : 0;
777 }
778
779 if(isset($settings['DISPLAY']))
780 {
781 $effectiveSettings['DISPLAY'] = $settings['DISPLAY'] !== ''
782 ? mb_strtoupper($settings['DISPLAY']) : 'CHECKBOX';
783 }
784
785 unset($fields['MULTIPLE']);
786 break;
787 }
788 case 'datetime':
789 {
790 if(isset($settings['DEFAULT_VALUE']))
791 {
792 $defaultValue = $settings['DEFAULT_VALUE'];
793 if(!is_array($defaultValue))
794 {
795 $defaultValue = array('VALUE' => $defaultValue, 'TYPE' => 'NONE');
796 }
797
798 $effectiveSettings['DEFAULT_VALUE'] = array(
799 'VALUE' => isset($defaultValue['VALUE'])
800 ? \CRestUtil::unConvertDateTime($defaultValue['VALUE']) : '',
801 'TYPE' => isset($defaultValue['TYPE']) && $defaultValue['TYPE'] !== ''
802 ? mb_strtoupper($defaultValue['TYPE']) : 'NONE'
803 );
804 }
805 break;
806 }
807 case 'enumeration':
808 {
809 if(isset($settings['DISPLAY']))
810 {
811 $effectiveSettings['DISPLAY'] = $settings['DISPLAY'] !== ''
812 ? mb_strtoupper($settings['DISPLAY']) : 'LIST';
813 }
814
815 if(isset($settings['LIST_HEIGHT']))
816 {
817 $effectiveSettings['LIST_HEIGHT'] = $settings['LIST_HEIGHT'] > 0 ? $settings['LIST_HEIGHT'] : 1;
818 }
819
820 if(isset($fields['LIST']))
821 {
822 $listItems = is_array($fields['LIST']) ? $fields['LIST'] : array();
823 $effectiveListItems = array();
824
825 $counter = 0;
826 $defaultItemKey = '';
827 foreach($listItems as $item)
828 {
829 $itemValue = isset($item['VALUE']) ? trim($item['VALUE'], " \t\n\r") : '';
830
831 $effectiveItem = array('VALUE' => $itemValue);
832 $itemXmlID = isset($item['XML_ID']) ? $item['XML_ID'] : '';
833 if($itemXmlID !== '')
834 {
835 $effectiveItem['XML_ID'] = $itemXmlID;
836 }
837 $itemSort = isset($item['SORT']) && is_numeric($item['SORT']) ? (int)$item['SORT'] : 0;
838 if($itemSort > 0)
839 {
840 $effectiveItem['SORT'] = $itemSort;
841 }
842
843 $itemID = isset($item['ID']) && is_numeric($item['ID']) ? (int)$item['ID'] : 0;
844 if($itemID > 0)
845 {
846 $itemKey = strval($itemID);
847 if(isset($item['DEL']) && mb_strtoupper($item['DEL']) === 'Y')
848 {
849 $effectiveItem['DEL'] = 'Y';
850 }
851 }
852 else
853 {
854 $itemKey = "n{$counter}";
855 $counter++;
856 }
857
858 if(isset($item['DEF']))
859 {
860 $isDefault = mb_strtoupper($item['DEF']) === 'Y';
861 if($isMultiple)
862 {
863 $effectiveItem['DEF'] = $isDefault ? 'Y' : 'N';
864 }
865 elseif($isDefault && $defaultItemKey === '')
866 {
867 $defaultItemKey = $itemKey;
868 }
869 }
870
871 if(!empty($item))
872 {
873 $effectiveListItems[$itemKey] = &$effectiveItem;
874 }
875 unset($effectiveItem);
876 }
877
878 if(!$isMultiple && $defaultItemKey !== '')
879 {
880 foreach($effectiveListItems as $key => &$item)
881 {
882 $item['DEF'] = $key === $defaultItemKey ? 'Y' : 'N';
883 }
884 unset($item);
885 }
886 $fields['LIST'] = $effectiveListItems;
887 }
888
889 break;
890 }
891 case 'iblock_section':
892 case 'iblock_element':
893 {
894 if(isset($settings['IBLOCK_TYPE_ID']))
895 {
896 $effectiveSettings['IBLOCK_TYPE_ID'] = $settings['IBLOCK_TYPE_ID'];
897 }
898
899 if(isset($settings['IBLOCK_ID']))
900 {
901 $effectiveSettings['IBLOCK_ID'] = $settings['IBLOCK_ID'] > 0 ? $settings['IBLOCK_ID'] : 0;
902 }
903
904 if(isset($settings['DEFAULT_VALUE']))
905 {
906 $effectiveSettings['DEFAULT_VALUE'] = $settings['DEFAULT_VALUE'];
907 }
908
909 if(isset($settings['DISPLAY']))
910 {
911 $effectiveSettings['DISPLAY'] = $settings['DISPLAY'] !== ''
912 ? mb_strtoupper($settings['DISPLAY']) : 'LIST';
913 }
914
915 if(isset($settings['LIST_HEIGHT']))
916 {
917 $effectiveSettings['LIST_HEIGHT'] = $settings['LIST_HEIGHT'] > 0 ? $settings['LIST_HEIGHT'] : 1;
918 }
919
920 if(isset($settings['ACTIVE_FILTER']))
921 {
922 $effectiveSettings['ACTIVE_FILTER'] = mb_strtoupper($settings['ACTIVE_FILTER']) === 'Y' ? 'Y' : 'N';
923 }
924
925 break;
926 }
927 case 'crm_status':
928 {
929 if(isset($settings['ENTITY_TYPE']))
930 {
931 $effectiveSettings['ENTITY_TYPE'] = $settings['ENTITY_TYPE'];
932 }
933 break;
934 }
935 case 'crm':
936 {
937 if(isset($settings['LEAD']))
938 {
939 $effectiveSettings['LEAD'] = mb_strtoupper($settings['LEAD']) === 'Y' ? 'Y' : 'N';
940 }
941
942 if(isset($settings['CONTACT']))
943 {
944 $effectiveSettings['CONTACT'] = mb_strtoupper($settings['CONTACT']) === 'Y' ? 'Y' : 'N';
945 }
946
947 if(isset($settings['COMPANY']))
948 {
949 $effectiveSettings['COMPANY'] = mb_strtoupper($settings['COMPANY']) === 'Y' ? 'Y' : 'N';
950 }
951
952 if(isset($settings['DEAL']))
953 {
954 $effectiveSettings['DEAL'] = mb_strtoupper($settings['DEAL']) === 'Y' ? 'Y' : 'N';
955 }
956 break;
957 }
958 case 'employee':
959 {
960 if(isset($fields['SHOW_FILTER']) && $fields['SHOW_FILTER'] !== 'N')
961 {
962 $fields['SHOW_FILTER'] = 'I'; // Force exact match for 'USER' field type
963 }
964 break;
965 }
966 }
967
968 $fields['SETTINGS'] = $effectiveSettings;
969
970 if($entity->Update($ID, $fields) === false)
971 {
972 $exc = $APPLICATION->GetException();
973 throw new RestException(
974 $exc !== false ? $exc->GetString() : 'Fail to update user field.',
976 );
977 }
978 elseif($userTypeID === 'enumeration' && isset($fields['LIST']) && is_array($fields['LIST']))
979 {
980 $enum = new \CUserFieldEnum();
981 if(!$enum->SetEnumValues($ID, $fields['LIST']))
982 {
983 $exc = $APPLICATION->GetException();
984 throw new RestException(
985 $exc !== false ? $exc->GetString() : 'Fail to save enumumeration field values.',
987 );
988 }
989 }
990 return true;
991 }
992 public function delete($ID)
993 {
994 global $APPLICATION;
995
996 if(!is_int($ID))
997 {
998 $ID = (int)$ID;
999 }
1000
1001 if($ID <= 0)
1002 {
1003 throw new RestException('ID is not defined or invalid.');
1004 }
1005
1006 if(!$this->checkDeletePermission())
1007 {
1008 throw new RestException('Access denied.');
1009 }
1010
1011 $entity = new \CUserTypeEntity();
1012 $dbResult = $entity->GetList(array(), array('ID' => $ID));
1013 $persistedFields = is_object($dbResult) ? $dbResult->Fetch() : null;
1014 if(!is_array($persistedFields))
1015 {
1016 throw new RestException("The entity with ID '{$ID}' is not found.", RestException::ERROR_NOT_FOUND);
1017 }
1018
1019 $entityID = isset($persistedFields['ENTITY_ID']) ? $persistedFields['ENTITY_ID'] : '';
1020 if($entityID !== $this->entityID)
1021 {
1022 throw new RestException('Access denied.');
1023 }
1024
1025 if($entity->Delete($ID) === false)
1026 {
1027 $exc = $APPLICATION->GetException();
1028 throw new RestException(
1029 $exc !== false ? $exc->GetString() : 'Fail to delete user field.',
1031 );
1032 }
1033 return true;
1034 }
1035
1036 protected static function sanitizeFields(array &$fields)
1037 {
1038 $fieldsInfo = self::getFields();
1039 foreach($fields as $k => $v)
1040 {
1041 if(!isset($fieldsInfo[$k]))
1042 {
1043 unset($fields[$k]);
1044 }
1045 }
1046 }
1047 protected function isAuthorizedUser()
1048 {
1049 if($this->isAuthorizedUser === null)
1050 {
1051 $this->isAuthorizedUser = $this->user->IsAuthorized();
1052 }
1054 }
1055 protected function isAdminUser()
1056 {
1057 if($this->isAdminUser !== null)
1058 {
1059 return $this->isAdminUser;
1060 }
1061
1062 $this->isAdminUser = $this->user->IsAdmin();
1063
1064 if(!$this->isAdminUser
1065 && \Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24')
1066 && \Bitrix\Main\Loader::includeModule('bitrix24'))
1067 {
1068 try
1069 {
1070 $this->isAdminUser = \CBitrix24::IsPortalAdmin($this->user->GetID());
1071 }
1072 catch(\Exception $exc)
1073 {
1074 }
1075 }
1076
1077 return $this->isAdminUser;
1078 }
1079 protected function getCurrentUser()
1080 {
1081 return isset($USER) && ((get_class($USER) === 'CUser') || ($USER instanceof \CUser))
1082 ? $USER : (new \CUser());
1083 }
1084 protected static function getAllLanguages()
1085 {
1086 if(self::$langs !== null)
1087 {
1088 return self::$langs;
1089 }
1090
1091 self::$langs = array();
1092 $entity = new \CLanguage();
1093 $dbResult = $entity->GetList();
1094 while($lang = $dbResult->Fetch())
1095 {
1096 self::$langs[$lang['LID']] = array('LID' => $lang['LID'], 'NAME' => $lang['NAME']);
1097 }
1098 return self::$langs;
1099 }
1100 protected static function prepareLabels(array &$fields, $name, $defaultLabel)
1101 {
1102 $label = isset($fields[$name]) ? $fields[$name] : null;
1103 if(is_string($label) && $label !== '')
1104 {
1105 $labels = array();
1106 $default = $label;
1107 }
1108 else
1109 {
1110 $labels = is_array($label) ? $label : array();
1111 $default = $defaultLabel;
1112 }
1113
1114 $langIDs = array_keys(self::getAllLanguages());
1115 $fields[$name] = array();
1116 foreach($langIDs as $lid)
1117 {
1118 $fields[$name][$lid] = isset($labels[$lid]) && is_string($labels[$lid]) && $labels[$lid] !== ''
1119 ? $labels[$lid] : $default;
1120 }
1121 }
1122 protected function checkCreatePermission()
1123 {
1124 return $this->isAdminUser();
1125 }
1126 protected function checkReadPermission()
1127 {
1128 return $this->isAdminUser();
1129 }
1130 protected function checkUpdatePermission()
1131 {
1132 return $this->isAdminUser();
1133 }
1134 protected function checkDeletePermission()
1135 {
1136 return $this->isAdminUser();
1137 }
1138
1139 private static function includeLangFile()
1140 {
1141 if(!self::$langIncluded)
1142 {
1143 self::$langIncluded = IncludeModuleLangFile(__FILE__);
1144 }
1145 }
1146}
static isModuleInstalled($moduleName)
static getByClientId($clientId)
Definition app.php:929
static getHandlersList($placement, $skipInstallCheck=false, int $userId=null)
__construct($entityID, \CUser $user=null)
static getSettingsFields($typeID)
getList(array $order, array $filter)
static sanitizeFields(array &$fields)
static getTypes(\CRestServer $server=null)
update($ID, array $fields)
static prepareLabels(array &$fields, $name, $defaultLabel)