[{"data":1,"prerenderedAt":1696},["ShallowReactive",2],{"navigation_docs":3,"-modules-options-portal-check":238,"-modules-options-portal-check-surround":1693},[4,45,60],{"title":5,"description":6,"icon":7,"path":8,"stem":9,"children":10},"Методология",null,"ruler","\u002Fmethodology","1.methodology",[11,15,20,25,30,35,40],{"title":12,"path":8,"stem":13,"description":14},"bxshef: методология и проверка навыков","1.methodology\u002Findex","Как писать навыки ИИ-агентов для Битрикса и как проверять, что им можно верить",{"title":16,"path":17,"stem":18,"description":19},"Стандарт навыка","\u002Fmethodology\u002Fstandard","1.methodology\u002F1.standard","11 правил, каждое из провала на стенде",{"title":21,"path":22,"stem":23,"description":24},"Методология проверки","\u002Fmethodology\u002Fmethod","1.methodology\u002F2.method","lint → eval → стенд; что измерено",{"title":26,"path":27,"stem":28,"description":29},"bxshef — CLI","\u002Fmethodology\u002Fbxshef","1.methodology\u002F3.bxshef","lint, eval, feedback",{"title":31,"path":32,"stem":33,"description":34},"GitHub Action","\u002Fmethodology\u002Faction","1.methodology\u002F4.action","тот же lint + eval в любом репозитории навыков",{"title":36,"path":37,"stem":38,"description":39},"Заготовка репозитория","\u002Fmethodology\u002Ftemplate","1.methodology\u002F5.template","с чего начать автору модуля",{"title":41,"path":42,"stem":43,"description":44},"Приёмник отзывов","\u002Fmethodology\u002Ffeedback","1.methodology\u002F6.feedback","куда уходят отзывы ИИ-агентов",{"title":46,"description":6,"icon":47,"path":48,"stem":49,"children":50},"Навыки","sparkles","\u002Fskills","2.skills",[51,55],{"title":52,"path":48,"stem":53,"description":54},"Навыки shef.*","2.skills\u002Findex","npx skills add bx-shef\u002Fskills",{"title":56,"path":57,"stem":58,"description":59},"shef-feedback","\u002Fskills\u002Fshef-feedback","2.skills\u002F1.shef-feedback","Отправить отзыв о навыке shef-* или навыке команды. Брать ВСЕГДА, когда просят оставить или отправить отзыв о навыке — даже если сам навык в диалоге не виден, —",{"title":61,"description":6,"icon":62,"path":63,"stem":64,"children":65},"Модули shef.*","package","\u002Fmodules","3.modules",[66,69,131,179],{"title":61,"path":63,"stem":67,"description":68},"3.modules\u002Findex","Что за чем ставить",{"title":70,"description":6,"path":71,"stem":72,"children":73},"shef.options","\u002Fmodules\u002Foptions","3.modules\u002F1.options\u002Findex",[74,76,81,86,91,96,101,106,110,114,119,123,127],{"title":70,"path":71,"stem":72,"description":75},"фундамент: настройки, трейты, компоненты",{"title":77,"path":78,"stem":79,"description":80},"[`\\Shef\\Options\\Installator`] Installer","\u002Fmodules\u002Foptions\u002Finstaller","3.modules\u002F1.options\u002F1.installer","Для облегчения установок.",{"title":82,"path":83,"stem":84,"description":85},"Сборка, CI и релиз","\u002Fmodules\u002Foptions\u002Fbuild-and-install","3.modules\u002F1.options\u002F10.build-and-install","Раскладка репозитория — в module-structure.md, процесс —\nв CONTRIBUTING.md, установка глазами пользователя —\nв README.md.",{"title":87,"path":88,"stem":89,"description":90},"Раскладка репозитория","\u002Fmodules\u002Foptions\u002Fmodule-structure","3.modules\u002F1.options\u002F11.module-structure","Файл про устройство репозитория. Опорные точки модуля — в CLAUDE.md,\nпроцесс — в CONTRIBUTING.md, сборка — в\nbuild-and-install.md.",{"title":92,"path":93,"stem":94,"description":95},"Проверка на портале","\u002Fmodules\u002Foptions\u002Fportal-check","3.modules\u002F1.options\u002F12.portal-check","Всё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, кеш,\nраскладка файлов, поведение при обновлении. Проверять это приходится руками —\nи лучше по списку, потому что забытый шаг находит не разработчик, а клиент.",{"title":97,"path":98,"stem":99,"description":100},"[`\\Shef\\Options\\Main\\Options`] Опции настроек модуля","\u002Fmodules\u002Foptions\u002Foptions","3.modules\u002F1.options\u002F2.options","Поддерживает следующие типы:",{"title":102,"path":103,"stem":104,"description":105},"Работа с пользователями","\u002Fmodules\u002Foptions\u002Fsecurity","3.modules\u002F1.options\u002F3.security","",{"title":107,"path":108,"stem":109,"description":105},"[`\\Shef\\Options\\Main\\Utils`] Утилиты","\u002Fmodules\u002Foptions\u002Futils","3.modules\u002F1.options\u002F4.utils",{"title":111,"path":112,"stem":113,"description":105},"[`\\Shef\\Options\\Components`] Работа с компонентами","\u002Fmodules\u002Foptions\u002Fcomponents","3.modules\u002F1.options\u002F5.components",{"title":115,"path":116,"stem":117,"description":118},"[`\\Shef\\Options\\Options`] Паттерны","\u002Fmodules\u002Foptions\u002Fpattern","3.modules\u002F1.options\u002F6.pattern","Запускаемые примеры: singleton.php,\nconfig.php, smartstd.php —\nкак их гонять, написано в examples\u002FREADME.md.",{"title":120,"path":121,"stem":122,"description":105},"[`\\Shef\\Options\\Tests`] Тестирование","\u002Fmodules\u002Foptions\u002Ftests","3.modules\u002F1.options\u002F7.tests",{"title":124,"path":125,"stem":126,"description":105},"[`\\Shef\\Options\\TraitList`] Набор трейтов","\u002Fmodules\u002Foptions\u002Ftraitlist","3.modules\u002F1.options\u002F8.traitlist",{"title":128,"path":129,"stem":130,"description":105},"Правила для ИИ-агентов в этом репозитории","\u002Fmodules\u002Foptions\u002Fagent-rules","3.modules\u002F1.options\u002F9.agent-rules",{"title":132,"description":6,"path":133,"stem":134,"children":135},"shef.problems","\u002Fmodules\u002Fproblems","3.modules\u002F2.problems\u002Findex",[136,138,143,147,152,157,161,166,169,172,175],{"title":132,"path":133,"stem":134,"description":137},"логи, журнал событий, учёт проблем",{"title":139,"path":140,"stem":141,"description":142},"[`\\Shef\\Problems\\Integration`] События и меню","\u002Fmodules\u002Fproblems\u002Fevents","3.modules\u002F2.problems\u002F1.events","Что модуль регистрирует в ядре при установке. Список — в .settings.php, ключ\ninstallEvents; что каждый обработчик существует, сверяет\ntests\u002Fsettings_test.php.",{"title":144,"path":145,"stem":146,"description":105},"Безопасность логов","\u002Fmodules\u002Fproblems\u002Fsecurity","3.modules\u002F2.problems\u002F10.security",{"title":148,"path":149,"stem":150,"description":151},"Быстрая отладка: `_pr`, `_log`, `_log1`","\u002Fmodules\u002Fproblems\u002Fdeffunctions","3.modules\u002F2.problems\u002F2.deffunctions","Функции объявляет def-functions.php, подключается он из include.php.",{"title":153,"path":154,"stem":155,"description":156},"Уровни логирования","\u002Fmodules\u002Fproblems\u002Floglevel","3.modules\u002F2.problems\u002F3.loglevel","Уровни — стандарт PSR-3, в Monolog это \\Monolog\\Level. Ниже — когда какой брать.",{"title":158,"path":159,"stem":160,"description":105},"[`\\Shef\\Problems\\Integration\\Monolog`] Monolog","\u002Fmodules\u002Fproblems\u002Fmonolog","3.modules\u002F2.problems\u002F4.monolog",{"title":162,"path":163,"stem":164,"description":165},"Ротация логов","\u002Fmodules\u002Fproblems\u002Flogrotate","3.modules\u002F2.problems\u002F5.logrotate","Логи модуля лежат в каталоге логов — по умолчанию на уровень выше корня сайта,\nдля BitrixVM \u002Fhome\u002Fbitrix\u002Fsh_log\u002F*.log, — и сами не чистятся. Ротацию делает\nlogrotate — системная утилита, а не Monolog: Monolog тоже умеет\n(RotatingFileHandler), но тогда за файлами следит каждый PHP-процесс, а не\nодна служба.",{"title":128,"path":167,"stem":168,"description":105},"\u002Fmodules\u002Fproblems\u002Fagent-rules","3.modules\u002F2.problems\u002F6.agent-rules",{"title":82,"path":170,"stem":171,"description":85},"\u002Fmodules\u002Fproblems\u002Fbuild-and-install","3.modules\u002F2.problems\u002F7.build-and-install",{"title":87,"path":173,"stem":174,"description":90},"\u002Fmodules\u002Fproblems\u002Fmodule-structure","3.modules\u002F2.problems\u002F8.module-structure",{"title":92,"path":176,"stem":177,"description":178},"\u002Fmodules\u002Fproblems\u002Fportal-check","3.modules\u002F2.problems\u002F9.portal-check","Всё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, меню,\nраскладка файлов, журнал событий, поведение при обновлении. Проверять это\nприходится руками — и лучше по списку, потому что забытый шаг находит не\nразработчик, а клиент.",{"title":180,"description":6,"path":181,"stem":182,"children":183},"shef.insync","\u002Fmodules\u002Finsync","3.modules\u002F3.insync\u002Findex",[184,186,191,194,198,203,208,213,218,222,227,232,235],{"title":180,"path":181,"stem":182,"description":185},"агенты, импорт, API-клиенты, модели",{"title":187,"path":188,"stem":189,"description":190},"[`\\Shef\\InSync\\Agents`] Агенты","\u002Fmodules\u002Finsync\u002Fagents","3.modules\u002F3.insync\u002F1.agents","Агент импорта — наследник \\Shef\\InSync\\Agents\\AAgent. Описание агента для\nb_agent — \\Shef\\InSync\\Agents\\Entity, установку и управление берёт на себя\n\\Shef\\InSync\\Agents\\Manager.",{"title":87,"path":192,"stem":193,"description":90},"\u002Fmodules\u002Finsync\u002Fmodule-structure","3.modules\u002F3.insync\u002F10.module-structure",{"title":92,"path":195,"stem":196,"description":197},"\u002Fmodules\u002Finsync\u002Fportal-check","3.modules\u002F3.insync\u002F11.portal-check","Всё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, левое\nменю, раскладка компонентов, агенты, таблица импорта, поведение при\nобновлении. Проверять это приходится руками — и лучше по списку, потому что\nзабытый шаг находит не разработчик, а клиент.",{"title":199,"path":200,"stem":201,"description":202},"Безопасность","\u002Fmodules\u002Finsync\u002Fsecurity","3.modules\u002F3.insync\u002F12.security","Модуль даёт другим модулям заготовки для синхронизаций, и самые опасные места\nу него общие с ними: кто может запускать агенты и импорт, что ложится в каталоги\nимпорта, что уходит в SQL и в лог. Ниже — что держит модуль и что остаётся\nпроекту.",{"title":204,"path":205,"stem":206,"description":207},"[`\\Shef\\InSync\\Sync`] Импорт","\u002Fmodules\u002Finsync\u002Fimport","3.modules\u002F3.insync\u002F2.import","Импорт идёт в два шага через таблицу импорта \\Shef\\InSync\\Sync\\Model\\SyncTable\n(shef_insync_model):",{"title":209,"path":210,"stem":211,"description":212},"[`\\Shef\\InSync\\Api`] API","\u002Fmodules\u002Finsync\u002Fapi","3.modules\u002F3.insync\u002F3.api","Обращение к внешнему API по HTTP — наследник \\Shef\\InSync\\Api\\AConnector.",{"title":214,"path":215,"stem":216,"description":217},"[`\\Shef\\InSync\\TraitList\\Xml`] Парсинг XML","\u002Fmodules\u002Finsync\u002Fxml","3.modules\u002F3.insync\u002F4.xml","Разбор XML сделан через SbWereWolf\u002Fxml-navigator\n(статья на Хабре): XMLReader идёт по\nдокументу потоком, а каждый элемент с нужным тегом HierarchyComposer\nпревращает в массив — n имя, v значение, a атрибуты, s вложенные\nэлементы.",{"title":219,"path":220,"stem":221,"description":105},"Компоненты","\u002Fmodules\u002Finsync\u002Fcomponents","3.modules\u002F3.insync\u002F5.components",{"title":223,"path":224,"stem":225,"description":226},"Страницы","\u002Fmodules\u002Finsync\u002Fpage","3.modules\u002F3.insync\u002F6.page","Страницы модуля — в левом меню, штатным разделом intranet\n(Bitrix\\Intranet\\CustomSection): раздел «SH Импорт», код shinsync.\nВерхней панели и shef.uiclear больше нет.",{"title":228,"path":229,"stem":230,"description":231},"[`\\Shef\\InSync\\Main\\Options`] Опции настроек модуля","\u002Fmodules\u002Finsync\u002Foptions","3.modules\u002F3.insync\u002F7.options","Опции для страницы настроек модуля импорта (на ShOptionsConfig из\nshef.options): добавьте их во вкладку своего options_conf.php.",{"title":128,"path":233,"stem":234,"description":105},"\u002Fmodules\u002Finsync\u002Fagent-rules","3.modules\u002F3.insync\u002F8.agent-rules",{"title":82,"path":236,"stem":237,"description":85},"\u002Fmodules\u002Finsync\u002Fbuild-and-install","3.modules\u002F3.insync\u002F9.build-and-install",{"id":239,"title":92,"body":240,"description":95,"extension":1687,"meta":1688,"navigation":1689,"path":93,"rawbody":1690,"seo":1691,"stem":94,"__hash__":1692},"docs\u002F3.modules\u002F1.options\u002F12.portal-check.md",{"type":241,"value":242,"toc":1670},"minimark",[243,246,254,266,271,353,360,364,370,432,435,462,466,473,545,548,558,565,602,606,609,620,623,668,674,684,698,702,721,727,733,737,740,745,766,777,781,804,810,820,824,828,836,841,847,850,862,866,905,916,923,927,937,945,956,969,973,981,1013,1017,1043,1048,1059,1062,1072,1093,1104,1108,1111,1127,1134,1149,1164,1241,1245,1252,1281,1300,1327,1356,1363,1373,1376,1484,1488,1491,1500,1519,1533,1543,1573,1576,1580,1583,1623,1626,1630,1638,1641,1653,1666],[244,245,95],"p",{},[244,247,248,249,253],{},"Процедура рассчитана на ",[250,251,252],"strong",{},"отдельный стенд",", а не на боевой портал. Шаги\n«удалить модуль» и «поставить на CP1251» на рабочем портале делать нельзя.",[244,255,256,257,261,262,265],{},"Раскладка репозитория — в ",[258,259,260],"a",{"href":88},"module-structure.md",", сборка и\nрелиз — в ",[258,263,264],{"href":83},"build-and-install.md",".",[267,268,270],"h2",{"id":269},"что-понадобится","Что понадобится",[272,273,274,285],"table",{},[275,276,277],"thead",{},[278,279,280,283],"tr",{},[281,282],"th",{},[281,284],{},[286,287,288,301,316,326,334,342],"tbody",{},[278,289,290,294],{},[291,292,293],"td",{},"портал",[291,295,296,297,300],{},"«коробка» Битрикс24 или БУС, главный модуль ",[250,298,299],{},"22.600.300"," и выше",[278,302,303,306],{},[291,304,305],{},"PHP",[291,307,308,311,312],{},[250,309,310],{},"8.2"," и выше, расширение ",[313,314,315],"code",{},"mbstring",[278,317,318,321],{},[291,319,320],{},"кодировка",[291,322,323],{},[250,324,325],{},"только UTF-8",[278,327,328,331],{},[291,329,330],{},"доступ",[291,332,333],{},"администратор портала и доступ к файлам по ssh или ftp",[278,335,336,339],{},[291,337,338],{},"если входа нет",[291,340,341],{},"четыре шага проходятся из CLI, см. раздел ниже",[278,343,344,347],{},[291,345,346],{},"архив",[291,348,349,350],{},"со страницы релиза либо собранный ",[313,351,352],{},".\u002Fbuild.sh",[244,354,355,356,359],{},"Для сценария «обновление» дополнительно нужен стенд, где уже стоит версия\n",[250,357,358],{},"2.x"," — именно на нём проверяется то, ради чего 3.0.0 сделана мажорной.",[267,361,363],{"id":362},"перед-началом","Перед началом",[244,365,366,369],{},[250,367,368],{},"Снимите копию каталога модуля и дамп таблицы настроек."," Шаги с удалением\nнеобратимы, а сравнивать «было \u002F стало» иначе не с чем.",[371,372,376],"pre",{"className":373,"code":374,"language":375,"meta":105,"style":105},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","cp -a \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fmodules\u002Fshef.options \u002Ftmp\u002Fshef.options.before\nmysqldump -u… portal b_option --where=\"MODULE_ID='shef.options'\" > \u002Ftmp\u002Fopt.before.sql\n","bash",[313,377,378,398],{"__ignoreMap":105},[379,380,383,387,391,395],"span",{"class":381,"line":382},"line",1,[379,384,386],{"class":385},"sbgvK","cp",[379,388,390],{"class":389},"stzsN"," -a",[379,392,394],{"class":393},"s_sjI"," \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fmodules\u002Fshef.options",[379,396,397],{"class":393}," \u002Ftmp\u002Fshef.options.before\n",[379,399,401,404,407,410,413,416,420,423,425,429],{"class":381,"line":400},2,[379,402,403],{"class":385},"mysqldump",[379,405,406],{"class":389}," -u…",[379,408,409],{"class":393}," portal",[379,411,412],{"class":393}," b_option",[379,414,415],{"class":389}," --where=",[379,417,419],{"class":418},"sjJ54","\"",[379,421,422],{"class":393},"MODULE_ID='shef.options'",[379,424,419],{"class":418},[379,426,428],{"class":427},"smGrS"," >",[379,430,431],{"class":393}," \u002Ftmp\u002Fopt.before.sql\n",[244,433,434],{},"Запишите, что лежит в публичных каталогах до установки — это пригодится на\nшаге удаления:",[371,436,438],{"className":373,"code":437,"language":375,"meta":105,"style":105},"ls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fcss\u002F \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002F | sort > \u002Ftmp\u002Fpublic.before\n",[313,439,440],{"__ignoreMap":105},[379,441,442,445,448,451,454,457,459],{"class":381,"line":382},[379,443,444],{"class":385},"ls",[379,446,447],{"class":393}," \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fcss\u002F",[379,449,450],{"class":393}," \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002F",[379,452,453],{"class":427}," |",[379,455,456],{"class":385}," sort",[379,458,428],{"class":427},[379,460,461],{"class":393}," \u002Ftmp\u002Fpublic.before\n",[267,463,465],{"id":464},"_0-архив-тот-самый","0. Архив — тот самый",[244,467,468,469,472],{},"Сверять не с константой из этого документа, а со своей сборкой из того же\nтега: архив собирается ",[250,470,471],{},"побайтово одинаково"," у всех, кто взял этот коммит.",[371,474,476],{"className":373,"code":475,"language":375,"meta":105,"style":105},"git clone https:\u002F\u002Fgithub.com\u002Fbx-shef\u002Foptions.git\ncd options && git checkout \u003Cтег проверяемой версии>\n.\u002Fbuild.sh                       # последняя строка напечатает sha256\nsha256sum \u002Fпуть\u002Fк\u002Fскачанному\u002Fshef.options.zip\n",[313,477,478,489,527,536],{"__ignoreMap":105},[379,479,480,483,486],{"class":381,"line":382},[379,481,482],{"class":385},"git",[379,484,485],{"class":393}," clone",[379,487,488],{"class":393}," https:\u002F\u002Fgithub.com\u002Fbx-shef\u002Foptions.git\n",[379,490,491,495,498,502,505,508,511,514,517,520,524],{"class":381,"line":400},[379,492,494],{"class":493},"sptTA","cd",[379,496,497],{"class":393}," options",[379,499,501],{"class":500},"sP7_E"," &&",[379,503,504],{"class":385}," git",[379,506,507],{"class":393}," checkout",[379,509,510],{"class":427}," \u003C",[379,512,513],{"class":393},"тег",[379,515,516],{"class":393}," проверяемой",[379,518,519],{"class":393}," верси",[379,521,523],{"class":522},"su5hD","и",[379,525,526],{"class":427},">\n",[379,528,530,532],{"class":381,"line":529},3,[379,531,352],{"class":385},[379,533,535],{"class":534},"sutJx","                       # последняя строка напечатает sha256\n",[379,537,539,542],{"class":381,"line":538},4,[379,540,541],{"class":385},"sha256sum",[379,543,544],{"class":393}," \u002Fпуть\u002Fк\u002Fскачанному\u002Fshef.options.zip\n",[244,546,547],{},"Хеши обязаны совпасть. Не сошлось — не ставьте: проверять поведение сборки,\nкоторая неизвестно откуда, бессмысленно.",[244,549,550,553,554,557],{},[250,551,552],{},"У выпусков 2.3.0, 3.0.0 и 3.0.1 сверять не с чем."," Воспроизводимость появилась\nвместе с нормализацией времени, прав и порядка записей в ",[313,555,556],{},"build_archive",", а\nэти три архива собраны раньше и несут внутри время того клона, из которого их\nсобирали. Их хеш пересборкой не повторить — это свойство тех архивов, а не\nпризнак подмены.",[244,559,560,561,564],{},"Первым уровнем внутри архива обязан быть каталог ",[313,562,563],{},"shef.options\u002F",":",[371,566,568],{"className":373,"code":567,"language":375,"meta":105,"style":105},"unzip -Z1 shef.options.zip | cut -d\u002F -f1 | sort -u   # ровно одна строка\n",[313,569,570],{"__ignoreMap":105},[379,571,572,575,578,581,583,586,589,592,594,596,599],{"class":381,"line":382},[379,573,574],{"class":385},"unzip",[379,576,577],{"class":389}," -Z1",[379,579,580],{"class":393}," shef.options.zip",[379,582,453],{"class":427},[379,584,585],{"class":385}," cut",[379,587,588],{"class":389}," -d\u002F",[379,590,591],{"class":389}," -f1",[379,593,453],{"class":427},[379,595,456],{"class":385},[379,597,598],{"class":389}," -u",[379,600,601],{"class":534},"   # ровно одна строка\n",[267,603,605],{"id":604},"если-входа-в-админку-нет","Если входа в админку нет",[244,607,608],{},"Четыре шага — A, C, D и F — сделаны в расчёте на административный раздел.\nКапча, чужой стенд, отсутствие пароля — и четыре пункта из десяти встают\nцеликом.",[244,610,611,612,615,616,619],{},"Запасной путь есть, и он измерен: страница настроек — это файл\n",[313,613,614],{},"bitrix\u002Fmodules\u002Fshef.options\u002Foptions.php",", тот же самый, который подключает\n",[313,617,618],{},"\u002Fbitrix\u002Fadmin\u002Fsettings.php",". Подняв пролог из CLI, авторизовавшись\nадминистратором и подключив этот файл с буферизацией вывода, вы получаете тот\nже html. На стенде с ядром 26.700.0 оба прохода — из CLI и через настоящую\nадминку — дали одно и то же.",[244,621,622],{},"Порядок такой:",[624,625,626,638,648,659],"ol",{},[627,628,629,630,633,634,637],"li",{},"подключить ",[313,631,632],{},"bitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_before.php",", задав\n",[313,635,636],{},"$_SERVER['DOCUMENT_ROOT']",";",[627,639,640,641,644,645,637],{},"авторизоваться администратором — права модуля читаются через\n",[313,642,643],{},"GetGroupRight()",", без входа он вернёт ",[313,646,647],{},"D",[627,649,650,651,654,655,658],{},"задать ",[313,652,653],{},"$mid = 'shef.options'"," — ",[313,656,657],{},"options.php"," ждёт его глобальной;",[627,660,629,661,663,664,667],{},[313,662,657],{}," с ",[313,665,666],{},"ob_start()"," и разобрать полученный html.",[244,669,670,673],{},[250,671,672],{},"Что этим проверяется:"," состав вкладок и опций, текст подписей, отсутствие\nвкладки «Документация», права пользователей.",[244,675,676,679,680,683],{},[250,677,678],{},"Что не проверяется:"," отрисовка в админке, применение стилей, сохранение\nчерез форму (POST с ",[313,681,682],{},"sessid","), кнопки установки и удаления. Эти пункты либо\nпроходятся с входом, либо честно отмечаются в бланке как непройденные.",[244,685,686,687,690,691,694,695,265],{},"Отдельно: состав настроек можно получить и без отрисовки — ",[313,688,689],{},"options_conf.php","\nвозвращает массив ",[313,692,693],{},"\\Shef\\Options\\Main\\Options\\Tab",", если перед этим\nподключён модуль и ",[313,696,697],{},"optionsconfig.php",[267,699,701],{"id":700},"a-чистая-установка","A. Чистая установка",[624,703,704,714],{},[627,705,706,707,710,711,265],{},"Распаковать в ",[313,708,709],{},"bitrix\u002Fmodules\u002F",", чтобы получилось\n",[313,712,713],{},"bitrix\u002Fmodules\u002Fshef.options\u002F",[627,715,716,717,720],{},"Административный раздел → ",[250,718,719],{},"Marketplace → Установленные решения"," →\nпоставить модуль.",[244,722,723,726],{},[250,724,725],{},"Ожидается:"," установка проходит, ошибок нет, модуль появился в списке с\nрусским названием и описанием.",[244,728,729,732],{},[250,730,731],{},"Если не так:"," снимите текст ошибки целиком. Самые частые причины — не та\nверсия PHP (текст скажет, какая нужна и какая есть) и портал не в UTF-8.",[267,734,736],{"id":735},"b-обновление-с-2x-главный-сценарий-300","B. Обновление с 2.x — главный сценарий 3.0.0",[244,738,739],{},"Делается на стенде, где уже работает 2.x.",[624,741,742],{},[627,743,744],{},"Запомнить, что было:",[371,746,748],{"className":373,"code":747,"language":375,"meta":105,"style":105},"ls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002Fshef-options\u002F 2>\u002Fdev\u002Fnull   # в 2.x каталог есть\n",[313,749,750],{"__ignoreMap":105},[379,751,752,754,757,760,763],{"class":381,"line":382},[379,753,444],{"class":385},[379,755,756],{"class":393}," \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002Fshef-options\u002F",[379,758,759],{"class":427}," 2>",[379,761,762],{"class":393},"\u002Fdev\u002Fnull",[379,764,765],{"class":534},"   # в 2.x каталог есть\n",[624,767,768,771],{"start":400},[627,769,770],{},"Заменить каталог модуля содержимым новой версии.",[627,772,773,774,265],{},"Открыть ",[313,775,776],{},"\u002Fbitrix\u002Fadmin\u002Fsettings.php?mid=shef.options",[244,778,779],{},[250,780,725],{},[782,783,784,787,794,801],"ul",{},[627,785,786],{},"страница открывается;",[627,788,789,790,793],{},"вкладка ",[250,791,792],{},"одна"," — «Общие». Вкладки «Документация» больше нет, и это не\nполомка: markdown-блок убран из модуля целиком, документация живёт в\nрепозитории;",[627,795,796,797,800],{},"ранее сохранённое значение «Служебный пользователь» ",[250,798,799],{},"на месте"," — имя\nнастройки не менялось;",[627,802,803],{},"в логе портала нет ошибок вида «class not found».",[244,805,806,809],{},[250,807,808],{},"Если вкладка «Документация» осталась"," — заменился не весь каталог модуля.\nУберите каталог целиком и распакуйте заново.",[244,811,812,819],{},[250,813,814,815,818],{},"Каталог ",[313,816,817],{},"\u002Fbitrix\u002Fjs\u002Fshef-options\u002F"," после обновления останется"," — это\nнормально: новая версия туда ничего не кладёт, а убирает его деинсталляция,\nсм. шаг F.",[267,821,823],{"id":822},"c-страница-настроек","C. Страница настроек",[244,825,826],{},[313,827,776],{},[244,829,830,831,835],{},"Входа в админку нет — см. ",[258,832,834],{"href":833},"#%D0%B5%D1%81%D0%BB%D0%B8-%D0%B2%D1%85%D0%BE%D0%B4%D0%B0-%D0%B2-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD%D0%BA%D1%83-%D0%BD%D0%B5%D1%82","«Если входа в админку нет»",":\nсостав вкладок и подписи проверяются отрисовкой из CLI, сохранение через\nформу — нет.",[244,837,838,840],{},[250,839,725],{}," вкладка «Общие», на ней одно поле — «Служебный пользователь»\nс описанием «Пользователь с правами администратора, которого не уволят».\nБольше на вкладке ничего нет.",[244,842,843,846],{},[250,844,845],{},"Жёлтого предупреждения про хранение свойств каталога быть не должно"," — оно\nубрано в 3.0.2. Осталось на стенде, обновлённом с версии ниже, — заменился\nне весь каталог модуля.",[244,848,849],{},"Дальше:",[624,851,852,855],{},[627,853,854],{},"Выбрать пользователя, сохранить, перезайти на страницу — значение на месте.",[627,856,857,858,861],{},"Зайти под сотрудником ",[250,859,860],{},"без прав"," на модуль — страница не должна\nоткрыться.",[267,863,865],{"id":864},"d-фронт-и-права-на-файлы","D. Фронт и права на файлы",[272,867,868,878],{},[275,869,870],{},[278,871,872,875],{},[281,873,874],{},"адрес",[281,876,877],{},"ожидается",[286,879,880,893],{},[278,881,882,887],{},[291,883,884],{},[313,885,886],{},"\u002Fbitrix\u002Fcss\u002Fshef.options\u002Fadmin-options.css",[291,888,889,892],{},[250,890,891],{},"200",", отдаётся содержимое",[278,894,895,900],{},[291,896,897],{},[313,898,899],{},"\u002Fbitrix\u002Fmodules\u002Fshef.options\u002Finstall\u002Fcss\u002Fshef.options\u002Fadmin-options.css",[291,901,902],{},[250,903,904],{},"403",[244,906,907,908,911,912,915],{},"Второе — не придирка: в поставке nginx закрывает ",[313,909,910],{},"\u002Fbitrix\u002Fmodules\u002F",", и\nпоэтому фронт раскладывается установщиком в ",[313,913,914],{},"\u002Fbitrix\u002Fcss",". Если каталог\nмодуля отдаётся браузером, на портале неверная конфигурация веб-сервера, и\nэто стоит починить раньше, чем модуль.",[244,917,918,919,922],{},"Стили на странице настроек применились. Если нет, а css отдаётся — это кеш:\nCtrl+F5 либо сброс автокеширования в настройках главного модуля. Путь вида\n",[313,920,921],{},"\u002Fbitrix\u002Fcache\u002Fjs\u002Fs1\u002F..."," в консоли браузера означает, что вы смотрите на кеш.",[267,924,926],{"id":925},"e-разбор-настройки-то-что-чинили-в-300","E. Разбор настройки — то, что чинили в 3.0.0",[244,928,929,932,933,936],{},[313,930,931],{},"\\Shef\\Options\\Main\\Constants::getSystemUserId()"," раньше приводил значение\nчерез ",[313,934,935],{},"(int)",", и опечатка в настройке молча выдавала права не тому\nпользователю. Проверяется так:",[624,938,939,942],{},[627,940,941],{},"Очистить поле «Служебный пользователь», сохранить.",[627,943,944],{},"Выполнить в консоли портала (или в тестовом скрипте под прологом):",[371,946,950],{"className":947,"code":948,"language":949,"meta":105,"style":105},"language-php shiki shiki-themes material-theme-lighter github-light github-dark","echo \\Shef\\Options\\Main\\Constants::getSystemUserId();\n","php",[313,951,952],{"__ignoreMap":105},[379,953,954],{"class":381,"line":382},[379,955,948],{},[244,957,958,964,965,968],{},[250,959,960,961],{},"Ожидается ",[313,962,963],{},"1"," — умолчание, а не ",[313,966,967],{},"0",". Ноль означал бы работу «от имени\nникого».",[267,970,972],{"id":971},"f-удаление","F. Удаление",[624,974,975,978],{},[627,976,977],{},"Административный раздел → удалить модуль.",[627,979,980],{},"Сравнить публичные каталоги:",[371,982,984],{"className":373,"code":983,"language":375,"meta":105,"style":105},"ls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fcss\u002F \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002F | sort > \u002Ftmp\u002Fpublic.after\ndiff \u002Ftmp\u002Fpublic.before \u002Ftmp\u002Fpublic.after\n",[313,985,986,1003],{"__ignoreMap":105},[379,987,988,990,992,994,996,998,1000],{"class":381,"line":382},[379,989,444],{"class":385},[379,991,447],{"class":393},[379,993,450],{"class":393},[379,995,453],{"class":427},[379,997,456],{"class":385},[379,999,428],{"class":427},[379,1001,1002],{"class":393}," \u002Ftmp\u002Fpublic.after\n",[379,1004,1005,1008,1011],{"class":381,"line":400},[379,1006,1007],{"class":385},"diff",[379,1009,1010],{"class":393}," \u002Ftmp\u002Fpublic.before",[379,1012,1002],{"class":393},[244,1014,1015],{},[250,1016,725],{},[782,1018,1019,1025,1035],{},[627,1020,1021,1024],{},[313,1022,1023],{},"\u002Fbitrix\u002Fcss\u002Fshef.options"," удалён;",[627,1026,1027,1030,1031,1034],{},[313,1028,1029],{},"\u002Fbitrix\u002Fjs\u002Fshef-options"," удалён — ",[250,1032,1033],{},"в том числе на стенде, обновлённом с\n2.x",", где этот каталог остался от прежней версии;",[627,1036,1037,654,1040,1042],{},[250,1038,1039],{},"чужие файлы и каталоги на месте",[313,1041,1007],{}," не должен показать ничего,\nкроме двух этих строк.",[624,1044,1045],{"start":529},[627,1046,1047],{},"Проверить, что настройки ушли вместе с модулем:",[371,1049,1053],{"className":1050,"code":1051,"language":1052,"meta":105,"style":105},"language-sql shiki shiki-themes material-theme-lighter github-light github-dark","SELECT * FROM b_option WHERE MODULE_ID = 'shef.options';   -- строк быть не должно\n","sql",[313,1054,1055],{"__ignoreMap":105},[379,1056,1057],{"class":381,"line":382},[379,1058,1051],{},[244,1060,1061],{},"Настройки стираются с 3.0.2. На стенде, где до удаления стояла версия ниже,\nстроки могли остаться от прежней установки — это не сбой текущего удаления.",[244,1063,1064,1065,1067,1068,1071],{},"Отдельно: если на портале стоит другой модуль линейки, зависящий от\n",[313,1066,70],{},", удаление должно ",[250,1069,1070],{},"отказаться"," и назвать этот модуль.",[244,1073,1074,1075,1078,1079,1082,1083,1085,1086,1088,1089,1092],{},"Зависимого модуля на стенде может не оказаться, и тогда шаг молча\nпропускается. Воспроизводится он так: у любого соседнего модуля временно\nдописать в ",[313,1076,1077],{},".settings.php"," ",[313,1080,1081],{},"'requireModules' => ['shef.options']",", попробовать\nснять ",[313,1084,70],{},", затем вернуть ",[313,1087,1077],{}," как было и ",[250,1090,1091],{},"сверить md5"," —\nиначе легко оставить чужой модуль поправленным.",[244,1094,1095,1096,1099,1100,1103],{},"Текст отказа из CLI не перехватить: ",[313,1097,1098],{},"ShowForm()"," заканчивается ",[313,1101,1102],{},"die()",", и\nбуфер теряется. Сам факт отказа виден по тому, что модуль остался\nустановленным.",[267,1105,1107],{"id":1106},"g-установка-через-composer","G. Установка через Composer",[244,1109,1110],{},"На проекте с Composer:",[371,1112,1114],{"className":373,"code":1113,"language":375,"meta":105,"style":105},"composer require bxshef\u002Foptions\n",[313,1115,1116],{"__ignoreMap":105},[379,1117,1118,1121,1124],{"class":381,"line":382},[379,1119,1120],{"class":385},"composer",[379,1122,1123],{"class":393}," require",[379,1125,1126],{"class":393}," bxshef\u002Foptions\n",[244,1128,1129,1131,1132,265],{},[250,1130,725],{}," модуль развернулся в ",[313,1133,713],{},[244,1135,1136,1078,1139,1142,1143,1078,1146,265],{},[250,1137,1138],{},"Не в",[313,1140,1141],{},"vendor\u002Fbxshef\u002Foptions\u002F"," и ",[250,1144,1145],{},"не в",[313,1147,1148],{},"bitrix\u002Fmodules\u002Fbxshef.options\u002F",[244,1150,1151,1152,1155,1156,1159,1160,1163],{},"Легло в ",[313,1153,1154],{},"vendor\u002F"," — на проекте не разрешён плагин ",[313,1157,1158],{},"composer\u002Finstallers",".\nВ неинтерактивном режиме Composer 2.2+ его не спрашивает, а молча пропускает.\nЛечится в корневом ",[313,1161,1162],{},"composer.json"," проекта:",[371,1165,1169],{"className":1166,"code":1167,"language":1168,"meta":105,"style":105},"language-json shiki shiki-themes material-theme-lighter github-light github-dark","{\n    \"config\": {\n        \"allow-plugins\": {\n            \"composer\u002Finstallers\": true\n        }\n    }\n}\n","json",[313,1170,1171,1176,1193,1208,1223,1229,1235],{"__ignoreMap":105},[379,1172,1173],{"class":381,"line":382},[379,1174,1175],{"class":500},"{\n",[379,1177,1178,1182,1186,1188,1190],{"class":381,"line":400},[379,1179,1181],{"class":1180},"s39Yj","    \"",[379,1183,1185],{"class":1184},"sseR_","config",[379,1187,419],{"class":1180},[379,1189,564],{"class":500},[379,1191,1192],{"class":500}," {\n",[379,1194,1195,1198,1202,1204,1206],{"class":381,"line":529},[379,1196,1197],{"class":1180},"        \"",[379,1199,1201],{"class":1200},"sZMiF","allow-plugins",[379,1203,419],{"class":1180},[379,1205,564],{"class":500},[379,1207,1192],{"class":500},[379,1209,1210,1213,1216,1218,1220],{"class":381,"line":538},[379,1211,1212],{"class":1180},"            \"",[379,1214,1158],{"class":1215},"srdBf",[379,1217,419],{"class":1180},[379,1219,564],{"class":500},[379,1221,1222],{"class":1180}," true\n",[379,1224,1226],{"class":381,"line":1225},5,[379,1227,1228],{"class":500},"        }\n",[379,1230,1232],{"class":381,"line":1231},6,[379,1233,1234],{"class":500},"    }\n",[379,1236,1238],{"class":381,"line":1237},7,[379,1239,1240],{"class":500},"}\n",[267,1242,1244],{"id":1243},"h-примеры","H. Примеры",[244,1246,1247,1248,1251],{},"Примеры из репозитория запускаются ",[250,1249,1250],{},"на самом портале"," — это не отдельная\nпесочница, а тот же код, что вы напишете у себя.",[371,1253,1255],{"className":373,"code":1254,"language":375,"meta":105,"style":105},"cd \u002Fпуть\u002Fк\u002Fрепозиторию\u002Foptions\nDOCUMENT_ROOT=\u002Fvar\u002Fwww\u002Fportal php examples\u002Fpid.php\n",[313,1256,1257,1264],{"__ignoreMap":105},[379,1258,1259,1261],{"class":381,"line":382},[379,1260,494],{"class":493},[379,1262,1263],{"class":393}," \u002Fпуть\u002Fк\u002Fрепозиторию\u002Foptions\n",[379,1265,1266,1269,1272,1275,1278],{"class":381,"line":400},[379,1267,1268],{"class":522},"DOCUMENT_ROOT",[379,1270,1271],{"class":427},"=",[379,1273,1274],{"class":393},"\u002Fvar\u002Fwww\u002Fportal",[379,1276,1277],{"class":385}," php",[379,1279,1280],{"class":393}," examples\u002Fpid.php\n",[244,1282,1283,1285,1286,1289,1290,1293,1294,1297,1298,265],{},[250,1284,725],{}," первая строка кончается ",[313,1287,1288],{},"[портал]",", дальше все строки ",[313,1291,1292],{},"ok",",\nпоследняя — ",[313,1295,1296],{},"ГОТОВО: pid",", код возврата ",[313,1299,967],{},[782,1301,1302,1314,1320],{},[627,1303,1304,1307,1308,1310,1311,637],{},[313,1305,1306],{},"[заглушки]"," вместо ",[313,1309,1288],{}," — не нашёлся\n",[313,1312,1313],{},"\u003CDOCUMENT_ROOT>\u002Fbitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_before.php",[627,1315,1316,1319],{},[313,1317,1318],{},"Модуль shef.options не установлен"," — модуль распакован, но не установлен из\nадминистративного раздела;",[627,1321,1322,1323,1326],{},"любая строка ",[313,1324,1325],{},"FAIL"," — расхождение кода с тем, что обещает пример. Это\nнаходка, а не шум: присылайте вывод целиком.",[244,1328,1329,1332,1333,1336,1337,1142,1340,1343,1344,1347,1348,1351,1352,1355],{},[313,1330,1331],{},"pid.php"," проверять обязательно: в нём правка ",[313,1334,1335],{},"\\Shef\\Options\\Main\\TempFile\\Pid",",\nкоторую заглушками до конца не проверить — живость процесса выясняется по\n",[313,1338,1339],{},"\u002Fproc",[313,1341,1342],{},"posix_kill",", а каталог и права на портале настоящие. Файлы он\nпишет во временный каталог портала (",[313,1345,1346],{},"upload\u002Ftmp\u002Fshef.options\u002Fexample-pid",") и\nза собой убирает; сигналов живым процессам не шлёт. ",[250,1349,1350],{},"Пустой каталог группы\nостаётся"," — так и задумано, файлы убирает ",[313,1353,1354],{},"remove()",", каталог не его дело.",[244,1357,1358,1359,1362],{},"Пример печатает, чем на этом стенде выясняется живость процесса: строка «Это\nокружение: \u002Fproc …, ext-posix …». Если нет ни того, ни другого, шаг «убран\nровно один файл» упадёт — и это не поломка модуля, а свойство окружения:\n",[313,1360,1361],{},"clearDir()"," в таком случае не удаляет ничего намеренно.",[244,1364,1365,1366,1368,1369,1372],{},"В контейнере есть отдельная ловушка: ",[313,1367,1339],{}," показывает процессы ",[250,1370,1371],{},"своего","\nконтейнера. Если временный каталог портала лежит на томе, общем с другим\nконтейнером, чужие живые блокировки выглядят мёртвыми и будут удалены. На\nодном контейнере это не бьёт.",[244,1374,1375],{},"Остальные четыре примера работают только с памятью процесса и на портале\nничего не меняют — их можно прогнать разом:",[371,1377,1379],{"className":373,"code":1378,"language":375,"meta":105,"style":105},"for f in examples\u002F*.php; do\n    [ \"$(basename \"$f\")\" = '_bootstrap.php' ] && continue\n    DOCUMENT_ROOT=\u002Fvar\u002Fwww\u002Fportal php \"$f\" > \u002Fdev\u002Fnull || echo \"провал: $f\"\ndone\n",[313,1380,1381,1401,1441,1479],{"__ignoreMap":105},[379,1382,1383,1387,1390,1393,1396,1398],{"class":381,"line":382},[379,1384,1386],{"class":1385},"sVHd0","for",[379,1388,1389],{"class":522}," f ",[379,1391,1392],{"class":1385},"in",[379,1394,1395],{"class":393}," examples\u002F*.php",[379,1397,637],{"class":500},[379,1399,1400],{"class":1385}," do\n",[379,1402,1403,1406,1409,1412,1415,1418,1421,1424,1427,1430,1433,1436,1438],{"class":381,"line":400},[379,1404,1405],{"class":500},"    [",[379,1407,1408],{"class":418}," \"$(",[379,1410,1411],{"class":385},"basename",[379,1413,1414],{"class":418}," \"",[379,1416,1417],{"class":522},"$f",[379,1419,1420],{"class":418},"\")\"",[379,1422,1423],{"class":427}," =",[379,1425,1426],{"class":418}," '",[379,1428,1429],{"class":393},"_bootstrap.php",[379,1431,1432],{"class":418},"'",[379,1434,1435],{"class":500}," ]",[379,1437,501],{"class":500},[379,1439,1440],{"class":1385}," continue\n",[379,1442,1443,1446,1448,1450,1452,1454,1456,1458,1460,1463,1466,1469,1471,1474,1476],{"class":381,"line":529},[379,1444,1445],{"class":522},"    DOCUMENT_ROOT",[379,1447,1271],{"class":427},[379,1449,1274],{"class":393},[379,1451,1277],{"class":385},[379,1453,1414],{"class":418},[379,1455,1417],{"class":522},[379,1457,419],{"class":418},[379,1459,428],{"class":427},[379,1461,1462],{"class":393}," \u002Fdev\u002Fnull",[379,1464,1465],{"class":427}," ||",[379,1467,1468],{"class":493}," echo",[379,1470,1414],{"class":418},[379,1472,1473],{"class":393},"провал: ",[379,1475,1417],{"class":522},[379,1477,1478],{"class":418},"\"\n",[379,1480,1481],{"class":381,"line":538},[379,1482,1483],{"class":1385},"done\n",[267,1485,1487],{"id":1486},"i-отказы-установки-если-есть-куда","I. Отказы установки — если есть куда",[244,1489,1490],{},"Два сценария требуют отдельных стендов, и если их нет, шаг пропускается\nосознанно, а не «забылся». Ниже сказано, когда «пропущено» — единственно\nвозможный ответ.",[244,1492,1493,1496,1497,1499],{},[250,1494,1495],{},"Портал в CP1251."," Установка должна ",[250,1498,1070],{}," с текстом «Модуль\nпоставляется в кодировке UTF-8…», а не поставиться наполовину и выдать мусор\nвместо русского текста.",[244,1501,1502,1503,1506,1507,1510,1511,1514,1515,1518],{},"На современных ядрах этот сценарий ",[250,1504,1505],{},"недостижим в принципе",": установщик\nспрашивает ",[313,1508,1509],{},"\\Bitrix\\Main\\Application::isUtfMode()",", а в main 26.700.0 этот\nметод возвращает ",[313,1512,1513],{},"true"," без условий — CP1251 платформой больше не\nподдерживается. Форсирование ",[313,1516,1517],{},"BX_UTF"," ничего не меняет, метод его не читает.\nВетка отказа при этом остаётся нужной: на ядре, где CP1251 ещё жив, она\nсработает. Отмечайте «пропущено, ядро 26.x» — искать, что вы сделали не так,\nне нужно.",[244,1520,1521,1524,1525,1528,1529,1532],{},[250,1522,1523],{},"PHP ниже 8.2."," Отказ с текстом «Для модуля требуется версия PHP выше\n8.2.0. Ваша версия …». Порог задан в ",[313,1526,1527],{},"install\u002Findex.php",", свойство\n",[313,1530,1531],{},"$PHP_MIN_VER",", — берите оттуда, а не отсюда.",[244,1534,1535,1536,1539,1540,564],{},"Образа Битрикса с PHP 8.1 не существует, а на голом ",[313,1537,1538],{},"php:8.1-cli"," пролог не\nподнять, поэтому установку целиком воспроизвести обычно негде. Частичная\nзамена — прогнать на настоящем 8.1 ровно то сравнение, которое делает\n",[313,1541,1542],{},"DoInstall()",[371,1544,1546],{"className":373,"code":1545,"language":375,"meta":105,"style":105},"php -r 'echo var_export(version_compare(PHP_VERSION, \"8.2.0\", \"\u003C\"), true), PHP_EOL;'\n# на 8.1 ожидается true  → установка откажется\n# на 8.2 ожидается false → установка продолжится\n",[313,1547,1548,1563,1568],{"__ignoreMap":105},[379,1549,1550,1552,1555,1557,1560],{"class":381,"line":382},[379,1551,949],{"class":385},[379,1553,1554],{"class":389}," -r",[379,1556,1426],{"class":418},[379,1558,1559],{"class":393},"echo var_export(version_compare(PHP_VERSION, \"8.2.0\", \"\u003C\"), true), PHP_EOL;",[379,1561,1562],{"class":418},"'\n",[379,1564,1565],{"class":381,"line":400},[379,1566,1567],{"class":534},"# на 8.1 ожидается true  → установка откажется\n",[379,1569,1570],{"class":381,"line":529},[379,1571,1572],{"class":534},"# на 8.2 ожидается false → установка продолжится\n",[244,1574,1575],{},"Это проверяет решение, но не саму установку. В бланке — «частично».",[267,1577,1579],{"id":1578},"если-что-то-не-сошлось","Если что-то не сошлось",[244,1581,1582],{},"Соберите сразу, одним сообщением:",[624,1584,1585,1588,1591,1604,1611,1616],{},[627,1586,1587],{},"что делали — номер шага отсюда;",[627,1589,1590],{},"что ожидали и что получили;",[627,1592,1593,1594,1597,1598,1600,1601,637],{},"версии: ",[313,1595,1596],{},"php -v",", версия главного модуля, версия ",[313,1599,70],{}," из\n",[313,1602,1603],{},"install\u002Fversion.php",[627,1605,1606,1607,1610],{},"текст ошибки ",[250,1608,1609],{},"целиком",", включая путь и строку;",[627,1612,1613,1614,637],{},"для шага H — весь вывод примера, не только строку ",[313,1615,1325],{},[627,1617,1618,1619,1622],{},"хвост ",[313,1620,1621],{},"bitrix\u002Fphp_interface\u002Flog.txt",", если портал в него пишет.",[244,1624,1625],{},"Без пунктов 3 и 4 разбирать нечего: одна и та же жалоба на разных версиях\nядра означает разные причины.",[267,1627,1629],{"id":1628},"бланк-результата","Бланк результата",[371,1631,1636],{"className":1632,"code":1634,"language":1635},[1633],"language-text","Стенд: ______________  Ядро: __________  PHP: ______  Кодировка: ______\nВерсия модуля: ______  sha256 архива сошёлся: да \u002F нет \u002F нечем (выпуск собран до воспроизводимой сборки)\nШаги A, C, D, F пройдены: через админку \u002F отрисовкой из CLI \u002F и так и так\n\n0 архив ................ [ ]      F удаление ............... [ ]\nA чистая установка ..... [ ]      G Composer ............... [ ]\nB обновление с 2.x ..... [ ]      H примеры ................ [ ]\nC страница настроек .... [ ]      I отказы установки ....... [ ] \u002F пропущено\nD фронт и права ........ [ ]\nE разбор настройки ..... [ ]      Проверил: ______________  Дата: ______\n","text",[313,1637,1634],{"__ignoreMap":105},[1639,1640],"hr",{},[244,1642,1643,1646,1647,1646,1650],{},[258,1644,1645],{"href":71},"↑ Содержание"," | ",[258,1648,1649],{"href":83},"Сборка и релиз",[258,1651,1652],{"href":88},"Структура",[1654,1655,1656],"note",{},[244,1657,1658,1659,1665],{},"Источник: ",[258,1660,1664],{"href":1661,"rel":1662},"https:\u002F\u002Fgithub.com\u002Fbx-shef\u002Foptions\u002Fblob\u002Fmain\u002Fdocs\u002Fportal-check.md",[1663],"nofollow","options\u002Fdocs\u002Fportal-check.md"," — правки туда, сайт пересобирается сам.",[1667,1668,1669],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}",{"title":105,"searchDepth":529,"depth":529,"links":1671},[1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686],{"id":269,"depth":400,"text":270},{"id":362,"depth":400,"text":363},{"id":464,"depth":400,"text":465},{"id":604,"depth":400,"text":605},{"id":700,"depth":400,"text":701},{"id":735,"depth":400,"text":736},{"id":822,"depth":400,"text":823},{"id":864,"depth":400,"text":865},{"id":925,"depth":400,"text":926},{"id":971,"depth":400,"text":972},{"id":1106,"depth":400,"text":1107},{"id":1243,"depth":400,"text":1244},{"id":1486,"depth":400,"text":1487},{"id":1578,"depth":400,"text":1579},{"id":1628,"depth":400,"text":1629},"md",{},true,"---\ntitle: \"Проверка на портале\"\n---\n\nВсё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, кеш,\nраскладка файлов, поведение при обновлении. Проверять это приходится руками —\nи лучше по списку, потому что забытый шаг находит не разработчик, а клиент.\n\nПроцедура рассчитана на **отдельный стенд**, а не на боевой портал. Шаги\n«удалить модуль» и «поставить на CP1251» на рабочем портале делать нельзя.\n\nРаскладка репозитория — в [module-structure.md](\u002Fmodules\u002Foptions\u002Fmodule-structure), сборка и\nрелиз — в [build-and-install.md](\u002Fmodules\u002Foptions\u002Fbuild-and-install).\n\n## Что понадобится\n\n| | |\n|---|---|\n| портал | «коробка» Битрикс24 или БУС, главный модуль **22.600.300** и выше |\n| PHP | **8.2** и выше, расширение `mbstring` |\n| кодировка | **только UTF-8** |\n| доступ | администратор портала и доступ к файлам по ssh или ftp |\n| если входа нет | четыре шага проходятся из CLI, см. раздел ниже |\n| архив | со страницы релиза либо собранный `.\u002Fbuild.sh` |\n\nДля сценария «обновление» дополнительно нужен стенд, где уже стоит версия\n**2.x** — именно на нём проверяется то, ради чего 3.0.0 сделана мажорной.\n\n## Перед началом\n\n**Снимите копию каталога модуля и дамп таблицы настроек.** Шаги с удалением\nнеобратимы, а сравнивать «было \u002F стало» иначе не с чем.\n\n```bash\ncp -a \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fmodules\u002Fshef.options \u002Ftmp\u002Fshef.options.before\nmysqldump -u… portal b_option --where=\"MODULE_ID='shef.options'\" > \u002Ftmp\u002Fopt.before.sql\n```\n\nЗапишите, что лежит в публичных каталогах до установки — это пригодится на\nшаге удаления:\n\n```bash\nls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fcss\u002F \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002F | sort > \u002Ftmp\u002Fpublic.before\n```\n\n## 0. Архив — тот самый\n\nСверять не с константой из этого документа, а со своей сборкой из того же\nтега: архив собирается **побайтово одинаково** у всех, кто взял этот коммит.\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fbx-shef\u002Foptions.git\ncd options && git checkout \u003Cтег проверяемой версии>\n.\u002Fbuild.sh                       # последняя строка напечатает sha256\nsha256sum \u002Fпуть\u002Fк\u002Fскачанному\u002Fshef.options.zip\n```\n\nХеши обязаны совпасть. Не сошлось — не ставьте: проверять поведение сборки,\nкоторая неизвестно откуда, бессмысленно.\n\n**У выпусков 2.3.0, 3.0.0 и 3.0.1 сверять не с чем.** Воспроизводимость появилась\nвместе с нормализацией времени, прав и порядка записей в `build_archive`, а\nэти три архива собраны раньше и несут внутри время того клона, из которого их\nсобирали. Их хеш пересборкой не повторить — это свойство тех архивов, а не\nпризнак подмены.\n\nПервым уровнем внутри архива обязан быть каталог `shef.options\u002F`:\n\n```bash\nunzip -Z1 shef.options.zip | cut -d\u002F -f1 | sort -u   # ровно одна строка\n```\n\n## Если входа в админку нет\n\nЧетыре шага — A, C, D и F — сделаны в расчёте на административный раздел.\nКапча, чужой стенд, отсутствие пароля — и четыре пункта из десяти встают\nцеликом.\n\nЗапасной путь есть, и он измерен: страница настроек — это файл\n`bitrix\u002Fmodules\u002Fshef.options\u002Foptions.php`, тот же самый, который подключает\n`\u002Fbitrix\u002Fadmin\u002Fsettings.php`. Подняв пролог из CLI, авторизовавшись\nадминистратором и подключив этот файл с буферизацией вывода, вы получаете тот\nже html. На стенде с ядром 26.700.0 оба прохода — из CLI и через настоящую\nадминку — дали одно и то же.\n\nПорядок такой:\n\n1. подключить `bitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_before.php`, задав\n   `$_SERVER['DOCUMENT_ROOT']`;\n2. авторизоваться администратором — права модуля читаются через\n   `GetGroupRight()`, без входа он вернёт `D`;\n3. задать `$mid = 'shef.options'` — `options.php` ждёт его глобальной;\n4. подключить `options.php` с `ob_start()` и разобрать полученный html.\n\n**Что этим проверяется:** состав вкладок и опций, текст подписей, отсутствие\nвкладки «Документация», права пользователей.\n\n**Что не проверяется:** отрисовка в админке, применение стилей, сохранение\nчерез форму (POST с `sessid`), кнопки установки и удаления. Эти пункты либо\nпроходятся с входом, либо честно отмечаются в бланке как непройденные.\n\nОтдельно: состав настроек можно получить и без отрисовки — `options_conf.php`\nвозвращает массив `\\Shef\\Options\\Main\\Options\\Tab`, если перед этим\nподключён модуль и `optionsconfig.php`.\n\n## A. Чистая установка\n\n1. Распаковать в `bitrix\u002Fmodules\u002F`, чтобы получилось\n   `bitrix\u002Fmodules\u002Fshef.options\u002F`.\n2. Административный раздел → **Marketplace → Установленные решения** →\n   поставить модуль.\n\n**Ожидается:** установка проходит, ошибок нет, модуль появился в списке с\nрусским названием и описанием.\n\n**Если не так:** снимите текст ошибки целиком. Самые частые причины — не та\nверсия PHP (текст скажет, какая нужна и какая есть) и портал не в UTF-8.\n\n## B. Обновление с 2.x — главный сценарий 3.0.0\n\nДелается на стенде, где уже работает 2.x.\n\n1. Запомнить, что было:\n\n```bash\nls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002Fshef-options\u002F 2>\u002Fdev\u002Fnull   # в 2.x каталог есть\n```\n\n2. Заменить каталог модуля содержимым новой версии.\n3. Открыть `\u002Fbitrix\u002Fadmin\u002Fsettings.php?mid=shef.options`.\n\n**Ожидается:**\n\n* страница открывается;\n* вкладка **одна** — «Общие». Вкладки «Документация» больше нет, и это не\n  поломка: markdown-блок убран из модуля целиком, документация живёт в\n  репозитории;\n* ранее сохранённое значение «Служебный пользователь» **на месте** — имя\n  настройки не менялось;\n* в логе портала нет ошибок вида «class not found».\n\n**Если вкладка «Документация» осталась** — заменился не весь каталог модуля.\nУберите каталог целиком и распакуйте заново.\n\n**Каталог `\u002Fbitrix\u002Fjs\u002Fshef-options\u002F` после обновления останется** — это\nнормально: новая версия туда ничего не кладёт, а убирает его деинсталляция,\nсм. шаг F.\n\n## C. Страница настроек\n\n`\u002Fbitrix\u002Fadmin\u002Fsettings.php?mid=shef.options`\n\nВхода в админку нет — см. [«Если входа в админку нет»](#если-входа-в-админку-нет):\nсостав вкладок и подписи проверяются отрисовкой из CLI, сохранение через\nформу — нет.\n\n**Ожидается:** вкладка «Общие», на ней одно поле — «Служебный пользователь»\nс описанием «Пользователь с правами администратора, которого не уволят».\nБольше на вкладке ничего нет.\n\n**Жёлтого предупреждения про хранение свойств каталога быть не должно** — оно\nубрано в 3.0.2. Осталось на стенде, обновлённом с версии ниже, — заменился\nне весь каталог модуля.\n\nДальше:\n\n1. Выбрать пользователя, сохранить, перезайти на страницу — значение на месте.\n2. Зайти под сотрудником **без прав** на модуль — страница не должна\n   открыться.\n\n## D. Фронт и права на файлы\n\n| адрес | ожидается |\n|---|---|\n| `\u002Fbitrix\u002Fcss\u002Fshef.options\u002Fadmin-options.css` | **200**, отдаётся содержимое |\n| `\u002Fbitrix\u002Fmodules\u002Fshef.options\u002Finstall\u002Fcss\u002Fshef.options\u002Fadmin-options.css` | **403** |\n\nВторое — не придирка: в поставке nginx закрывает `\u002Fbitrix\u002Fmodules\u002F`, и\nпоэтому фронт раскладывается установщиком в `\u002Fbitrix\u002Fcss`. Если каталог\nмодуля отдаётся браузером, на портале неверная конфигурация веб-сервера, и\nэто стоит починить раньше, чем модуль.\n\nСтили на странице настроек применились. Если нет, а css отдаётся — это кеш:\nCtrl+F5 либо сброс автокеширования в настройках главного модуля. Путь вида\n`\u002Fbitrix\u002Fcache\u002Fjs\u002Fs1\u002F...` в консоли браузера означает, что вы смотрите на кеш.\n\n## E. Разбор настройки — то, что чинили в 3.0.0\n\n`\\Shef\\Options\\Main\\Constants::getSystemUserId()` раньше приводил значение\nчерез `(int)`, и опечатка в настройке молча выдавала права не тому\nпользователю. Проверяется так:\n\n1. Очистить поле «Служебный пользователь», сохранить.\n2. Выполнить в консоли портала (или в тестовом скрипте под прологом):\n\n```php\necho \\Shef\\Options\\Main\\Constants::getSystemUserId();\n```\n\n**Ожидается `1`** — умолчание, а не `0`. Ноль означал бы работу «от имени\nникого».\n\n## F. Удаление\n\n1. Административный раздел → удалить модуль.\n2. Сравнить публичные каталоги:\n\n```bash\nls \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fcss\u002F \u002Fvar\u002Fwww\u002Fportal\u002Fbitrix\u002Fjs\u002F | sort > \u002Ftmp\u002Fpublic.after\ndiff \u002Ftmp\u002Fpublic.before \u002Ftmp\u002Fpublic.after\n```\n\n**Ожидается:**\n\n* `\u002Fbitrix\u002Fcss\u002Fshef.options` удалён;\n* `\u002Fbitrix\u002Fjs\u002Fshef-options` удалён — **в том числе на стенде, обновлённом с\n  2.x**, где этот каталог остался от прежней версии;\n* **чужие файлы и каталоги на месте** — `diff` не должен показать ничего,\n  кроме двух этих строк.\n\n3. Проверить, что настройки ушли вместе с модулем:\n\n```sql\nSELECT * FROM b_option WHERE MODULE_ID = 'shef.options';   -- строк быть не должно\n```\n\nНастройки стираются с 3.0.2. На стенде, где до удаления стояла версия ниже,\nстроки могли остаться от прежней установки — это не сбой текущего удаления.\n\nОтдельно: если на портале стоит другой модуль линейки, зависящий от\n`shef.options`, удаление должно **отказаться** и назвать этот модуль.\n\nЗависимого модуля на стенде может не оказаться, и тогда шаг молча\nпропускается. Воспроизводится он так: у любого соседнего модуля временно\nдописать в `.settings.php` `'requireModules' => ['shef.options']`, попробовать\nснять `shef.options`, затем вернуть `.settings.php` как было и **сверить md5** —\nиначе легко оставить чужой модуль поправленным.\n\nТекст отказа из CLI не перехватить: `ShowForm()` заканчивается `die()`, и\nбуфер теряется. Сам факт отказа виден по тому, что модуль остался\nустановленным.\n\n## G. Установка через Composer\n\nНа проекте с Composer:\n\n```bash\ncomposer require bxshef\u002Foptions\n```\n\n**Ожидается:** модуль развернулся в `bitrix\u002Fmodules\u002Fshef.options\u002F`.\n\n**Не в** `vendor\u002Fbxshef\u002Foptions\u002F` и **не в** `bitrix\u002Fmodules\u002Fbxshef.options\u002F`.\n\nЛегло в `vendor\u002F` — на проекте не разрешён плагин `composer\u002Finstallers`.\nВ неинтерактивном режиме Composer 2.2+ его не спрашивает, а молча пропускает.\nЛечится в корневом `composer.json` проекта:\n\n```json\n{\n\t\"config\": {\n\t\t\"allow-plugins\": {\n\t\t\t\"composer\u002Finstallers\": true\n\t\t}\n\t}\n}\n```\n\n## H. Примеры\n\nПримеры из репозитория запускаются **на самом портале** — это не отдельная\nпесочница, а тот же код, что вы напишете у себя.\n\n```bash\ncd \u002Fпуть\u002Fк\u002Fрепозиторию\u002Foptions\nDOCUMENT_ROOT=\u002Fvar\u002Fwww\u002Fportal php examples\u002Fpid.php\n```\n\n**Ожидается:** первая строка кончается `[портал]`, дальше все строки `ok`,\nпоследняя — `ГОТОВО: pid`, код возврата `0`.\n\n* `[заглушки]` вместо `[портал]` — не нашёлся\n  `\u003CDOCUMENT_ROOT>\u002Fbitrix\u002Fmodules\u002Fmain\u002Finclude\u002Fprolog_before.php`;\n* `Модуль shef.options не установлен` — модуль распакован, но не установлен из\n  административного раздела;\n* любая строка `FAIL` — расхождение кода с тем, что обещает пример. Это\n  находка, а не шум: присылайте вывод целиком.\n\n`pid.php` проверять обязательно: в нём правка `\\Shef\\Options\\Main\\TempFile\\Pid`,\nкоторую заглушками до конца не проверить — живость процесса выясняется по\n`\u002Fproc` и `posix_kill`, а каталог и права на портале настоящие. Файлы он\nпишет во временный каталог портала (`upload\u002Ftmp\u002Fshef.options\u002Fexample-pid`) и\nза собой убирает; сигналов живым процессам не шлёт. **Пустой каталог группы\nостаётся** — так и задумано, файлы убирает `remove()`, каталог не его дело.\n\nПример печатает, чем на этом стенде выясняется живость процесса: строка «Это\nокружение: \u002Fproc …, ext-posix …». Если нет ни того, ни другого, шаг «убран\nровно один файл» упадёт — и это не поломка модуля, а свойство окружения:\n`clearDir()` в таком случае не удаляет ничего намеренно.\n\nВ контейнере есть отдельная ловушка: `\u002Fproc` показывает процессы **своего**\nконтейнера. Если временный каталог портала лежит на томе, общем с другим\nконтейнером, чужие живые блокировки выглядят мёртвыми и будут удалены. На\nодном контейнере это не бьёт.\n\nОстальные четыре примера работают только с памятью процесса и на портале\nничего не меняют — их можно прогнать разом:\n\n```bash\nfor f in examples\u002F*.php; do\n\t[ \"$(basename \"$f\")\" = '_bootstrap.php' ] && continue\n\tDOCUMENT_ROOT=\u002Fvar\u002Fwww\u002Fportal php \"$f\" > \u002Fdev\u002Fnull || echo \"провал: $f\"\ndone\n```\n\n## I. Отказы установки — если есть куда\n\nДва сценария требуют отдельных стендов, и если их нет, шаг пропускается\nосознанно, а не «забылся». Ниже сказано, когда «пропущено» — единственно\nвозможный ответ.\n\n**Портал в CP1251.** Установка должна **отказаться** с текстом «Модуль\nпоставляется в кодировке UTF-8…», а не поставиться наполовину и выдать мусор\nвместо русского текста.\n\nНа современных ядрах этот сценарий **недостижим в принципе**: установщик\nспрашивает `\\Bitrix\\Main\\Application::isUtfMode()`, а в main 26.700.0 этот\nметод возвращает `true` без условий — CP1251 платформой больше не\nподдерживается. Форсирование `BX_UTF` ничего не меняет, метод его не читает.\nВетка отказа при этом остаётся нужной: на ядре, где CP1251 ещё жив, она\nсработает. Отмечайте «пропущено, ядро 26.x» — искать, что вы сделали не так,\nне нужно.\n\n**PHP ниже 8.2.** Отказ с текстом «Для модуля требуется версия PHP выше\n8.2.0. Ваша версия …». Порог задан в `install\u002Findex.php`, свойство\n`$PHP_MIN_VER`, — берите оттуда, а не отсюда.\n\nОбраза Битрикса с PHP 8.1 не существует, а на голом `php:8.1-cli` пролог не\nподнять, поэтому установку целиком воспроизвести обычно негде. Частичная\nзамена — прогнать на настоящем 8.1 ровно то сравнение, которое делает\n`DoInstall()`:\n\n```bash\nphp -r 'echo var_export(version_compare(PHP_VERSION, \"8.2.0\", \"\u003C\"), true), PHP_EOL;'\n# на 8.1 ожидается true  → установка откажется\n# на 8.2 ожидается false → установка продолжится\n```\n\nЭто проверяет решение, но не саму установку. В бланке — «частично».\n\n## Если что-то не сошлось\n\nСоберите сразу, одним сообщением:\n\n1. что делали — номер шага отсюда;\n2. что ожидали и что получили;\n3. версии: `php -v`, версия главного модуля, версия `shef.options` из\n   `install\u002Fversion.php`;\n4. текст ошибки **целиком**, включая путь и строку;\n5. для шага H — весь вывод примера, не только строку `FAIL`;\n6. хвост `bitrix\u002Fphp_interface\u002Flog.txt`, если портал в него пишет.\n\nБез пунктов 3 и 4 разбирать нечего: одна и та же жалоба на разных версиях\nядра означает разные причины.\n\n## Бланк результата\n\n```\nСтенд: ______________  Ядро: __________  PHP: ______  Кодировка: ______\nВерсия модуля: ______  sha256 архива сошёлся: да \u002F нет \u002F нечем (выпуск собран до воспроизводимой сборки)\nШаги A, C, D, F пройдены: через админку \u002F отрисовкой из CLI \u002F и так и так\n\n0 архив ................ [ ]      F удаление ............... [ ]\nA чистая установка ..... [ ]      G Composer ............... [ ]\nB обновление с 2.x ..... [ ]      H примеры ................ [ ]\nC страница настроек .... [ ]      I отказы установки ....... [ ] \u002F пропущено\nD фронт и права ........ [ ]\nE разбор настройки ..... [ ]      Проверил: ______________  Дата: ______\n```\n\n---\n\n[↑ Содержание](\u002Fmodules\u002Foptions) | [Сборка и релиз](\u002Fmodules\u002Foptions\u002Fbuild-and-install) | [Структура](\u002Fmodules\u002Foptions\u002Fmodule-structure)\n\n::note\nИсточник: [options\u002Fdocs\u002Fportal-check.md](https:\u002F\u002Fgithub.com\u002Fbx-shef\u002Foptions\u002Fblob\u002Fmain\u002Fdocs\u002Fportal-check.md) — правки туда, сайт пересобирается сам.\n::\n\n",{"title":92,"description":95},"gTClJbGtdHnd1sB1z5mGmJapB-Y1IOWwMpsoC5uHow0",[1694,1695],{"title":87,"path":88,"stem":89,"description":90,"children":-1},{"title":97,"path":98,"stem":99,"description":100,"children":-1},1790857269719]