41 $this->arFieldsCache = [];
42 $this->arUserTypes =
false;
58 if (!is_array($this->arUserTypes))
60 $this->arUserTypes = [];
61 foreach (
GetModuleEvents(
"main",
"OnUserTypeBuildList",
true) as $arEvent)
64 $this->arUserTypes[
$res[
"USER_TYPE_ID"]] =
$res;
67 if ($user_type_id !==
false)
69 if (array_key_exists($user_type_id, $this->arUserTypes))
71 return $this->arUserTypes[$user_type_id];
80 return $this->arUserTypes;
86 if ($arType = $this->
GetUserType($arUserField[
"USER_TYPE_ID"]))
88 if (is_callable([$arType[
"CLASS_NAME"],
"getdbcolumntype"]))
90 return call_user_func_array([$arType[
"CLASS_NAME"],
"getdbcolumntype"], [$arUserField]);
98 if ($arUserField[
'MULTIPLE'] ==
'Y')
116 $user_type_id = $arUserField[
'USER_TYPE_ID'] ??
null;
119 $rsUserType = CUserTypeEntity::GetList([], [
"ID" =>
$ID]);
120 $arUserType = $rsUserType->Fetch();
123 $user_type_id = $arUserType[
"USER_TYPE_ID"];
124 $arUserField += $arUserType;
128 if (!$bCheckUserType)
130 if (!isset($arUserField[
"SETTINGS"]))
135 if (!is_array($arUserField[
"SETTINGS"]))
140 if (empty($arUserField[
"SETTINGS"]))
148 if ($userType && is_callable([$userType[
'CLASS_NAME'],
'preparesettings']))
150 return call_user_func_array([$userType[
'CLASS_NAME'],
'preparesettings'], [$arUserField]);
164 isset($userField[
'USER_TYPE'][
'CLASS_NAME'])
165 && is_callable([$userField[
'USER_TYPE'][
'CLASS_NAME'],
'getCustomData']);
170 $customData = call_user_func_array(
171 [$userField[
'USER_TYPE'][
'CLASS_NAME'],
'getCustomData'],
172 [$userField, $entityValueId]
176 return is_array($customData) ? $customData : [];
195 $entity_id = static::normalizeId($entity_id);
196 $value_id = intval($value_id);
200 if (!empty(
$result) && $value_id > 0)
210 foreach (
$result as $fieldName => $arUserField)
212 $result[$fieldName][
"ENTITY_VALUE_ID"] = $value_id;
214 if (is_array($valuesGottenByEvent))
216 $result[$fieldName][
"VALUE"] = array_key_exists($fieldName, $valuesGottenByEvent) ? $valuesGottenByEvent[$fieldName] :
$result[$fieldName][
"VALUE"];
221 if ($arUserField[
"MULTIPLE"] ==
"N"
222 && is_array($arUserField[
"USER_TYPE"])
223 && array_key_exists(
"CLASS_NAME", $arUserField[
"USER_TYPE"])
224 && is_callable([$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"FormatField"]))
226 $select[] = call_user_func_array([$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"FormatField"], [$arUserField, $fieldName]) .
" " . $fieldName;
235 if (is_array($valuesGottenByEvent))
242 $rs =
$DB->Query(
"SELECT " . implode(
', ',
$select) .
" FROM b_uts_" . strtolower($entity_id) .
" WHERE VALUE_ID = " . $value_id);
246 foreach (
$ar as
$key => $value)
253 if (!str_starts_with($value,
'a') && $value > 0)
259 $value = unserialize($value, [
'allowed_classes' =>
false]);
267 foreach (
$result as $fieldName => $userField)
289 if ($readyData ===
null)
294 $entity_id = static::normalizeId($entity_id);
298 foreach ($readyData as
$key => $value)
302 if (
$result[
$key][
"MULTIPLE"] ==
"Y" && !is_array($value))
304 $value = unserialize($value, [
'allowed_classes' =>
false]);
308 $result[
$key][
"ENTITY_VALUE_ID"] = $readyData[$primaryIdName] ??
null;
319 $entity_id = static::normalizeId($entity_id);
320 $field_id = static::normalizeId($field_id);
321 $value_id = intval($value_id);
322 $strTableName =
"b_uts_" . strtolower($entity_id);
326 "ENTITY_ID" => $entity_id,
327 "FIELD_NAME" => $field_id,
334 if ($arUserField =
$rs->Fetch())
337 if (is_array($values))
339 return $values[$arUserField[
'FIELD_NAME']];
341 $arUserField[
"USER_TYPE"] = $this->
GetUserType($arUserField[
"USER_TYPE_ID"]);
342 $arTableFields =
$DB->GetTableFields($strTableName);
343 if (array_key_exists($field_id, $arTableFields))
345 $simpleFormat =
true;
347 if ($arUserField[
"MULTIPLE"] ==
"N")
349 if ($arType = $arUserField[
"USER_TYPE"])
351 if (is_callable([$arType[
"CLASS_NAME"],
"FormatField"]))
353 $select = call_user_func_array([$arType[
"CLASS_NAME"],
"FormatField"], [$arUserField, $field_id]);
354 $simpleFormat =
false;
363 $rs =
$DB->Query(
"SELECT " .
$select .
" " .
$DB->quote(
'VALUE') .
" FROM " . $strTableName .
" WHERE VALUE_ID = " . $value_id);
366 if ($arUserField[
"MULTIPLE"] ==
"Y")
387 if ($this->entityList ===
null)
389 $event = new \Bitrix\Main\Event(
'main',
'onUserTypeEntityOrmMap');
392 foreach (
$event->getResults() as $eventResult)
394 if ($eventResult->getType() == \
Bitrix\
Main\EventResult::SUCCESS)
396 $result = $eventResult->getParameters();
399 if (!str_starts_with($entityClass,
'\\'))
401 $entityClass =
'\\' . $entityClass;
404 $this->entityList[
$entityId] = $entityClass;
410 return $this->entityList;
415 if (is_callable([$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"onafterfetch"]))
417 if ($arUserField[
"MULTIPLE"] ==
"Y")
423 foreach ($resultCopy as $value)
425 $convertedValue = call_user_func_array(
426 [$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"onafterfetch"],
434 if ($convertedValue !==
null)
443 $result = call_user_func_array(
444 [$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"onafterfetch"],
464 FROM b_utm_" . strtolower($arUserField[
"ENTITY_ID"]) .
"
465 WHERE VALUE_ID = " . intval($valueId) .
"
466 AND FIELD_ID = " . $arUserField[
"ID"] .
"
468 while (
$ar =
$rs->Fetch())
470 if ($arUserField[
"USER_TYPE"][
"USER_TYPE_ID"] ==
"date")
476 switch ($arUserField[
"USER_TYPE"][
"BASE_TYPE"])
499 $entity_id = static::normalizeId($entity_id);
502 "DIV" =>
"user_fields_tab_" . $entity_id,
505 "TITLE" =>
GetMessage(
"USER_TYPE_EDIT_TAB_TITLE"),
515 echo
"<tr colspan=\"2\"><td align=\"left\"><a href=\"/bitrix/admin/userfield_edit.php?lang=" . LANG .
"&ENTITY_ID=" . urlencode($entity_id) .
"&back_url=" . urlencode(
$APPLICATION->GetCurPageParam(
"", [
"bxpublic"]) .
"&tabControl_active_tab=user_fields_tab") .
"\">" .
GetMessage(
"USER_TYPE_EDIT_TAB_HREF") .
"</a></td></tr>";
519 if (!empty($arUserFields))
521 foreach ($arUserFields as $FIELD_NAME => $arUserField)
523 $arUserField[
"VALUE_ID"] = intval(
$ID);
545 foreach ($arUserFields as $arUserField)
547 $fieldName = $arUserField[
'FIELD_NAME'];
548 if ($arUserField[
"EDIT_IN_LIST"] ==
"Y")
550 if ($arUserField[
"USER_TYPE"][
"BASE_TYPE"] ==
"file")
552 if (isset(
$files[$fieldName]))
554 if (is_array(
$files[$fieldName][
"name"]))
557 foreach (
$files[$fieldName][
"name"] as
$key => $value)
559 $old_id = $form[$fieldName .
"_old_id"][
$key] ??
null;
563 "tmp_name" =>
$files[$fieldName][
"tmp_name"][
$key],
567 isset($form[$fieldName .
"_del"])
568 && is_array($form[$fieldName .
"_del"]) &&
569 (in_array($old_id, $form[$fieldName .
"_del"]) ||
571 array_key_exists(
$key, $form[$fieldName .
"_del"]) &&
572 $form[$fieldName .
"_del"][
$key] ==
"Y"
582 $arFields[$fieldName][
"del"] = $form[$fieldName .
"_del"] ??
'';
583 $arFields[$fieldName][
"old_id"] = $form[$fieldName .
"_old_id"] ??
'';
588 if (isset($form[$fieldName]))
590 if (!is_array($form[$fieldName]))
592 if (intval($form[$fieldName]) > 0)
594 $arFields[$fieldName] = intval($form[$fieldName]);
600 foreach ($form[$fieldName] as
$val)
602 if (intval(
$val) > 0)
614 if (isset(
$files[$fieldName]))
617 CFile::ConvertFilesToPost(
$files[$fieldName], $arFile);
619 if (isset($form[$fieldName]))
621 if ($arUserField[
"MULTIPLE"] ==
"Y")
623 foreach ($form[$fieldName] as
$key => $value)
630 $arFields[$fieldName] = array_merge($form[$fieldName], $arFile);
640 if (isset($form[$fieldName]))
642 $arFields[$fieldName] = $form[$fieldName];
658 foreach ($arUserFields as $fieldName => $arUserField)
660 if ($arUserField[
'SHOW_FILTER'] !=
'N' && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] !=
'file')
663 if ($arUserField[
'USER_TYPE'][
'BASE_TYPE'] ==
'datetime')
675 foreach ($arUserFields as $fieldName => $arUserField)
677 if ($arUserField[
'SHOW_FILTER'] !=
'N' && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] !=
'file')
679 if (is_callable([$arUserField[
'USER_TYPE'][
'CLASS_NAME'],
'GetFilterData']))
682 [$arUserField[
'USER_TYPE'][
'CLASS_NAME'],
'GetFilterData'],
687 'NAME' => $arUserField[
'LIST_FILTER_LABEL'] ?: $arUserField[
'FIELD_NAME'],
698 if (is_array($value))
700 foreach ($value as $v)
702 if ((
string)$v <>
'')
712 if ((
string)$value <>
'')
731 foreach ($arUserFields as $fieldName => $arUserField)
734 $arUserField[
'SHOW_FILTER'] !=
'N' &&
735 $arUserField[
'USER_TYPE'][
'BASE_TYPE'] ==
'datetime'
738 $value1 =
$GLOBALS[
'find_' . $fieldName .
'_from'] ??
null;
739 $value2 =
$GLOBALS[
'find_' . $fieldName .
'_to'] ??
null;
742 $date = new \Bitrix\Main\Type\Date($value1);
747 $date = new \Bitrix\Main\Type\Date($value2);
748 if ($arUserField[
'USER_TYPE_ID'] !=
'date')
750 $date->add(
'+1 day');
758 $value =
$GLOBALS[
'find_' . $fieldName] ??
null;
761 $arUserField[
'SHOW_FILTER'] !=
'N'
762 && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] !=
'file'
766 if ($arUserField[
'SHOW_FILTER'] ==
'I')
770 elseif ($arUserField[
'SHOW_FILTER'] ==
'S')
788 foreach ($arUserFields as $fieldName => $arUserField)
790 if ($arUserField[
'SHOW_FILTER'] !=
'N' && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] ==
'datetime')
792 $value1 = $filterData[$fieldName .
'_from'] ??
'';
793 $value2 = $filterData[$fieldName .
'_to'] ??
'';
796 $date = new \Bitrix\Main\Type\Date($value1);
801 $date = new \Bitrix\Main\Type\Date($value2);
802 if ($arUserField[
'USER_TYPE_ID'] !=
'date')
804 $date->add(
'+1 day');
810 elseif ($arUserField[
'SHOW_FILTER'] !=
'N' && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] ==
'int')
812 if ($arUserField[
'USER_TYPE_ID'] ==
'boolean')
814 if (isset($filterData[$fieldName]) && $filterData[$fieldName] ===
'Y')
816 $filterData[$fieldName] = 1;
818 if (isset($filterData[$fieldName]) && $filterData[$fieldName] ===
'N')
820 $filterData[$fieldName] = 0;
823 $value = $filterData[$fieldName] ??
null;
827 $value = $filterData[$fieldName] ??
null;
830 $arUserField[
'SHOW_FILTER'] !=
'N'
831 && $arUserField[
'USER_TYPE'][
'BASE_TYPE'] !=
'file'
835 if ($arUserField[
'SHOW_FILTER'] ==
'I')
840 elseif ($arUserField[
'SHOW_FILTER'] ==
'S')
856 foreach ($arUserFields as $FIELD_NAME => $arUserField)
858 if ($arUserField[
"EDIT_IN_LIST"] !=
"Y")
868 foreach ($arUserFields as $FIELD_NAME => $arUserField)
870 if ($arUserField[
"SHOW_IN_LIST"] ==
"Y")
874 "content" =>
htmlspecialcharsbx($arUserField[
"LIST_COLUMN_LABEL"] ?: $arUserField[
"FIELD_NAME"]),
875 "sort" => $arUserField[
"MULTIPLE"] ==
"N" ? $FIELD_NAME :
false,
884 foreach ($arUserFields as $FIELD_NAME => $arUserField)
886 if ($arUserField[
"SHOW_IN_LIST"] ==
"Y" && array_key_exists($FIELD_NAME,
$arRes))
896 foreach ($arUserFields as $FIELD_NAME => $arUserField)
898 if ($arUserField[
"SHOW_FILTER"] !=
"N" && $arUserField[
"USER_TYPE"][
"BASE_TYPE"] !=
"file")
900 if ($arUserField[
"USER_TYPE"] && is_callable([$arUserField[
"USER_TYPE"][
"CLASS_NAME"],
"getfilterhtml"]))
902 if ($arUserField[
"LIST_FILTER_LABEL"])
908 $arFindFields[$FIELD_NAME] = $arUserField[
"FIELD_NAME"];
918 foreach ($arUserFields as $FIELD_NAME => $arUserField)
920 if ($arUserField[
"SHOW_FILTER"] !=
"N" && $arUserField[
"USER_TYPE"][
"BASE_TYPE"] !=
"file")
931 $APPLICATION->AddHeadScript(
"/bitrix/js/main/usertype.js");
941 if ($arUserField[
"USER_TYPE"])
943 if ($this->
GetRights($arUserField[
"ENTITY_ID"]) >=
"W")
946 $userFieldUrl =
$selfFolderUrl .
"userfield_edit.php?lang=" . LANGUAGE_ID .
"&ID=" . $arUserField[
"ID"];
948 $edit_link = ($arUserField[
"HELP_MESSAGE"] ? htmlspecialcharsex($arUserField[
"HELP_MESSAGE"]) .
'<br>' :
'') .
'<a href="' .
htmlspecialcharsbx($userFieldUrl .
'&back_url=' . urlencode(
$APPLICATION->GetCurPageParam(
"", [
"bxpublic"]) .
'&tabControl_active_tab=user_fields_tab')) .
'">' . htmlspecialcharsex(
GetMessage(
"MAIN_EDIT")) .
'</a>';
955 $hintHTML =
'<span id="hint_' . $arUserField[
"FIELD_NAME"] .
'"></span><script>BX.hint_replace(BX(\'hint_' . $arUserField[
"FIELD_NAME"] .
'\'), \
'' . CUtil::JSEscape($edit_link) .
'\');</script>&
nbsp;
';
957 if ($arUserField["MANDATORY"] == "Y")
959 $strLabelHTML = $hintHTML . '<span
class=
"adm-required-field">
' . htmlspecialcharsbx($arUserField["EDIT_FORM_LABEL"] ?: $arUserField["FIELD_NAME"]) . '</span>
' . ':
';
963 $strLabelHTML = $hintHTML . htmlspecialcharsbx($arUserField["EDIT_FORM_LABEL"] ?: $arUserField["FIELD_NAME"]) . ':
';
966 if (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtml"]))
968 $js = $this->ShowScript();
972 $form_value = $arUserField["VALUE"];
974 elseif ($arUserField["USER_TYPE"]["BASE_TYPE"] == "file")
976 $form_value = $GLOBALS[$arUserField["FIELD_NAME"] . "_old_id"];
978 elseif ($arUserField["EDIT_IN_LIST"] == "N")
980 $form_value = $arUserField["VALUE"];
984 $arUserField["MULTIPLE"] === "N"
986 !empty($arUserField['USER_TYPE
']['USE_FIELD_COMPONENT
'])
991 $html = call_user_func_array(
992 [$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtml"],
996 "NAME" => $arUserField["FIELD_NAME"],
997 "VALUE" => (is_array($form_value) ? $form_value : htmlspecialcharsbx($form_value)),
998 "VALIGN" => &$valign,
999 "ROWCLASS" => &$rowClass,
1004 return '<tr
' . ($rowClass != '' ? ' class=
"' . $rowClass . '"' : '') . '><td
' . ($valign <> 'middle
' ? ' class=
"adm-detail-valign-top"' : '') . ' width=
"40%">
' . $strLabelHTML . '</td><td
width=
"60%">
' . $html . '</td></tr>
' . $js;
1006 elseif (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtmlmulty"]))
1008 if (!is_array($form_value))
1012 foreach ($form_value as $key => $value)
1014 if (!is_array($value))
1016 $form_value[$key] = htmlspecialcharsbx($value);
1021 $html = call_user_func_array(
1022 [$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtmlmulty"],
1026 "NAME" => $arUserField["FIELD_NAME"] . "[]",
1027 "VALUE" => $form_value,
1028 "ROWCLASS" => &$rowClass,
1033 return '<tr
' . ($rowClass != '' ? ' class=
"' . $rowClass . '"' : '') . '><td
class=
"adm-detail-valign-top">
' . $strLabelHTML . '</td><td>
' . $html . '</td></tr>
' . $js;
1037 if (!is_array($form_value))
1043 foreach ($form_value as $i => $value)
1046 (is_array($value) && (implode("", $value) <> ''))
1047 || ((!is_array($value)) && ((string)$value <> ''))
1050 $html .= '<tr><td>
' . call_user_func_array(
1051 [$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtml"],
1055 "NAME" => $arUserField["FIELD_NAME"] . "[" . $i . "]",
1056 "VALUE" => (is_array($value) ? $value : htmlspecialcharsbx($value)),
1063 //Add multiple values support
1065 $FIELD_NAME_X = str_replace('_
', 'x
', $arUserField["FIELD_NAME"]);
1066 $fieldHtml = call_user_func_array(
1067 [$arUserField["USER_TYPE"]["CLASS_NAME"], "geteditformhtml"],
1071 "NAME" => $arUserField["FIELD_NAME"] . "[" . ($i + 1) . "]",
1073 "ROWCLASS" => &$rowClass,
1078 return '<tr
' . ($rowClass != '' ? ' class=
"' . $rowClass . '"' : '') . '><td
class=
"adm-detail-valign-top">
' . $strLabelHTML . '</td><td>
' .
1079 '<table
id=
"table_' . $arUserField["FIELD_NAME
"] . '">
' . $html . '<tr><td>
' . $fieldHtml . '</td></tr>
' .
1080 '<tr><td
style=
"padding-top: 6px;"><input type=
"button" value=
"' . GetMessage("USER_TYPE_PROP_ADD
") . '" onClick=
"addNewRow(\'table_' . $arUserField["FIELD_NAME
"] . '\', \'' . $FIELD_NAME_X . '|' . $arUserField["FIELD_NAME
"] . '|' . $arUserField["FIELD_NAME
"] . '_old_id\')"></td></tr>
' .
1081 "<script>BX.addCustomEvent('onAutoSaveRestore
', function(ob, data) {
1084 if (i.substring(0," . (mb_strlen($arUserField['FIELD_NAME
']) + 1) . ")=='" . CUtil::JSEscape($arUserField['FIELD_NAME']) . "[
')
1086 addNewRow('table_
" . $arUserField["FIELD_NAME
"] . "', '" . $FIELD_NAME_X . '|' . $arUserField["FIELD_NAME
"] . '|' . $arUserField["FIELD_NAME
"] . "_old_id
');
1098 public function GetFilterHTML($arUserField, $filter_name, $filter_value)
1100 if ($arUserField["USER_TYPE"])
1102 if (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "getfilterhtml"]))
1104 $useFieldComponent = ($arUserField['USER_TYPE
']['USE_FIELD_COMPONENT
'] ?? false) === true;
1105 $html = call_user_func_array(
1106 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getfilterhtml"],
1110 'NAME
' => $filter_name,
1111 'VALUE
' => ($useFieldComponent ? $filter_value : htmlspecialcharsEx($filter_value)),
1114 ) . CAdminCalendar::ShowScript();
1116 return '<tr><td>
' . htmlspecialcharsbx($arUserField["LIST_FILTER_LABEL"] ?: $arUserField["FIELD_NAME"]) . ':</td><td>
' . $html . '</td></tr>
';
1128 public function AddUserField($arUserField, $value, $row)
1130 if ($arUserField["USER_TYPE"])
1132 $js = $this->ShowScript();
1133 $useFieldComponent = !empty($arUserField['USER_TYPE
']['USE_FIELD_COMPONENT
']);
1135 if (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"]))
1137 if ($arUserField["MULTIPLE"] == "N")
1139 $html = call_user_func_array(
1140 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"],
1144 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]",
1145 "VALUE" => ($useFieldComponent ? $value : htmlspecialcharsbx($value)),
1153 $row->AddViewField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1155 elseif (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtmlmulty"]))
1157 if (is_array($value))
1159 $form_value = $value;
1163 $form_value = unserialize($value, ['allowed_classes
' => false]);
1166 if (!is_array($form_value))
1171 foreach ($form_value as $key => $val)
1173 $form_value[$key] = ($useFieldComponent ? $val : htmlspecialcharsbx($val));
1176 $html = call_user_func_array(
1177 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtmlmulty"],
1181 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]" . "[]",
1182 "VALUE" => $form_value,
1190 $row->AddViewField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1196 if (is_array($value))
1198 $form_value = $value;
1202 $form_value = $value <> '' ? unserialize($value, ['allowed_classes
' => false]) : false;
1205 if (!is_array($form_value))
1210 foreach ($form_value as $i => $val)
1216 $html .= call_user_func_array(
1217 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"],
1221 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]" . "[" . $i . "]",
1222 "VALUE" => ($useFieldComponent ? $val : htmlspecialcharsbx($val)),
1231 $row->AddViewField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1234 if ($arUserField["EDIT_IN_LIST"] == "Y" && is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtml"]))
1236 if (!$row->bEditMode)
1239 $row->AddEditField($arUserField["FIELD_NAME"], " ");
1241 elseif ($arUserField["MULTIPLE"] == "N")
1243 $html = call_user_func_array(
1244 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtml"],
1248 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]",
1249 "VALUE" => ($useFieldComponent ? $value : htmlspecialcharsbx($value)),
1257 $row->AddEditField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1259 elseif (is_callable([$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtmlmulty"]))
1261 if (is_array($value))
1263 $form_value = $value;
1267 $form_value = $value <> '' ? unserialize($value, ['allowed_classes
' => false]) : false;
1270 if (!is_array($form_value))
1275 foreach ($form_value as $key => $val)
1277 $form_value[$key] = ($useFieldComponent ? $val : htmlspecialcharsbx($val));
1280 $html = call_user_func_array(
1281 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtmlmulty"],
1285 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "][]",
1286 "VALUE" => $form_value,
1294 $row->AddEditField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1298 $html = "<table id=\"table_" . $arUserField["FIELD_NAME"] . "_" . $row->id . "\">";
1299 if (is_array($value))
1301 $form_value = $value;
1305 $form_value = unserialize($value, ['allowed_classes
' => false]);
1308 if (!is_array($form_value))
1314 foreach ($form_value as $i => $val)
1316 $html .= '<tr><td>
' . call_user_func_array(
1317 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtml"],
1321 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]" . "[" . $i . "]",
1322 "VALUE" => ($useFieldComponent ? $val : htmlspecialcharsbx($val)),
1327 $html .= '<tr><td>
' . call_user_func_array(
1328 [$arUserField["USER_TYPE"]["CLASS_NAME"], "getadminlistedithtml"],
1332 "NAME" => "FIELDS[" . $row->id . "][" . $arUserField["FIELD_NAME"] . "]" . "[" . ($i + 1) . "]",
1337 $html .= '<tr><td><input type=
"button" value=
"' . GetMessage("USER_TYPE_PROP_ADD
") . '" onClick=
"addNewRow(\'table_' . $arUserField["FIELD_NAME
"] . '_' . $row->id . '\', \'FIELDS\\\\[' . $row->id . '\\\\]\\\\[' . $arUserField["FIELD_NAME
"] . '\\\\]\')"></td></tr>
' .
1339 $row->AddEditField($arUserField["FIELD_NAME"], $html . $js . CAdminCalendar::ShowScript());
1345 public function getListView($userfield, $value)
1349 if (is_callable([$userfield["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"]))
1351 if ($userfield["MULTIPLE"] == "N")
1353 $html = call_user_func_array(
1354 [$userfield["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"],
1358 "VALUE" => htmlspecialcharsbx($value),
1363 elseif (is_callable([$userfield["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtmlmulty"]))
1365 $form_value = is_array($value) ? $value : unserialize($value, ['allowed_classes
' => false]);
1367 if (!is_array($form_value))
1372 foreach ($form_value as $key => $val)
1374 $form_value[$key] = htmlspecialcharsbx($val);
1377 $html = call_user_func_array(
1378 [$userfield["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtmlmulty"],
1382 "VALUE" => $form_value,
1389 if (is_array($value))
1391 $form_value = $value;
1395 $form_value = $value <> '' ? unserialize($value, ['allowed_classes
' => false]) : false;
1398 if (!is_array($form_value))
1403 foreach ($form_value as $val)
1410 $html .= call_user_func_array(
1411 [$userfield["USER_TYPE"]["CLASS_NAME"], "getadminlistviewhtml"],
1415 "VALUE" => htmlspecialcharsbx($val),
1423 return $html <> '' ? $html : '&
nbsp;
';
1426 public function CallUserTypeComponent($componentName, $componentTemplate, $arUserField, $arAdditionalParameters = [])
1428 global $APPLICATION;
1429 $arParams = $arAdditionalParameters;
1430 $arParams['arUserField
'] = $arUserField;
1432 $APPLICATION->IncludeComponent(
1437 ["HIDE_ICONS" => "Y"]
1439 return ob_get_clean();
1447 public function renderField(array $userField, ?array $additionalParameters = []): ?string
1449 $userType = $this->getUserType($userField['USER_TYPE_ID
']);
1450 if (!empty($userType['CLASS_NAME
']) && is_callable([$userType['CLASS_NAME
'], 'renderField']))
1452 return call_user_func([$userType['CLASS_NAME
'], 'renderField'], $userField, $additionalParameters);
1457 public function GetPublicView($arUserField, $arAdditionalParameters = [])
1459 $event = new \Bitrix\Main\Event("main", "onBeforeGetPublicView", [&$arUserField, &$arAdditionalParameters]);
1462 $arType = $this->GetUserType($arUserField["USER_TYPE_ID"]);
1465 $event = new \Bitrix\Main\Event("main", "onGetPublicView", [$arUserField, $arAdditionalParameters]);
1467 foreach ($event->getResults() as $evenResult)
1469 if ($evenResult->getType() == \Bitrix\Main\EventResult::SUCCESS)
1471 $html = $evenResult->getParameters();
1480 elseif (isset($arUserField["VIEW_CALLBACK"]) && is_callable($arUserField['VIEW_CALLBACK
']))
1482 $html = call_user_func_array($arUserField["VIEW_CALLBACK"], [
1484 $arAdditionalParameters,
1487 elseif ($arType && isset($arType["VIEW_CALLBACK"]) && is_callable($arType['VIEW_CALLBACK
']))
1489 $html = call_user_func_array($arType["VIEW_CALLBACK"], [
1491 $arAdditionalParameters,
1494 elseif (isset($arUserField["VIEW_COMPONENT_NAME"]))
1496 $html = $this->CallUserTypeComponent(
1497 $arUserField["VIEW_COMPONENT_NAME"],
1498 $arUserField["VIEW_COMPONENT_TEMPLATE"],
1500 $arAdditionalParameters
1503 elseif ($arType && isset($arType["VIEW_COMPONENT_NAME"]))
1505 $html = $this->CallUserTypeComponent(
1506 $arType["VIEW_COMPONENT_NAME"],
1507 $arType["VIEW_COMPONENT_TEMPLATE"],
1509 $arAdditionalParameters
1514 $html = $this->CallUserTypeComponent(
1515 "bitrix:system.field.view",
1516 $arUserField["USER_TYPE_ID"],
1518 $arAdditionalParameters
1522 $event = new \Bitrix\Main\Event("main", "onAfterGetPublicView", [$arUserField, $arAdditionalParameters, &$html]);
1528 public function getPublicText($userField)
1530 $userType = $this->getUserType($userField['USER_TYPE_ID
']);
1531 if (!empty($userType['CLASS_NAME
']) && is_callable([$userType['CLASS_NAME
'], 'getPublicText']))
1533 return call_user_func_array([$userType['CLASS_NAME
'], 'getPublicText'], [$userField]);
1536 return join(',
', array_map(function ($v) {
1537 return is_null($v) || is_scalar($v) ? (string)$v : '';
1538 }, (array)$userField['VALUE
']));
1541 public function GetPublicEdit($arUserField, $arAdditionalParameters = [])
1543 $event = new \Bitrix\Main\Event("main", "onBeforeGetPublicEdit", [&$arUserField, &$arAdditionalParameters]);
1546 $arType = $this->GetUserType($arUserField["USER_TYPE_ID"]);
1549 $event = new \Bitrix\Main\Event("main", "onGetPublicEdit", [$arUserField, $arAdditionalParameters]);
1551 foreach ($event->getResults() as $evenResult)
1553 if ($evenResult->getType() == \Bitrix\Main\EventResult::SUCCESS)
1555 $html = $evenResult->getParameters();
1564 elseif (isset($arUserField["EDIT_CALLBACK"]) && is_callable($arUserField['EDIT_CALLBACK
']))
1566 $html = call_user_func_array($arUserField["EDIT_CALLBACK"], [
1568 $arAdditionalParameters,
1571 elseif ($arType && isset($arType["EDIT_CALLBACK"]) && is_callable($arType['EDIT_CALLBACK
']))
1573 $html = call_user_func_array($arType["EDIT_CALLBACK"], [
1575 $arAdditionalParameters,
1578 elseif (isset($arUserField["EDIT_COMPONENT_NAME"]))
1580 $html = $this->CallUserTypeComponent(
1581 $arUserField["EDIT_COMPONENT_NAME"],
1582 $arUserField["EDIT_COMPONENT_TEMPLATE"],
1584 $arAdditionalParameters
1587 elseif ($arType && isset($arType["EDIT_COMPONENT_NAME"]))
1589 $html = $this->CallUserTypeComponent(
1590 $arType["EDIT_COMPONENT_NAME"],
1591 $arType["EDIT_COMPONENT_TEMPLATE"],
1593 $arAdditionalParameters
1598 $html = $this->CallUserTypeComponent(
1599 "bitrix:system.field.edit",
1600 $arUserField["USER_TYPE_ID"],
1602 $arAdditionalParameters
1606 $event = new \Bitrix\Main\Event("main", "onAfterGetPublicEdit", [$arUserField, $arAdditionalParameters, &$html]);
1612 public function GetSettingsHTML($arUserField, $bVarsFromForm = false)
1614 if (!is_array($arUserField)) // New field
1616 if ($arType = $this->GetUserType($arUserField))
1618 if (is_callable([$arType["CLASS_NAME"], "getsettingshtml"]))
1620 return call_user_func_array([$arType["CLASS_NAME"], "getsettingshtml"], [false, ["NAME" => "SETTINGS"], $bVarsFromForm]);
1626 if (!is_array($arUserField["SETTINGS"]) || empty($arUserField["SETTINGS"]))
1628 $arUserField["SETTINGS"] = $this->PrepareSettings(0, $arUserField);
1631 if ($arType = $this->GetUserType($arUserField["USER_TYPE_ID"]))
1633 if (is_callable([$arType["CLASS_NAME"], "getsettingshtml"]))
1635 return call_user_func_array([$arType["CLASS_NAME"], "getsettingshtml"], [$arUserField, ["NAME" => "SETTINGS"], $bVarsFromForm]);
1652 public function CheckFields($entity_id, $ID, $arFields, $user_id = false, $checkRequired = true, array $requiredFields = null, array $filteredFields = null)
1654 global $APPLICATION;
1656 $requiredFieldMap = ($requiredFields !== null ? array_fill_keys($requiredFields, true) : null);
1659 //1 Get user typed fields list for entity
1660 $selectFields = null;
1661 if ($ID === null || $ID > 0 || !$checkRequired)
1663 // need to select all fields only for a new record and check required
1664 $selectFields = array_keys($arFields);
1665 if ($requiredFields !== null)
1667 $selectFields = $selectFields + $requiredFields;
1669 if ($filteredFields !== null)
1671 $selectFields = array_diff($selectFields, $filteredFields);
1674 $arUserFields = $this->GetUserFields($entity_id, $ID, LANGUAGE_ID, false, $selectFields);
1676 //2 Filter user typed fields
1677 if ($filteredFields !== null && $selectFields === null)
1679 $arUserFields = array_filter(
1681 static function ($fieldName) use ($filteredFields) {
1682 return in_array($fieldName, $filteredFields);
1684 ARRAY_FILTER_USE_KEY
1689 foreach ($arUserFields as $FIELD_NAME => $arUserField)
1691 $enableRequiredFieldCheck = $arUserField["MANDATORY"] === "Y"
1692 ? $checkRequired : ($requiredFieldMap && isset($requiredFieldMap[$FIELD_NAME]));
1694 //common Check for all fields
1695 $isSingleValue = ($arUserField["MULTIPLE"] === "N");
1698 $enableRequiredFieldCheck
1700 ($ID !== null && $ID <= 0)
1701 || array_key_exists($FIELD_NAME, $arFields)
1705 $EDIT_FORM_LABEL = $arUserField["EDIT_FORM_LABEL"] <> '
' ? $arUserField["EDIT_FORM_LABEL"] : $arUserField["FIELD_NAME"];
1707 if ($arUserField["USER_TYPE"]["BASE_TYPE"] === "file")
1709 $isNewFilePresent = false;
1711 if (is_array($arUserField["VALUE"]))
1713 $files = array_flip($arUserField["VALUE"]);
1715 elseif ($arUserField["VALUE"] > 0)
1717 $files = [$arUserField["VALUE"] => 0];
1719 elseif (is_numeric($arFields[$FIELD_NAME]))
1721 if (!$this->isFileValueDeleted($arUserField, (int)$arFields[$FIELD_NAME]))
1723 $files = [$arFields[$FIELD_NAME] => 0];
1729 $value = $arFields[$FIELD_NAME];
1730 if (is_array($value) && array_key_exists("tmp_name", $value))
1732 if (array_key_exists("del", $value) && $value["del"])
1734 unset($files[$value["old_id"]]);
1736 elseif (array_key_exists("size", $value) && $value["size"] > 0)
1738 $isNewFilePresent = true;
1743 if (!$this->isFileValueDeleted($arUserField, (int)$value))
1745 $isNewFilePresent = true;
1746 $files[$value] = $value;
1752 if (is_array($arFields[$FIELD_NAME]))
1754 foreach ($arFields[$FIELD_NAME] as $value)
1756 if (is_array($value) && array_key_exists("tmp_name", $value))
1758 if (array_key_exists("del", $value) && $value["del"])
1760 unset($files[$value["old_id"]]);
1762 elseif (array_key_exists("size", $value) && $value["size"] > 0)
1764 $isNewFilePresent = true;
1769 if (!$this->isFileValueDeleted($arUserField, (int)$value))
1771 $isNewFilePresent = true;
1772 $files[$value] = $value;
1779 if (!$isNewFilePresent && empty($files))
1781 $aMsg[] = ["id" => $FIELD_NAME, "text" => str_replace("#FIELD_NAME#", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING"))];
1784 elseif ($isSingleValue)
1786 if ($this->isValueEmpty($arUserField, $arFields[$FIELD_NAME]))
1788 $aMsg[] = ["id" => $FIELD_NAME, "text" => str_replace("#FIELD_NAME#", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING"))];
1793 if (!is_array($arFields[$FIELD_NAME]))
1795 $aMsg[] = ["id" => $FIELD_NAME, "text" => str_replace("#FIELD_NAME#", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING"))];
1800 foreach ($arFields[$FIELD_NAME] as $value)
1805 && (implode("", $value) <> '')
1810 && !$this->isValueEmpty($arUserField, $value)
1820 $aMsg[] = ["id" => $FIELD_NAME, "text" => str_replace("#FIELD_NAME#", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING"))];
1825 //identify user type
1826 if ($arUserField["USER_TYPE"])
1828 $CLASS_NAME = $arUserField["USER_TYPE"]["CLASS_NAME"];
1829 if (array_key_exists($FIELD_NAME, $arFields) && is_callable([$CLASS_NAME, "checkfields"]))
1833 if (!($arFields[$FIELD_NAME] instanceof SqlExpression))
1835 $canUseArrayValueForSingleField = false;
1837 is_callable([$CLASS_NAME, 'canUseArrayValueForSingleField
'])
1838 && $CLASS_NAME::canUseArrayValueForSingleField()
1841 $canUseArrayValueForSingleField = true;
1844 if (is_array($arFields[$FIELD_NAME]) && !$canUseArrayValueForSingleField)
1846 $fieldName = HtmlFilter::encode(
1847 empty($arUserField['EDIT_FORM_LABEL
'])
1848 ? $arUserField['FIELD_NAME
']
1849 : $arUserField['EDIT_FORM_LABEL
']
1853 'id' => $arUserField['FIELD_NAME
'],
1854 'text
' => Loc::getMessage('USER_TYPE_FIELD_VALUE_IS_MULTIPLE
', [
1855 '#FIELD_NAME#
' => $fieldName,
1862 //apply appropriate check function
1863 $messages = call_user_func_array(
1870 $arFields[$FIELD_NAME],
1875 $aMsg = array_merge($aMsg, $messages);
1878 elseif (is_array($arFields[$FIELD_NAME]))
1880 foreach ($arFields[$FIELD_NAME] as $value)
1884 if ($value instanceof SqlExpression)
1887 'id' => $FIELD_NAME,
1888 'text
' => "Multiple field \"#FIELD_NAME#\" can't handle
SqlExpression because of serialized uts cache
",
1893 //apply appropriate check function
1894 $ar = call_user_func_array(
1895 [$CLASS_NAME, "checkfields
"],
1896 [$arUserField, $value, $user_id]
1898 $aMsg = array_merge($aMsg, $ar);
1907 //3 Return succsess/fail flag
1910 $e = new CAdminException($aMsg);
1911 $APPLICATION->ThrowException($e);
1926 public function CheckFieldsWithOldData($entity_id, $oldData, $arFields)
1928 global $APPLICATION;
1932 //1 Get user typed fields list for entity
1933 $arUserFields = $this->getUserFieldsWithReadyData($entity_id, $oldData, LANGUAGE_ID);
1936 foreach ($arUserFields as $FIELD_NAME => $arUserField)
1938 //identify user type
1939 if ($arUserField["USER_TYPE
"])
1941 $CLASS_NAME = $arUserField["USER_TYPE
"]["CLASS_NAME
"];
1942 $EDIT_FORM_LABEL = $arUserField["EDIT_FORM_LABEL
"] <> '' ? $arUserField["EDIT_FORM_LABEL
"] : $arUserField["FIELD_NAME
"];
1944 if (array_key_exists($FIELD_NAME, $arFields) && is_callable([$CLASS_NAME, "checkfields
"]))
1946 // check required values
1947 if ($arUserField["MANDATORY
"] === "Y
")
1949 if ($arUserField["USER_TYPE
"]["BASE_TYPE
"] === "file
")
1951 $isNewFilePresent = false;
1953 if (is_array($arUserField["VALUE
"]))
1955 $files = array_flip($arUserField["VALUE
"]);
1957 elseif ($arUserField["VALUE
"] > 0)
1959 $files = [$arUserField["VALUE
"] => 0];
1961 elseif (is_numeric($arFields[$FIELD_NAME]))
1963 $files = [$arFields[$FIELD_NAME] => 0];
1966 if ($arUserField["MULTIPLE
"] === "N
")
1968 $value = $arFields[$FIELD_NAME];
1969 if (is_array($value) && array_key_exists("tmp_name
", $value))
1971 if (array_key_exists("del
", $value) && $value["del
"])
1973 unset($files[$value["old_id
"]]);
1975 elseif (array_key_exists("size", $value) && $value["size"] > 0)
1977 $isNewFilePresent = true;
1982 $isNewFilePresent = true;
1983 $files[$value] = $value;
1988 if (is_array($arFields[$FIELD_NAME]))
1990 foreach ($arFields[$FIELD_NAME] as $value)
1992 if (is_array($value) && array_key_exists("tmp_name
", $value))
1994 if (array_key_exists("del
", $value) && $value["del
"])
1996 unset($files[$value["old_id
"]]);
1998 elseif (array_key_exists("size", $value) && $value["size"] > 0)
2000 $isNewFilePresent = true;
2005 $isNewFilePresent = true;
2006 $files[$value] = $value;
2012 if (!$isNewFilePresent && empty($files))
2014 $aMsg[] = ["id" => $FIELD_NAME, "text
" => str_replace("#FIELD_NAME#
", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING
"))];
2017 elseif ($arUserField["MULTIPLE
"] == "N
")
2019 if ($this->isValueEmpty($arUserField, $arFields[$FIELD_NAME]))
2021 $aMsg[] = ["id" => $FIELD_NAME, "text
" => str_replace("#FIELD_NAME#
", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING
"))];
2026 if (!is_array($arFields[$FIELD_NAME]))
2028 $aMsg[] = ["id" => $FIELD_NAME, "text
" => str_replace("#FIELD_NAME#
", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING
"))];
2033 foreach ($arFields[$FIELD_NAME] as $value)
2036 (is_array($value) && (implode("", $value) <> ''))
2037 || ((!is_array($value)) && ((string)$value <> ''))
2046 $aMsg[] = ["id" => $FIELD_NAME, "text
" => str_replace("#FIELD_NAME#
", $EDIT_FORM_LABEL, GetMessage("USER_TYPE_FIELD_VALUE_IS_MISSING
"))];
2052 // check regular values
2053 if ($arUserField["MULTIPLE
"] == "N
")
2055 //apply appropriate check function
2056 $ar = call_user_func_array(
2057 [$CLASS_NAME, "checkfields
"],
2058 [$arUserField, $arFields[$FIELD_NAME]]
2060 $aMsg = array_merge($aMsg, $ar);
2062 elseif (is_array($arFields[$FIELD_NAME]))
2064 foreach ($arFields[$FIELD_NAME] as $value)
2068 //apply appropriate check function
2069 $ar = call_user_func_array(
2070 [$CLASS_NAME, "checkfields
"],
2071 [$arUserField, $value]
2073 $aMsg = array_merge($aMsg, $ar);
2081 //3 Return succsess/fail flag
2084 $e = new CAdminException($aMsg);
2085 $APPLICATION->ThrowException($e);
2092 protected function isValueEmpty(array $userField, $value): bool
2094 $className = $userField['USER_TYPE']['CLASS_NAME'] ?? null;
2095 if (!is_a($className, BaseType::class, true))
2097 $className = BaseType::class;
2099 if (!$className::isMandatorySupported())
2104 $userField['USER_TYPE_ID'] === \Bitrix\Main\UserField\Types\IntegerType::USER_TYPE_ID
2105 || $userField['USER_TYPE_ID'] === \Bitrix\Main\UserField\Types\DoubleType::USER_TYPE_ID
2110 $value === 0 || $value === 0.0 || $value === "0
" || $value === "0.0
" || $value === "0,0
"
2117 return (string)$value === "";
2120 public function Update($entity_id, $ID, $arFields, $user_id = false)
2122 $entity_id = static::normalizeId($entity_id);
2125 $result = $this->updateUserFieldValuesByEvent($entity_id, $ID, $arFields);
2126 if ($result !== null)
2136 $arUserFields = $this->GetUserFields($entity_id, $ID, false, $user_id, array_keys($arFields));
2138 foreach ($arUserFields as $FIELD_NAME => $arUserField)
2140 if (array_key_exists($FIELD_NAME, $arFields))
2142 $arUserField['VALUE_ID'] = $ID;
2144 if ($arUserField["MULTIPLE
"] == "N
")
2146 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesave
"]))
2148 $arFields[$FIELD_NAME] = call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesave
"], [$arUserField, $arFields[$FIELD_NAME], $user_id]);
2151 $modified = (!array_key_exists('VALUE_RAW', $arUserField) || $arFields[$FIELD_NAME] !== $arUserField['VALUE_RAW']);
2154 if ((string)$arFields[$FIELD_NAME] !== '')
2156 $arUpdate[$FIELD_NAME] = $arFields[$FIELD_NAME];
2158 elseif (!empty($arUserField['VALUE_EXISTS']))
2160 $arUpdate[$FIELD_NAME] = null;
2164 elseif (is_array($arFields[$FIELD_NAME]))
2166 $arInsert[$arUserField["ID
"]] = [];
2167 $arInsertType[$arUserField["ID
"]] = $arUserField["USER_TYPE
"];
2168 $arInsertType[$arUserField['ID']]['FIELD_NAME'] = $arUserField['FIELD_NAME'];
2170 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesaveall
"]))
2172 $arInsert[$arUserField["ID
"]] = call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesaveall
"], [$arUserField, $arFields[$FIELD_NAME], $user_id]);
2176 foreach ($arFields[$FIELD_NAME] as $value)
2178 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesave
"]))
2180 $value = call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onbeforesave
"], [$arUserField, $value, $user_id]);
2183 if ((string)$value <> '')
2185 switch ($arInsertType[$arUserField["ID
"]]["BASE_TYPE
"])
2190 $value = intval($value);
2193 $value = doubleval($value);
2194 if (!is_finite($value))
2200 $value = (string)$value;
2203 $arInsert[$arUserField["ID
"]][] = $value;
2208 if ($arUserField['USER_TYPE_ID'] == 'datetime')
2210 $serialized = \Bitrix\Main\UserFieldTable::serializeMultipleDatetime($arInsert[$arUserField["ID
"]]);
2212 elseif ($arUserField['USER_TYPE_ID'] == 'date')
2214 $serialized = \Bitrix\Main\UserFieldTable::serializeMultipleDate($arInsert[$arUserField["ID
"]]);
2218 $serialized = serialize($arInsert[$arUserField["ID
"]]);
2221 $modified = (!array_key_exists('VALUE_RAW', $arUserField) || $serialized !== $arUserField['VALUE_RAW']);
2224 $arUpdate[$FIELD_NAME] = $serialized;
2226 if (!empty($arUserField['VALUE_EXISTS']))
2228 $arDelete[$arUserField["ID
"]] = true;
2233 $arInsert[$arUserField["ID
"]] = [];
2239 $lower_entity_id = strtolower($entity_id);
2241 $connection = Application::getConnection();
2242 $helper = $connection->getSqlHelper();
2244 if (!empty($arUpdate))
2246 $insertFields = $arUpdate;
2247 $insertFields['VALUE_ID'] = $ID;
2248 $strUpdate = $helper->prepareMerge("b_uts_
" . $lower_entity_id, ['VALUE_ID'], $insertFields, $arUpdate)[0];
2252 // nothing to insert/update
2256 $connection->startTransaction();
2258 $connection->query($strUpdate);
2260 foreach ($arDelete as $key => $value)
2262 $connection->query("DELETE from b_utm_
" . $lower_entity_id . " WHERE FIELD_ID =
" . intval($key) . " AND VALUE_ID =
" . $ID);
2265 foreach ($arInsert as $FieldId => $arField)
2267 switch ($arInsertType[$FieldId]["BASE_TYPE
"])
2272 $COLUMN = "VALUE_INT
";
2275 $COLUMN = "VALUE_DOUBLE
";
2278 $COLUMN = "VALUE_DATE
";
2283 foreach ($arField as $value)
2285 if ($value instanceof \Bitrix\Main\Type\Date)
2287 // little hack to avoid timezone vs 00:00:00 ambiguity. for utm only
2288 $value = new \Bitrix\Main\Type\DateTime($value->format('Y-m-d H:i:s'), 'Y-m-d H:i:s');
2291 switch ($arInsertType[$FieldId]["BASE_TYPE
"])
2299 $userFieldName = $arInsertType[$FieldId]['FIELD_NAME'];
2300 $value = DateTimeType::charToDate($arUserFields[$userFieldName], $value);
2303 $value = "'" . $helper->forSql($value) . "'";
2305 $connection->query("INSERT INTO b_utm_
" . $lower_entity_id . " (VALUE_ID, FIELD_ID,
" . $COLUMN . ")
2306 VALUES (
" . intval($ID) . ",
'" . $FieldId . "',
" . $value . ")
");
2310 $connection->commitTransaction();
2315 public function copy($entity_id, $id, $copiedId, $entityObject, $userId = false, $ignoreList = [])
2317 $userFields = $this->getUserFields($entity_id, $id);
2320 foreach ($userFields as $fieldName => $userField)
2322 if (!in_array($fieldName, $ignoreList))
2324 if (is_callable([$userField["USER_TYPE
"]["CLASS_NAME
"], "onBeforeCopy
"]))
2326 $fields[$fieldName] = call_user_func_array(
2327 [$userField["USER_TYPE
"]["CLASS_NAME
"], "onBeforeCopy
"],
2328 [$userField, $copiedId, $userField["VALUE
"], $entityObject, $userId]
2333 $fields[$fieldName] = $userField["VALUE
"];
2338 $this->update($entity_id, $copiedId, $fields, $userId);
2340 foreach ($userFields as $fieldName => $userField)
2342 if (!in_array($fieldName, $ignoreList))
2344 if (is_callable([$userField["USER_TYPE
"]["CLASS_NAME
"], "onAfterCopy
"]))
2346 $fields[$fieldName] = call_user_func_array(
2347 [$userField["USER_TYPE
"]["CLASS_NAME
"], "onAfterCopy
"],
2348 [$userField, $copiedId, $fields[$fieldName], $entityObject, $userId]
2355 public function Delete($entity_id, $ID)
2361 $result = $this->deleteUserFieldValuesByEvent($entity_id, $ID);
2362 if ($result !== null)
2367 if ($arUserFields = $this->GetUserFields($entity_id, $ID, false, 0))
2369 foreach ($arUserFields as $arUserField)
2371 if (is_array($arUserField["VALUE
"]))
2373 foreach ($arUserField["VALUE
"] as $value)
2375 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "ondelete
"]))
2377 call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "ondelete
"], [$arUserField, $value]);
2380 if ($arUserField["USER_TYPE
"]["BASE_TYPE
"] == "file
")
2382 CFile::Delete($value);
2388 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "ondelete
"]))
2390 call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "ondelete
"], [$arUserField, $arUserField["VALUE
"]]);
2393 if ($arUserField["USER_TYPE
"]["BASE_TYPE
"] == "file
")
2395 CFile::Delete($arUserField["VALUE
"]);
2399 $DB->Query("DELETE FROM b_utm_
" . strtolower($entity_id) . " WHERE VALUE_ID =
" . $ID);
2400 $DB->Query("DELETE FROM b_uts_
" . strtolower($entity_id) . " WHERE VALUE_ID =
" . $ID);
2404 public function OnSearchIndex($entity_id, $ID)
2407 if ($arUserFields = $this->GetUserFields($entity_id, $ID, false, 0))
2409 foreach ($arUserFields as $arUserField)
2411 if ($arUserField["IS_SEARCHABLE
"] == "Y
")
2413 if ($arUserField["USER_TYPE
"])
2415 if (is_callable([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onsearchindex
"]))
2417 $result .= "\r\n
" . call_user_func_array([$arUserField["USER_TYPE
"]["CLASS_NAME
"], "onsearchindex
"], [$arUserField]);
2426 public function GetRights($ENTITY_ID = false, $ID = false)
2428 if (($ID !== false) && array_key_exists("ID:
" . $ID, $this->arRightsCache))
2430 return $this->arRightsCache["ID:
" . $ID];
2432 if (($ENTITY_ID !== false) && array_key_exists("ENTITY_ID:
" . $ENTITY_ID, $this->arRightsCache))
2434 return $this->arRightsCache["ENTITY_ID:
" . $ENTITY_ID];
2438 if (is_object($USER) && $USER->CanDoOperation('edit_other_settings'))
2447 $ar = CUserTypeEntity::GetByID($ID);
2450 $ENTITY_ID = $ar["ENTITY_ID
"];
2454 foreach (GetModuleEvents("main
", "OnUserTypeRightsCheck
", true) as $arEvent)
2456 $res = ExecuteModuleEventEx($arEvent, [$ENTITY_ID]);
2466 $this->arRightsCache["ID:
" . $ID] = $RIGHTS;
2468 if ($ENTITY_ID !== false)
2470 $this->arRightsCache["ENTITY_ID:
" . $ENTITY_ID] = $RIGHTS;
2484 public function getEntityField($arUserField, $fieldName = null, $fieldParameters = [])
2486 if (empty($fieldName))
2488 $fieldName = $arUserField['FIELD_NAME'];
2491 if (is_callable([$arUserField['USER_TYPE']['CLASS_NAME'], 'getEntityField']))
2493 $field = call_user_func([$arUserField['USER_TYPE']['CLASS_NAME'], 'getEntityField'], $fieldName, $fieldParameters);
2495 elseif ($arUserField['USER_TYPE']['USER_TYPE_ID'] == 'date')
2497 $field = new Fields\DateField($fieldName, $fieldParameters);
2501 switch ($arUserField['USER_TYPE']['BASE_TYPE'])
2506 $field = (new Fields\IntegerField($fieldName, $fieldParameters))
2507 ->configureNullable()
2511 $field = (new Fields\FloatField($fieldName, $fieldParameters))
2512 ->configureNullable()
2516 $field = (new Fields\StringField($fieldName, $fieldParameters))
2517 ->configureNullable()
2521 $field = (new Fields\DatetimeField($fieldName, $fieldParameters))
2522 ->configureNullable()
2523 ->configureUseTimezone(isset($arUserField['SETTINGS']['USE_TIMEZONE']) && $arUserField['SETTINGS']['USE_TIMEZONE'] == 'Y')
2527 throw new \Bitrix\Main\ArgumentException(sprintf(
2528 'Unknown userfield base type `%s`', $arUserField["USER_TYPE
"]['BASE_TYPE']
2533 $ufHandlerClass = $arUserField['USER_TYPE']['CLASS_NAME'];
2535 if (is_subclass_of($ufHandlerClass, BaseType::class))
2537 $defaultValue = $ufHandlerClass::getDefaultValue($arUserField);
2538 $field->configureDefaultValue($defaultValue);
2550 public function getEntityReferences($arUserField, Fields\ScalarField $entityField)
2552 if (is_callable([$arUserField['USER_TYPE']['CLASS_NAME'], 'getEntityReferences']))
2554 return call_user_func([$arUserField['USER_TYPE']['CLASS_NAME'], 'getEntityReferences'], $arUserField, $entityField);
2560 protected function getUserFieldValuesByEvent(array $userFields, string $entityId, int $value): ?array
2567 $isGotByEvent = false;
2568 $event = new \Bitrix\Main\Event('main', 'onGetUserFieldValues', ['userFields' => $userFields, 'entityId' => $entityId, 'value' => $value]);
2570 foreach ($event->getResults() as $eventResult)
2572 if ($eventResult->getType() === \Bitrix\Main\EventResult::SUCCESS)
2574 $parameters = $eventResult->getParameters();
2575 if (isset($parameters['values']) && is_array($parameters['values']))
2577 $isGotByEvent = true;
2578 foreach ($userFields as $fieldName => $userField)
2580 if (isset($parameters['values'][$fieldName]))
2582 $result[$fieldName] = $parameters['values'][$fieldName];
2596 protected function updateUserFieldValuesByEvent(string $entityId, int $id, array $fields): ?bool
2600 $event = new \Bitrix\Main\Event('main', 'onUpdateUserFieldValues', ['entityId' => $entityId, 'id' => $id, 'fields' => $fields]);
2602 foreach ($event->getResults() as $eventResult)
2604 if ($eventResult->getType() === \Bitrix\Main\EventResult::SUCCESS)
2608 elseif ($eventResult->getType() === \Bitrix\Main\EventResult::ERROR)
2617 protected function deleteUserFieldValuesByEvent(string $entityId, int $id): ?bool
2621 $event = new \Bitrix\Main\Event('main', 'onDeleteUserFieldValues', ['entityId' => $entityId, 'id' => $id]);
2623 foreach ($event->getResults() as $eventResult)
2625 if ($eventResult->getType() === \Bitrix\Main\EventResult::SUCCESS)
2629 elseif ($eventResult->getType() === \Bitrix\Main\EventResult::ERROR)
2638 protected function getEntities($entity_id, $LANG, $user_id)
2640 $cacheId = $entity_id . ".
" . $LANG . '.' . (int)$user_id;
2643 if (!array_key_exists($cacheId, $this->arFieldsCache))
2645 $arFilter = ["ENTITY_ID
" => $entity_id];
2648 $arFilter["LANG
"] = $LANG;
2650 $rs = CUserTypeEntity::GetList([], $arFilter);
2651 while ($arUserField = $rs->Fetch())
2653 if ($arType = $this->GetUserType($arUserField["USER_TYPE_ID
"]))
2655 if ($user_id !== 0 && is_callable([$arType["CLASS_NAME
"], "checkpermission
"]))
2657 if (!call_user_func_array([$arType["CLASS_NAME
"], "checkpermission
"], [$arUserField, $user_id]))
2662 $arUserField["USER_TYPE
"] = $arType;
2663 $arUserField["VALUE
"] = false;
2664 if (!is_array($arUserField["SETTINGS
"]) || empty($arUserField["SETTINGS
"]))
2666 $arUserField["SETTINGS
"] = $this->PrepareSettings(0, $arUserField);
2668 $result[$arUserField["FIELD_NAME
"]] = $arUserField;
2671 $this->arFieldsCache[$cacheId] = $result;
2675 $result = $this->arFieldsCache[$cacheId];
2681 protected static function normalizeId(string $id): string
2683 return preg_replace("/[^0-9A-Z_]+/
", "", $id);
2686 protected function isFileValueDeleted(array $userField, int $fileId): bool
2688 $fieldName = $userField['FIELD_NAME'] ?? '';
2690 if (is_string($fieldName) && $fieldName !== '')
2692 $deletedValues = Application::getInstance()->getContext()->getRequest()->get($fieldName . '_del');
2694 if (!is_array($deletedValues))
2696 $deletedValues = [$deletedValues];
2699 foreach ($deletedValues as $deletedValue)
2701 if ($fileId === (int)$deletedValue)
2707 $fileInputUtility = FileInputUtility::instance();
2708 $delResult = $fileInputUtility->checkDeletedFiles($fileInputUtility->getUserFieldCid($userField));
2709 if (in_array($fileId, $delResult))
static getConnection($name="")
static isCorrect($time, $format=null)
AdminListAddFilterV2($entityId, &$arFilter, $filterId, $filterFields)
EditFormAddFields($entity_id, &$arFields, array $options=null)
getUserFieldsWithReadyData($entity_id, $readyData, $LANG=false, $user_id=false, $primaryIdName='VALUE_ID')
OnEntityDelete($entity_id)
LoadMultipleValues($arUserField, $valueId)
GetEditFormHTML($bVarsFromForm, $form_value, $arUserField)
GetFilterHTML($arUserField, $filter_name, $filter_value)
getEntities($entity_id, $LANG, $user_id)
GetDBColumnType($arUserField)
AdminListPrepareFields($entity_id, &$arFields)
GetUserType($user_type_id=false)
AdminListAddFilterFieldsV2($entityId, &$arFilterFields)
AddUserField($arUserField, $value, $row)
getUtsDBColumnType($arUserField)
OnAfterFetch($arUserField, $result)
GetRights($ENTITY_ID=false, $ID=false)
AdminListShowFilter($entity_id)
AdminListAddFilter($entityId, &$arFilter)
GetUserFields($entity_id, $value_id=0, $LANG=false, $user_id=false, $selectFields=null)
EditFormShowTab($entity_id, $bVarsFromForm, $ID)
renderField(array $userField, ?array $additionalParameters=[])
getCustomData(array $userField, int $entityValueId)
PrepareSettings($ID, $arUserField, $bCheckUserType=true)
AdminListAddFilterFields($entityId, &$arFilterFields)
getUserFieldValuesByEvent(array $userFields, string $entityId, int $value)
AddUserFields($entity_id, $arRes, $row)
GetUserFieldValue($entity_id, $field_id, $value_id, $LANG=false)
AdminListAddHeaders($entity_id, &$arHeaders)
getPublicText($userField)
AddFindFields($entity_id, &$arFindFields)
getUtmDBColumnType($arUserField)
bx popup label bx width30 PAGE_NEW_MENU_NAME text width
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
global $adminSidePanelHelper
ExecuteModuleEventEx($arEvent, $arParams=[])
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
GetMessage($name, $aReplace=null)
$GLOBALS['____1690880296']
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key