[{"data":1,"prerenderedAt":57},["ShallowReactive",2],{"article:bitrix-admin-customization":3},{"html":4,"toc":5},"\u003Cp>Менеджеру нужен переход к разделам инфоблока из карточки товара, редактору — поле с проверкой служебного кода, оператору — дополнительная информация в заказе. Для этих задач в Битрикс есть разные точки расширения. Обычно достаточно дополнить штатную страницу через событие: добавить кнопку, вкладку, тип поля или блок.\u003C\u002Fp>\n\u003Cp>Ниже разберу, какой способ подходит для каждой задачи и как его подключить. JavaScript нужен для поведения элементов в браузере, \u003Ccode>admin_header.php\u003C\u002Fcode> — для общего PHP-фрагмента, \u003Ccode>OnEndBufferContent\u003C\u002Fcode> — для изменения готовой разметки. Замену формы и отдельную административную страницу оставлю напоследок: к ним стоит переходить, если расширения штатного интерфейса недостаточно.\u003C\u002Fp>\n\u003Cp>Каждый пример решает отдельную задачу и подключается самостоятельно. PHP-обработчики добавляются в \u003Ccode>\u002Flocal\u002Fphp_interface\u002Finit.php\u003C\u002Fcode>, если рядом с кодом не указан другой файл. В существующем PHP-файле повторный \u003Ccode>&lt;?php\u003C\u002Fcode> не нужен. Значение \u003Ccode>7\u003C\u002Fcode> в условиях — ID инфоблока, который нужно заменить своим. Примеры интерфейсных дополнений ограничены администраторами; для других ролей проверку следует заменить проверкой разрешений на конкретный объект.\u003C\u002Fp>\n\u003Ch2 id=\"section-1\">Добавить пункт в левое меню: OnBuildGlobalMenu\u003C\u002Fh2>\n\u003Cp>Пункт меню даёт постоянный вход в нужный раздел. Например, можно вынести разделы конкретного инфоблока в меню «Настройки». Событие \u003Ccode>OnBuildGlobalMenu\u003C\u002Fcode> позволяет дополнить массив модульных пунктов, сохранив существующее меню.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnBuildGlobalMenu'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (&amp;\u003Cspan class=\"hljs-variable\">$globalMenu\u003C\u002Fspan>, &amp;\u003Cspan class=\"hljs-variable\">$moduleMenu\u003C\u002Fspan>): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$moduleMenu\u003C\u002Fspan>[] = [\n            \u003Cspan class=\"hljs-string\">'parent_menu'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'global_menu_settings'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'section'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'alexeslm_extension'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'sort'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-number\">900\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'text'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Разделы каталога'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'title'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Открыть разделы каталога'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'url'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_section_admin.php'\u003C\u002Fspan>\n                . \u003Cspan class=\"hljs-string\">'?IBLOCK_ID=7&amp;type=content&amp;lang='\u003C\u002Fspan>\n                . \u003Cspan class=\"hljs-title function_\">rawurlencode\u003C\u002Fspan>(LANGUAGE_ID),\n            \u003Cspan class=\"hljs-string\">'items_id'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'menu_alexeslm_extension'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'items'\u003C\u002Fspan> =&gt; [],\n        ];\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>В ссылке замените \u003Ccode>IBLOCK_ID=7\u003C\u002Fcode> и \u003Ccode>type=content\u003C\u002Fcode> на ID и тип своего инфоблока. После подключения пункт появится в разделе «Настройки» у администратора. Создавать собственную страницу для такого перехода не требуется.\u003C\u002Fp>\n\u003Ch2 id=\"section-2\">Добавить кнопку над формой: OnAdminContextMenuShow\u003C\u002Fh2>\n\u003Cp>Когда действие относится к открытому объекту, его удобнее разместить рядом с формой. Этот пример добавляет в карточку элемента кнопку перехода к разделам его инфоблока.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminContextMenuShow'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (&amp;\u003Cspan class=\"hljs-variable\">$items\u003C\u002Fspan>, &amp;\u003Cspan class=\"hljs-variable\">$additionalItems\u003C\u002Fspan>): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n            || !\u003Cspan class=\"hljs-title function_\">defined\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ADMIN_SECTION'\u003C\u002Fspan>) || ADMIN_SECTION !== \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() !== \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_edit.php'\u003C\u002Fspan>\n            || (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$_GET\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) !== \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        }\n        \u003Cspan class=\"hljs-variable\">$items\u003C\u002Fspan>[] = [\n            \u003Cspan class=\"hljs-string\">'TEXT'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Разделы инфоблока'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'LINK'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_section_admin.php?IBLOCK_ID=7&amp;type=content&amp;lang='\u003C\u002Fspan>\n                . \u003Cspan class=\"hljs-title function_\">rawurlencode\u003C\u002Fspan>(LANGUAGE_ID),\n        ];\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Условие ограничивает кнопку одной формой и одним инфоблоком. Параметр \u003Ccode>type\u003C\u002Fcode> в ссылке также нужно заменить на тип своего инфоблока.\u003C\u002Fp>\n\u003Ch2 id=\"section-3\">Добавить действие в меню строки: OnAdminListDisplay\u003C\u002Fh2>\n\u003Cp>Если действие выбирают для конкретной строки списка, используйте \u003Ccode>OnAdminListDisplay\u003C\u002Fcode>. Здесь к действиям элемента добавляется переход к его редактированию.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminListDisplay'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (&amp;\u003Cspan class=\"hljs-variable\">$list\u003C\u002Fspan>): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n            || !\u003Cspan class=\"hljs-title function_\">defined\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ADMIN_SECTION'\u003C\u002Fspan>) || ADMIN_SECTION !== \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() !== \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_admin.php'\u003C\u002Fspan>\n            || (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$_GET\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) !== \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        }\n        \u003Cspan class=\"hljs-keyword\">foreach\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">$list\u003C\u002Fspan>-&gt;aRows \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$row\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> = (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$row\u003C\u002Fspan>-&gt;arRes[\u003Cspan class=\"hljs-string\">'ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>);\n            \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> &lt;= \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) { \u003Cspan class=\"hljs-keyword\">continue\u003C\u002Fspan>; }\n            \u003Cspan class=\"hljs-variable\">$url\u003C\u002Fspan> = \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_edit.php?IBLOCK_ID=7&amp;type=content&amp;ID='\u003C\u002Fspan>\n                . \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> . \u003Cspan class=\"hljs-string\">'&amp;lang='\u003C\u002Fspan> . \u003Cspan class=\"hljs-title function_\">rawurlencode\u003C\u002Fspan>(LANGUAGE_ID);\n            \u003Cspan class=\"hljs-variable\">$actions\u003C\u002Fspan> = \u003Cspan class=\"hljs-title function_\">is_array\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$row\u003C\u002Fspan>-&gt;aActions) ? \u003Cspan class=\"hljs-variable\">$row\u003C\u002Fspan>-&gt;aActions : [];\n            \u003Cspan class=\"hljs-variable\">$actions\u003C\u002Fspan>[] = [\u003Cspan class=\"hljs-string\">'TEXT'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Открыть карточку'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'ACTION'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-variable\">$list\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">ActionRedirect\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$url\u003C\u002Fspan>)];\n            \u003Cspan class=\"hljs-variable\">$row\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">AddActions\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$actions\u003C\u002Fspan>);\n        }\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>AddActions()\u003C\u002Fcode> заменяет набор действий строки, поэтому сначала берём существующий \u003Ccode>aActions\u003C\u002Fcode>. В проекте таким же способом добавляется переход к связанному объекту или отчёту с ID строки. Пример относится к классическому административному списку.\u003C\u002Fp>\n\u003Ch2 id=\"section-4\">Добавить кнопку в верхнюю панель сайта: OnPanelCreate\u003C\u002Fh2>\n\u003Cp>Верхняя панель в публичной части сайта — отдельный интерфейс. Если редактору нужен быстрый переход с сайта к списку контента, кнопку добавляют через \u003Ccode>OnPanelCreate\u003C\u002Fcode>, а не через событие контекстного меню административной формы.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnPanelCreate'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">AddPanelButton\u003C\u002Fspan>([\n            \u003Cspan class=\"hljs-string\">'ID'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'catalog_sections'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TEXT'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Разделы каталога'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'HREF'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_section_admin.php?IBLOCK_ID=7&amp;type=content&amp;lang='\u003C\u002Fspan>\n                . \u003Cspan class=\"hljs-title function_\">rawurlencode\u003C\u002Fspan>(LANGUAGE_ID),\n            \u003Cspan class=\"hljs-string\">'SORT'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-number\">900\u003C\u002Fspan>,\n        ]);\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"section-5\">Добавить вкладку элемента или раздела инфоблока\u003C\u002Fh2>\n\u003Cp>Для связанных сведений, которым тесно рядом со штатными полями, подходят \u003Ccode>OnAdminIBlockElementEdit\u003C\u002Fcode> и \u003Ccode>OnAdminIBlockSectionEdit\u003C\u002Fcode>. Они подключают набор вкладок через \u003Ccode>CAdminTabEngine\u003C\u002Fcode>. Пример добавляет вкладку с ID открытого объекта.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\n\u003Cspan class=\"hljs-keyword\">final\u003C\u002Fspan> \u003Cspan class=\"hljs-class\">\u003Cspan class=\"hljs-keyword\">class\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">ProjectIblockTab\u003C\u002Fspan>\n\u003C\u002Fspan>{\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">init\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>)\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK'\u003C\u002Fspan>])\n            &amp;&amp; (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK'\u003C\u002Fspan>][\u003Cspan class=\"hljs-string\">'ID'\u003C\u002Fspan>] !== \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>;\n        }\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\n            \u003Cspan class=\"hljs-string\">'TABSET'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'alexeslm_info'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'GetTabs'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'tabs'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'ShowTab'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'show'\u003C\u002Fspan>],\n        ];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">tabs\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [[\n            \u003Cspan class=\"hljs-string\">'DIV'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'info'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TAB'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Сведения'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'TITLE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Контекст открытого объекта'\u003C\u002Fspan>,\n        ]];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">show\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$div\u003C\u002Fspan>, \u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$fromForm\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">void\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">$div\u003C\u002Fspan> !== \u003Cspan class=\"hljs-string\">'info'\u003C\u002Fspan> || !(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> = (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-keyword\">echo\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;tr&gt;&lt;td&gt;ID:&lt;\u002Ftd&gt;&lt;td&gt;'\u003C\u002Fspan>\n            . (\u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> &gt; \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan> ? \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">'Новый объект: ID ещё нет'\u003C\u002Fspan>)\n            . \u003Cspan class=\"hljs-string\">'&lt;\u002Ftd&gt;&lt;\u002Ftr&gt;'\u003C\u002Fspan>;\n    }\n}\n\n\u003Cspan class=\"hljs-keyword\">foreach\u003C\u002Fspan> ([\u003Cspan class=\"hljs-string\">'OnAdminIBlockElementEdit'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminIBlockSectionEdit'\u003C\u002Fspan>] \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>) {\n    \u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n        \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>, [\u003Cspan class=\"hljs-title class_\">ProjectIblockTab\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'init'\u003C\u002Fspan>]\n    );\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Эти события регистрируются в модуле \u003Ccode>main\u003C\u002Fcode>. \u003Ccode>GetTabs\u003C\u002Fcode> возвращает описание вкладки, \u003Ccode>ShowTab\u003C\u002Fcode> печатает её содержимое. При создании объекта ID ещё нет. Для редактируемых данных одного HTML-поля недостаточно: нужны обработчики проверки и сохранения \u003Ccode>Check\u003C\u002Fcode>\u002F\u003Ccode>Action\u003C\u002Fcode> либо штатное свойство инфоблока.\u003C\u002Fp>\n\u003Ch2 id=\"section-6\">Дополнить существующий CAdminTabControl: OnAdminTabControlBegin\u003C\u002Fh2>\n\u003Cp>Если нужная форма построена на \u003Ccode>CAdminTabControl\u003C\u002Fcode>, её набор вкладок можно расширить через \u003Ccode>OnAdminTabControlBegin\u003C\u002Fcode>. Обработчик должен узнавать конкретную форму: имя контроллера и адрес страницы возьмите из её PHP-кода.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminTabControlBegin'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (&amp;\u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n            || !\u003Cspan class=\"hljs-title function_\">defined\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ADMIN_SECTION'\u003C\u002Fspan>) || ADMIN_SECTION !== \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() !== \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fproject_settings.php'\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>-&gt;name !== \u003Cspan class=\"hljs-string\">'project_settings'\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        }\n        \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>-&gt;tabs[] = [\n            \u003Cspan class=\"hljs-string\">'DIV'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'project_help'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TAB'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Памятка'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TITLE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Порядок изменения настроек'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'CONTENT'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'&lt;tr&gt;&lt;td colspan=\"2\"&gt;Перед изменением сохраните текущие настройки.&lt;\u002Ftd&gt;&lt;\u002Ftr&gt;'\u003C\u002Fspan>,\n        ];\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Здесь \u003Ccode>project_settings.php\u003C\u002Fcode> и \u003Ccode>project_settings\u003C\u002Fcode> обозначают страницу и контроллер, которые вы расширяете: замените оба значения. \u003Ccode>CONTENT\u003C\u002Fcode> выводится внутри таблицы, поэтому содержит \u003Ccode>&lt;tr&gt;\u003C\u002Fcode> и \u003Ccode>&lt;td&gt;\u003C\u002Fcode>. Для стандартной формы элемента инфоблока удобнее специальные события из предыдущего раздела.\u003C\u002Fp>\n\u003Ch2 id=\"section-7\">Создать тип свойства инфоблока: OnIBlockPropertyBuildList\u003C\u002Fh2>\n\u003Cp>Для значения товара или другого элемента инфоблока используйте пользовательский тип свойства. Пример «Служебный код» принимает латинские буквы, цифры, дефис и подчёркивание, ограничивает длину 32 символами и приводит значение к верхнему регистру.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\n\u003Cspan class=\"hljs-keyword\">final\u003C\u002Fspan> \u003Cspan class=\"hljs-class\">\u003Cspan class=\"hljs-keyword\">class\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">ProjectCodeProperty\u003C\u002Fspan>\n\u003C\u002Fspan>{\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">description\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\n            \u003Cspan class=\"hljs-string\">'PROPERTY_TYPE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'S'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'USER_TYPE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'alexeslm_code'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'DESCRIPTION'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Служебный код'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'GetPropertyFieldHtml'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'input'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'GetAdminListViewHTML'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'view'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'CheckFields'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'check'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'ConvertToDB'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'toDb'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'GetLength'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'length'\u003C\u002Fspan>],\n        ];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">input\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">renderInput\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>], \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>);\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">view\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>);\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">check\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">valid\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>) ? []\n            : [\u003Cspan class=\"hljs-string\">'Код: до 32 латинских букв, цифр, дефисов или подчёркиваний.'\u003C\u002Fspan>];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">toDb\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] = \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">length\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">int\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">strlen\u003C\u002Fspan>(\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>));\n    }\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">is_scalar\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) ? \u003Cspan class=\"hljs-title function_\">strtoupper\u003C\u002Fspan>(\u003Cspan class=\"hljs-title function_\">trim\u003C\u002Fspan>((\u003Cspan class=\"hljs-keyword\">string\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>)) : \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">valid\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">bool\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-title function_\">is_scalar\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) &amp;&amp; \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> !== \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">false\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> = \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> === \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-title function_\">preg_match\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'\u002F\\A[A-Z0-9_-]{1,32}\\z\u002F'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) === \u003Cspan class=\"hljs-number\">1\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">private\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">renderInput\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$name\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;input type=\"text\" size=\"32\" maxlength=\"32\" name=\"'\u003C\u002Fspan>\n            . \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$name\u003C\u002Fspan>) . \u003Cspan class=\"hljs-string\">'\" value=\"'\u003C\u002Fspan>\n            . \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) . \u003Cspan class=\"hljs-string\">'\" placeholder=\"SKU-001\"&gt;'\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">private\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">htmlspecialchars\u003C\u002Fspan>((\u003Cspan class=\"hljs-keyword\">string\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>, ENT_QUOTES | ENT_SUBSTITUTE, \u003Cspan class=\"hljs-string\">'UTF-8'\u003C\u002Fspan>);\n    }\n}\n\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'iblock'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnIBlockPropertyBuildList'\u003C\u002Fspan>, [\u003Cspan class=\"hljs-title class_\">ProjectCodeProperty\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'description'\u003C\u002Fspan>]\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>После подключения выберите тип «Служебный код» при создании свойства инфоблока. Ввод \u003Ccode>sku-001\u003C\u002Fcode> сохраняется как \u003Ccode>SKU-001\u003C\u002Fcode>; кириллица и строка длиннее 32 символов отклоняются. Пустое значение допускает сам тип, а обязательность задаётся в настройках поля. HTML-экранирование защищает вывод значения и имени поля.\u003C\u002Fp>\n\u003Ch2 id=\"section-8\">Создать тип пользовательского поля: OnUserTypeBuildList\u003C\u002Fh2>\n\u003Cp>Если данные принадлежат сущности с полями \u003Ccode>UF_*\u003C\u002Fcode>, нужен пользовательский тип поля, а не свойство инфоблока. Например, для служебного кода пользователя можно создать поле \u003Ccode>UF_SERVICE_CODE\u003C\u002Fcode>. Этот пример сам содержит вывод, проверку и нормализацию значения.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\n\u003Cspan class=\"hljs-keyword\">final\u003C\u002Fspan> \u003Cspan class=\"hljs-class\">\u003Cspan class=\"hljs-keyword\">class\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">ProjectCodeUserField\u003C\u002Fspan>\n\u003C\u002Fspan>{\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">description\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\n            \u003Cspan class=\"hljs-string\">'USER_TYPE_ID'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'alexeslm_code'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'CLASS_NAME'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'DESCRIPTION'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Служебный код'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'BASE_TYPE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'string'\u003C\u002Fspan>,\n        ];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">GetDBColumnType\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'varchar(32)'\u003C\u002Fspan>; \u003Cspan class=\"hljs-comment\">\u002F\u002F MySQL, одиночное значение.\u003C\u002Fspan>\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">GetEditFormHTML\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">renderInput\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'NAME'\u003C\u002Fspan>], \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>);\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">GetAdminListViewHTML\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$control\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>);\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">CheckFields\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">valid\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) ? [] : [[\n            \u003Cspan class=\"hljs-string\">'id'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'FIELD_NAME'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'text'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Код: до 32 латинских букв, цифр, дефисов или подчёркиваний.'\u003C\u002Fspan>,\n        ]];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">OnBeforeSave\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$field\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>);\n    }\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">is_scalar\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) ? \u003Cspan class=\"hljs-title function_\">strtoupper\u003C\u002Fspan>(\u003Cspan class=\"hljs-title function_\">trim\u003C\u002Fspan>((\u003Cspan class=\"hljs-keyword\">string\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>)) : \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">valid\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">bool\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-title function_\">is_scalar\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) &amp;&amp; \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> !== \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">false\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> = \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">normalize\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan> === \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-title function_\">preg_match\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'\u002F\\A[A-Z0-9_-]{1,32}\\z\u002F'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) === \u003Cspan class=\"hljs-number\">1\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">private\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">renderInput\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$name\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;input type=\"text\" size=\"32\" maxlength=\"32\" name=\"'\u003C\u002Fspan>\n            . \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$name\u003C\u002Fspan>) . \u003Cspan class=\"hljs-string\">'\" value=\"'\u003C\u002Fspan>\n            . \u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>) . \u003Cspan class=\"hljs-string\">'\" placeholder=\"SKU-001\"&gt;'\u003C\u002Fspan>;\n    }\n\n    \u003Cspan class=\"hljs-keyword\">private\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">escape\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">htmlspecialchars\u003C\u002Fspan>((\u003Cspan class=\"hljs-keyword\">string\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$value\u003C\u002Fspan>, ENT_QUOTES | ENT_SUBSTITUTE, \u003Cspan class=\"hljs-string\">'UTF-8'\u003C\u002Fspan>);\n    }\n}\n\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnUserTypeBuildList'\u003C\u002Fspan>, [\u003Cspan class=\"hljs-title class_\">ProjectCodeUserField\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'description'\u003C\u002Fspan>]\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>После подключения выберите тип «Служебный код» при создании пользовательского поля. Реализация рассчитана на одиночное строковое поле в MySQL. Ввод \u003Ccode>sku-001\u003C\u002Fcode> сохраняется как \u003Ccode>SKU-001\u003C\u002Fcode>; кириллица и строка длиннее 32 символов отклоняются. Пустое значение допускает сам тип, а обязательность задаётся в настройках поля. HTML-экранирование защищает вывод значения и имени поля.\u003C\u002Fp>\n\u003Ch2 id=\"section-9\">Добавить настройку использования свойства: OnPropertyFeatureBuildList\u003C\u002Fh2>\n\u003Cp>Признак свойства нужен, когда существующее поле требуется пометить для дополнительного сценария: например, включать его в выгрузку. Это настройка самого свойства, а не новый тип вводимого значения.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandler\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'iblock'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'Bitrix\\Iblock\\Model\\PropertyFeature::OnPropertyFeatureBuildList'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (\\Bitrix\\Main\\Event \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>): \\Bitrix\\Main\\EventResult {\n        \u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan> = \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">getParameter\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'property'\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-variable\">$features\u003C\u002Fspan> = (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$property\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) === \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>\n            ? [[\u003Cspan class=\"hljs-string\">'MODULE_ID'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'FEATURE_ID'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'PROJECT_EXPORT'\u003C\u002Fspan>,\n                \u003Cspan class=\"hljs-string\">'FEATURE_NAME'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Участвует в выгрузке проекта'\u003C\u002Fspan>]]\n            : [];\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">new\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventResult\u003C\u002Fspan>(\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventResult\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">SUCCESS\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$features\u003C\u002Fspan>);\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>При включённом механизме расширенных свойств появится дополнительный признак. Код выгрузки должен отдельно читать и учитывать его: одна регистрация признака выгрузку не реализует. Здесь используется D7-событие с полным именем класса и параметром \u003Ccode>property\u003C\u002Fcode> в нижнем регистре.\u003C\u002Fp>\n\u003Ch2 id=\"section-10\">Показать строку в информационном блоке заказа\u003C\u002Fh2>\n\u003Cp>Для короткого значения — внутреннего номера или статуса внешней системы — подходит \u003Ccode>sale:onSaleAdminOrderInfoBlockShow\u003C\u002Fcode>. Обработчик возвращает пары \u003Ccode>TITLE\u003C\u002Fcode>\u002F\u003Ccode>VALUE\u003C\u002Fcode>; отдельная вкладка для такой строки не нужна.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">use\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">Bitrix\u003C\u002Fspan>\\\u003Cspan class=\"hljs-title\">Main\u003C\u002Fspan>\\{\u003Cspan class=\"hljs-title\">Event\u003C\u002Fspan>, \u003Cspan class=\"hljs-title\">EventResult\u003C\u002Fspan>};\n\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandler\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'sale'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'onSaleAdminOrderInfoBlockShow'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (Event \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>): EventResult {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">new\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">EventResult\u003C\u002Fspan>(\u003Cspan class=\"hljs-title class_\">EventResult\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">SUCCESS\u003C\u002Fspan>, []);\n        }\n        \u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan> = \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">getParameter\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ORDER'\u003C\u002Fspan>);\n        \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> = \u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan> ? (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">getId\u003C\u002Fspan>() : \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">new\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">EventResult\u003C\u002Fspan>(\u003Cspan class=\"hljs-title class_\">EventResult\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">SUCCESS\u003C\u002Fspan>, [[\n            \u003Cspan class=\"hljs-string\">'TITLE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Внутренний ID'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'VALUE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> &gt; \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan> ? (\u003Cspan class=\"hljs-keyword\">string\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">'Ещё не присвоен'\u003C\u002Fspan>,\n        ]]);\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"section-11\">Добавить перемещаемый блок в карточку заказа\u003C\u002Fh2>\n\u003Cp>Для нескольких связанных сведений или памятки оператору удобен отдельный блок. События \u003Ccode>OnAdminSaleOrderViewDraggable\u003C\u002Fcode>, \u003Ccode>OnAdminSaleOrderEditDraggable\u003C\u002Fcode> и \u003Ccode>OnAdminSaleOrderCreateDraggable\u003C\u002Fcode> подключают его соответственно при просмотре, редактировании и создании заказа.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">final\u003C\u002Fspan> \u003Cspan class=\"hljs-class\">\u003Cspan class=\"hljs-keyword\">class\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">ProjectOrderBlock\u003C\u002Fspan>\n\u003C\u002Fspan>{\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">init\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan> = []\u003C\u002Fspan>)\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\n            \u003Cspan class=\"hljs-string\">'BLOCKSET'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'alexeslm_order'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'getBlocksBrief'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'brief'\u003C\u002Fspan>],\n            \u003Cspan class=\"hljs-string\">'getBlockContent'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'content'\u003C\u002Fspan>],\n        ];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">brief\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\u003Cspan class=\"hljs-string\">'alexeslm_order_note'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-string\">'TITLE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Перед передачей заказа'\u003C\u002Fspan>]];\n    }\n\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">content\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$code\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$selectedTab\u003C\u002Fspan>, \u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">string\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">$code\u003C\u002Fspan> !== \u003Cspan class=\"hljs-string\">'alexeslm_order_note'\u003C\u002Fspan> || !(\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>())) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan> = \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'ORDER'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> = \u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan> ? (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)\u003Cspan class=\"hljs-variable\">$order\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">getId\u003C\u002Fspan>() : \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;div class=\"adm-info-message\"&gt;'\u003C\u002Fspan>\n            . (\u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> &gt; \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan> ? \u003Cspan class=\"hljs-string\">'Заказ №'\u003C\u002Fspan> . \u003Cspan class=\"hljs-variable\">$id\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">'Заказ пока не сохранён'\u003C\u002Fspan>)\n            . \u003Cspan class=\"hljs-string\">'. Проверьте контактные данные и способ доставки.&lt;\u002Fdiv&gt;'\u003C\u002Fspan>;\n    }\n}\n\n\u003Cspan class=\"hljs-keyword\">foreach\u003C\u002Fspan> ([\u003Cspan class=\"hljs-string\">'OnAdminSaleOrderViewDraggable'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminSaleOrderEditDraggable'\u003C\u002Fspan>,\n          \u003Cspan class=\"hljs-string\">'OnAdminSaleOrderCreateDraggable'\u003C\u002Fspan>] \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>) {\n    \u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n        \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>, [\u003Cspan class=\"hljs-title class_\">ProjectOrderBlock\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'init'\u003C\u002Fspan>]\n    );\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>getBlocksBrief\u003C\u002Fcode> описывает блок, \u003Ccode>getBlockContent\u003C\u002Fcode> возвращает HTML. У нового заказа может ещё не быть ID. События движка блоков регистрируются в \u003Ccode>main\u003C\u002Fcode>, хотя сама карточка относится к модулю продаж.\u003C\u002Fp>\n\u003Ch2 id=\"section-12\">Добавить отдельную вкладку заказа\u003C\u002Fh2>\n\u003Cp>Вкладка подходит для сведений, которые нужно вынести за пределы основного экрана заказа: например, регламента обработки или истории обмена. Для этого служат \u003Ccode>OnAdminSaleOrderView\u003C\u002Fcode>, \u003Ccode>OnAdminSaleOrderEdit\u003C\u002Fcode> и \u003Ccode>OnAdminSaleOrderCreate\u003C\u002Fcode>. Ниже — самостоятельная вкладка с памяткой.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">final\u003C\u002Fspan> \u003Cspan class=\"hljs-class\">\u003Cspan class=\"hljs-keyword\">class\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">ProjectOrderTab\u003C\u002Fspan>\n\u003C\u002Fspan>{\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">init\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>)\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [\u003Cspan class=\"hljs-string\">'TABSET'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'project_order_help'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'GetTabs'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'tabs'\u003C\u002Fspan>], \u003Cspan class=\"hljs-string\">'ShowTab'\u003C\u002Fspan> =&gt; [\u003Cspan class=\"hljs-built_in\">self\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'show'\u003C\u002Fspan>]];\n    }\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">tabs\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">array\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan> [[\u003Cspan class=\"hljs-string\">'DIV'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'help'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TAB'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Памятка'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'TITLE'\u003C\u002Fspan> =&gt; \u003Cspan class=\"hljs-string\">'Перед передачей заказа'\u003C\u002Fspan>]];\n    }\n    \u003Cspan class=\"hljs-keyword\">public\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> \u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-keyword\">function\u003C\u002Fspan> \u003Cspan class=\"hljs-title\">show\u003C\u002Fspan>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable\">$div\u003C\u002Fspan>, \u003Cspan class=\"hljs-keyword\">array\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$args\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$fromForm\u003C\u002Fspan>\u003C\u002Fspan>): \u003Cspan class=\"hljs-title\">void\u003C\u002Fspan>\n    \u003C\u002Fspan>{\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">$div\u003C\u002Fspan> !== \u003Cspan class=\"hljs-string\">'help'\u003C\u002Fspan> || !\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()) { \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>; }\n        \u003Cspan class=\"hljs-keyword\">echo\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;tr&gt;&lt;td colspan=\"2\"&gt;Проверьте контактные данные и способ доставки.&lt;\u002Ftd&gt;&lt;\u002Ftr&gt;'\u003C\u002Fspan>;\n    }\n}\n\u003Cspan class=\"hljs-keyword\">foreach\u003C\u002Fspan> ([\u003Cspan class=\"hljs-string\">'OnAdminSaleOrderView'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminSaleOrderEdit'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnAdminSaleOrderCreate'\u003C\u002Fspan>] \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>) {\n    \u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n        \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$event\u003C\u002Fspan>, [\u003Cspan class=\"hljs-title class_\">ProjectOrderTab\u003C\u002Fspan>::\u003Cspan class=\"hljs-variable\">class\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'init'\u003C\u002Fspan>]\n    );\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Вкладка использует \u003Ccode>CAdminTabEngine\u003C\u002Fcode>; её события также относятся к \u003Ccode>main\u003C\u002Fcode>. Пример только выводит информацию. Если разместить здесь поля, обработку и сохранение их значений нужно реализовать отдельно.\u003C\u002Fp>\n\u003Ch2 id=\"section-13\">Подключить JavaScript для поведения элементов формы\u003C\u002Fh2>\n\u003Cp>JavaScript подходит для раскрытия пояснений, переключения видимости полей и реакции на действия пользователя. PHP по-прежнему проверяет и сохраняет данные. Подключим скрипт только в форме элемента нужного инфоблока через \u003Ccode>OnEpilog\u003C\u002Fcode> и \u003Ccode>Asset::addJs()\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnEpilog'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n            &amp;&amp; \u003Cspan class=\"hljs-title function_\">defined\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ADMIN_SECTION'\u003C\u002Fspan>) &amp;&amp; ADMIN_SECTION === \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>\n            &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() === \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_edit.php'\u003C\u002Fspan>\n            &amp;&amp; (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$_GET\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) === \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\Page\\Asset\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addJs\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'\u002Flocal\u002Fjs\u002Fadmin-help.js'\u003C\u002Fspan>);\n        }\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>В HTML своего поля или вкладки разместите кнопку и пояснение. Если строка выводится внутри таблицы административной формы, её содержимое нужно поместить в \u003Ccode>&lt;tr&gt;&lt;td&gt;\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: html\">\u003Ccode class=\"hljs language-html\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">button\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">type\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">\"button\"\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">data-admin-extension-toggle\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">aria-expanded\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">\"false\"\u003C\u002Fspan>\n        \u003Cspan class=\"hljs-attr\">aria-controls\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">\"admin-extension-help\"\u003C\u002Fspan>&gt;\u003C\u002Fspan>Показать пояснение\u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">button\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">p\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">id\u003C\u002Fspan>=\u003Cspan class=\"hljs-string\">\"admin-extension-help\"\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">hidden\u003C\u002Fspan>&gt;\u003C\u002Fspan>Служебный код используется при обмене с внешней системой.\u003Cspan class=\"hljs-tag\">&lt;\u002F\u003Cspan class=\"hljs-name\">p\u003C\u002Fspan>&gt;\u003C\u002Fspan>\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Содержимое \u003Ccode>\u002Flocal\u002Fjs\u002Fadmin-help.js\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: javascript\">\u003Ccode class=\"hljs language-javascript\">(\u003Cspan class=\"hljs-function\">() =&gt;\u003C\u002Fspan> {\n    \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-variable\">window\u003C\u002Fspan>.\u003Cspan class=\"hljs-property\">alexeslmAdminExtensionBound\u003C\u002Fspan>) \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n    \u003Cspan class=\"hljs-variable\">window\u003C\u002Fspan>.\u003Cspan class=\"hljs-property\">alexeslmAdminExtensionBound\u003C\u002Fspan> = \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>;\n    \u003Cspan class=\"hljs-variable\">document\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'click'\u003C\u002Fspan>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">event\u003C\u002Fspan>) =&gt;\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">const\u003C\u002Fspan> button = event.\u003Cspan class=\"hljs-property\">target\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">instanceof\u003C\u002Fspan> \u003Cspan class=\"hljs-title class_\">Element\u003C\u002Fspan>\n            ? event.\u003Cspan class=\"hljs-property\">target\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">closest\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'[data-admin-extension-toggle]'\u003C\u002Fspan>) : \u003Cspan class=\"hljs-literal\">null\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!button) \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C\u002Fspan> help = \u003Cspan class=\"hljs-variable\">document\u003C\u002Fspan>.\u003Cspan class=\"hljs-title function_\">getElementById\u003C\u002Fspan>(button.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'aria-controls'\u003C\u002Fspan>));\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!help) \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C\u002Fspan> expanded = button.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'aria-expanded'\u003C\u002Fspan>) === \u003Cspan class=\"hljs-string\">'true'\u003C\u002Fspan>;\n        button.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'aria-expanded'\u003C\u002Fspan>, \u003Cspan class=\"hljs-title class_\">String\u003C\u002Fspan>(!expanded));\n        button.\u003Cspan class=\"hljs-property\">textContent\u003C\u002Fspan> = expanded ? \u003Cspan class=\"hljs-string\">'Показать пояснение'\u003C\u002Fspan> : \u003Cspan class=\"hljs-string\">'Скрыть пояснение'\u003C\u002Fspan>;\n        help.\u003Cspan class=\"hljs-property\">hidden\u003C\u002Fspan> = expanded;\n    });\n})();\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Скрипт меняет \u003Ccode>hidden\u003C\u002Fcode> и \u003Ccode>aria-expanded\u003C\u002Fcode>. Делегирование клика позволяет обработать и элементы, добавленные после загрузки страницы. \u003Ccode>OnEpilog\u003C\u002Fcode> здесь регистрирует ресурс, а не печатает \u003Ccode>&lt;script&gt;\u003C\u002Fcode> после готового документа.\u003C\u002Fp>\n\u003Ch2 id=\"section-14\">Вывести общий PHP-фрагмент через admin_header.php\u003C\u002Fh2>\n\u003Cp>Если сообщение должно появляться перед содержимым административных страниц, можно использовать \u003Ccode>\u002Flocal\u002Fphp_interface\u002Fadmin_header.php\u003C\u002Fcode>. В примере уведомление ограничено формой редактирования элементов одного инфоблока. Добавьте фрагмент в существующий файл, сохранив его содержимое.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n    &amp;&amp; \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() === \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_edit.php'\u003C\u002Fspan>\n    &amp;&amp; (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$_GET\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) === \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>) {\n    \u003Cspan class=\"hljs-keyword\">echo\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;div class=\"adm-info-message\"&gt;Изменения каталога попадут в следующую выгрузку.&lt;\u002Fdiv&gt;'\u003C\u002Fspan>;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Это подключаемый PHP-файл, а не событие. Он подходит для общего сообщения, но не заменяет API вкладок, кнопок и типов полей.\u003C\u002Fp>\n\u003Ch2 id=\"section-15\">Изменить готовый HTML через OnEndBufferContent\u003C\u002Fh2>\n\u003Cp>Если подходящего события для элемента нет, остаётся обработка выходного буфера. Например, код ниже заменяет HTML-маркер, который уже выводится вашим шаблоном формы. Этот способ зависит от разметки, поэтому сначала стоит проверить штатные точки расширения.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-title class_\">\\Bitrix\\Main\\EventManager\u003C\u002Fspan>::\u003Cspan class=\"hljs-title function_\">getInstance\u003C\u002Fspan>()-&gt;\u003Cspan class=\"hljs-title function_\">addEventHandlerCompatible\u003C\u002Fspan>(\n    \u003Cspan class=\"hljs-string\">'main'\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'OnEndBufferContent'\u003C\u002Fspan>,\n    \u003Cspan class=\"hljs-built_in\">static\u003C\u002Fspan> function (&amp;\u003Cspan class=\"hljs-variable\">$content\u003C\u002Fspan>): \u003Cspan class=\"hljs-keyword\">void\u003C\u002Fspan> {\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-keyword\">isset\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]) || !\u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'USER'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()\n            || !\u003Cspan class=\"hljs-title function_\">defined\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'ADMIN_SECTION'\u003C\u002Fspan>) || ADMIN_SECTION !== \u003Cspan class=\"hljs-literal\">true\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-variable\">$GLOBALS\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'APPLICATION'\u003C\u002Fspan>]-&gt;\u003Cspan class=\"hljs-title function_\">GetCurPage\u003C\u002Fspan>() !== \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fadmin\u002Fiblock_element_edit.php'\u003C\u002Fspan>\n            || (\u003Cspan class=\"hljs-keyword\">int\u003C\u002Fspan>)(\u003Cspan class=\"hljs-variable\">$_GET\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'IBLOCK_ID'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>) !== \u003Cspan class=\"hljs-number\">7\u003C\u002Fspan>\n            || (\u003Cspan class=\"hljs-variable\">$_SERVER\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'REQUEST_METHOD'\u003C\u002Fspan>] ?? \u003Cspan class=\"hljs-string\">''\u003C\u002Fspan>) !== \u003Cspan class=\"hljs-string\">'GET'\u003C\u002Fspan>\n            || \u003Cspan class=\"hljs-title function_\">stripos\u003C\u002Fspan>(\u003Cspan class=\"hljs-variable\">$content\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">'&lt;\u002Fhtml&gt;'\u003C\u002Fspan>) === \u003Cspan class=\"hljs-literal\">false\u003C\u002Fspan>) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C\u002Fspan>;\n        }\n        \u003Cspan class=\"hljs-variable\">$content\u003C\u002Fspan> = \u003Cspan class=\"hljs-title function_\">str_replace\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'&lt;!--PROJECT_CATALOG_NOTE--&gt;'\u003C\u002Fspan>,\n            \u003Cspan class=\"hljs-string\">'&lt;p class=\"adm-info-message\"&gt;Проверьте данные перед выгрузкой.&lt;\u002Fp&gt;'\u003C\u002Fspan>, \u003Cspan class=\"hljs-variable\">$content\u003C\u002Fspan>);\n    }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Маркер \u003Ccode>&lt;!--PROJECT_CATALOG_NOTE--&gt;\u003C\u002Fcode> должен присутствовать в исходном HTML; без него замены не будет. Буфер передаётся по ссылке. Условия ограничивают обработчик полной HTML-страницей выбранной формы и не предназначены для AJAX-ответов.\u003C\u002Fp>\n\u003Ch2 id=\"section-16\">Заменить форму элемента через EDIT_FILE_AFTER\u003C\u002Fh2>\n\u003Cp>Если настройки формы, вкладок и типов свойств недостаточно, для инфоблока можно указать собственную форму редактирования. Это уже замена интерфейса: поддержку его поведения и совместимости придётся брать на себя.\u003C\u002Fp>\n\u003Cp>В настройках инфоблока укажите путь в параметре \u003Ccode>EDIT_FILE_AFTER\u003C\u002Fcode>, например \u003Ccode>\u002Flocal\u002Fadmin\u002Fcatalog_element_form.php\u003C\u002Fcode>. За основу возьмите действующую форму из установленного ядра, разберите её зависимости и сохраните обработку полей, проверку прав, сессии и ошибок. Файл подключается штатной страницей редактирования после обработки данных: он не является самостоятельным обработчиком сохранения. Ветка пользовательской формы отличается от штатной в том числе проверкой сессии, поэтому нельзя ограничиться копированием HTML: проверку запроса нужно сохранить в обработке до записи данных.\u003C\u002Fp>\n\u003Cp>Универсального короткого кода для полной замены нет: содержимое зависит от полей конкретного инфоблока. Такой способ оправдан при существенной перестройке экрана; ради дополнительной кнопки или информационного блока менять всю форму не нужно.\u003C\u002Fp>\n\u003Ch2 id=\"section-17\">Создать отдельную административную страницу\u003C\u002Fh2>\n\u003Cp>Собственная страница нужна для самостоятельного инструмента: отчёта с отдельными фильтрами, управления своей сущностью или обработки данных из нескольких модулей. Это крайний вариант, если нужный сценарий не помещается в штатные формы и их расширения.\u003C\u002Fp>\n\u003Cp>Основной код разместите в \u003Ccode>\u002Flocal\u002Fadmin\u002Fproject_tool.php\u003C\u002Fcode>. Минимальная страница подключает административное окружение, проверяет доступ и выводит содержимое между прологом и эпилогом.\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">require\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$_SERVER\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'DOCUMENT_ROOT'\u003C\u002Fspan>] . \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_admin_before.php'\u003C\u002Fspan>;\n\u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> (!\u003Cspan class=\"hljs-variable\">$USER\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">IsAdmin\u003C\u002Fspan>()) {\n    \u003Cspan class=\"hljs-variable\">$APPLICATION\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">AuthForm\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'Доступ только администратору.'\u003C\u002Fspan>);\n}\n\u003Cspan class=\"hljs-variable\">$APPLICATION\u003C\u002Fspan>-&gt;\u003Cspan class=\"hljs-title function_\">SetTitle\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">'Проверка интеграции'\u003C\u002Fspan>);\n\u003Cspan class=\"hljs-keyword\">require\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$_SERVER\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'DOCUMENT_ROOT'\u003C\u002Fspan>] . \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_admin_after.php'\u003C\u002Fspan>;\n\u003Cspan class=\"hljs-keyword\">echo\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">'&lt;div class=\"adm-info-message\"&gt;Здесь размещается результат проверки интеграции.&lt;\u002Fdiv&gt;'\u003C\u002Fspan>;\n\u003Cspan class=\"hljs-keyword\">require\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$_SERVER\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'DOCUMENT_ROOT'\u003C\u002Fspan>] . \u003Cspan class=\"hljs-string\">'\u002Fbitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fepilog_admin.php'\u003C\u002Fspan>;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Точка входа \u003Ccode>\u002Fbitrix\u002Fadmin\u002Fproject_tool.php\u003C\u002Fcode> подключает этот файл:\u003C\u002Fp>\n\u003Cpre tabindex=\"0\" aria-label=\"Блок кода: php\">\u003Ccode class=\"hljs language-php\">\u003Cspan class=\"hljs-meta\">&lt;?php\u003C\u002Fspan>\n\u003Cspan class=\"hljs-keyword\">require\u003C\u002Fspan> \u003Cspan class=\"hljs-variable\">$_SERVER\u003C\u002Fspan>[\u003Cspan class=\"hljs-string\">'DOCUMENT_ROOT'\u003C\u002Fspan>] . \u003Cspan class=\"hljs-string\">'\u002Flocal\u002Fadmin\u002Fproject_tool.php'\u003C\u002Fspan>;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Откройте \u003Ccode>\u002Fbitrix\u002Fadmin\u002Fproject_tool.php\u003C\u002Fcode> под администратором: появятся заголовок и информационный блок. Если инструмент изменяет данные, добавьте POST-обработчик с проверкой сессии, прав и входных значений до вывода страницы. Сам административный пролог не реализует бизнес-логику инструмента.\u003C\u002Fp>\n\u003Cp>Выбирайте точку расширения по месту действия: переход — в меню или кнопке, данные объекта — в поле или вкладке, сведения заказа — в его карточке. После подключения выбранного примера проверьте нужную страницу и соседние экраны, а также доступ под теми ролями, которые будут пользоваться доработкой.\u003C\u002Fp>\n",[6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],{"id":7,"title":8},"section-1","Добавить пункт в левое меню: OnBuildGlobalMenu",{"id":10,"title":11},"section-2","Добавить кнопку над формой: OnAdminContextMenuShow",{"id":13,"title":14},"section-3","Добавить действие в меню строки: OnAdminListDisplay",{"id":16,"title":17},"section-4","Добавить кнопку в верхнюю панель сайта: OnPanelCreate",{"id":19,"title":20},"section-5","Добавить вкладку элемента или раздела инфоблока",{"id":22,"title":23},"section-6","Дополнить существующий CAdminTabControl: OnAdminTabControlBegin",{"id":25,"title":26},"section-7","Создать тип свойства инфоблока: OnIBlockPropertyBuildList",{"id":28,"title":29},"section-8","Создать тип пользовательского поля: OnUserTypeBuildList",{"id":31,"title":32},"section-9","Добавить настройку использования свойства: OnPropertyFeatureBuildList",{"id":34,"title":35},"section-10","Показать строку в информационном блоке заказа",{"id":37,"title":38},"section-11","Добавить перемещаемый блок в карточку заказа",{"id":40,"title":41},"section-12","Добавить отдельную вкладку заказа",{"id":43,"title":44},"section-13","Подключить JavaScript для поведения элементов формы",{"id":46,"title":47},"section-14","Вывести общий PHP-фрагмент через admin_header.php",{"id":49,"title":50},"section-15","Изменить готовый HTML через OnEndBufferContent",{"id":52,"title":53},"section-16","Заменить форму элемента через EDIT_FILE_AFTER",{"id":55,"title":56},"section-17","Создать отдельную административную страницу",1790082845804]