Перейти до основного вмісту

Адмін-профайлер (debug toolbar)

В ECMS9 є стандартний debug toolbar CodeIgniter 4 — SQL-запити з часом, таймери, пам'ять, завантажені в'юхи, збіглий роут, спрацьовані події — але підключений він так, що бачить його лише Адміністратор, який сам його увімкнув, на робочому сайті, у власному браузері, на 30 хвилин. Решта не отримує жодного байта дебаг-виводу.

Увімкнути і вимкнути

ДіяURL
Увімкнути для цього браузера (30 хв)/admin/profiler/enable
Вимкнути/admin/profiler/disable

Панель профайлера з відкритою вкладкою Database на сторінці адмінки

Обидва — звичайні GET-роути модуля Admin (Profiler::enable / Profiler::disable). Вони не зареєстровані в shop_rbac_privileges, тому за фолбеком адмін-фільтра доступні лише Адміністратору. Після виклику вас повертає на сторінку, з якої прийшли (враховується лише referer того самого хоста, інакше — на /admin).

Коли 30 хвилин минають, тулбар зникає сам — відкрийте /admin/profiler/enable ще раз. Якщо в .env немає encryption.key, увімкнення падає з повідомленням про помилку: куку нічим підписати.

Після увімкнення тулбар рендериться і в адмінці, і на вітрині, поки сесія адмінська. Саме тому це головний інструмент для розслідувань «чому ця категорія повільна» на живому сайті.

Як влаштований гейт

Мають бути відкриті два незалежні гейти:

  1. Гейт завантаження (app/Config/Boot/production.php). У production CI_DEBUG дорівнює false, тож нічого не збирається і детальні сторінки помилок ніколи не показуються. /admin/profiler/enable ставить куку cms9_profiler зі значенням <expiry>:<hmac>, де hmac = hash_hmac('sha256', 'profiler:<expiry>', key), а key — сирий рядок encryption.key з .env. На кожному запиті boot-файл перевіряє куку (формат, термін, підпис через hash_equals) і лише тоді визначає CI_DEBUG = true. Підроблена чи прострочена кука лишає сайт у звичайному production-режимі.
  2. Гейт рендеру (App\Filters\AdminDebugToolbar, зареєстрований як alias toolbar в app/Config/Filters.php). Він розширює штатний фільтр DebugToolbar і вставляє HTML тулбара лише коли service('auth')->isLoggedIn() && isAdmin(). Це покриває і дев-стенди, де CI_DEBUG увімкнено глобально: гість однаково нічого не бачить.

Гейт рендеру додатково шле X-LiteSpeed-Cache-Control: no-cache, щоб тулбар ніколи не потрапив у публічну кеш-копію.

Збір запитів — звичайний блок CI_DEBUG в app/Config/Events.php (слухач DBQuery + toolbar()->respond()); колектори налаштовані в app/Config/Toolbar.php (Timers, Database, Logs, Views, Files, Routes, Events; maxQueries = 1000, maxHistory = 20).

Чому сирий setcookie

Контролер ставить куку через PHP setcookie(), а не через CookieStore CI4 — відповідь redirect() губить куки CookieStore, і прапор ніколи не дійшов би до браузера. Майте це на увазі, якщо правите цей код.

Відомі граблі за проксі

  • Cloudflare Rocket Loader переписує type усіх <script>, і лоадер тулбара мовчки вмирає. Саме тому AdminDebugToolbar::after() додає data-cfasync="false" до тега скрипта debugbar_loader.
  • Кеш сторінок LiteSpeed віддає гостьову копію адміну: сторінка вітрини приходить з кешу, PHP не запускається, тулбара немає. Робочий фікс на таких хостах — правило в .htaccess, яке дає запитам із кукою cms9_profiler окремий ключ кешу (RewriteCond %{HTTP_COOKIE} cms9_profilerRewriteRule .* - [E=cache-vary:cms9_profiler]).

Безпека: що врахувати розробнику модуля

  • Не покладайтесь на те, що CI_DEBUG завжди false, щоб щось сховати: з кукою він true для запитів одного адміна. Вважайте його прапором на запит.
  • Не логуйте секрети через log_message() на рівнях info/debug — колектор Logs покаже їх у тулбарі тому, хто його увімкнув.
  • Пейлоад тулбара для важкої сторінки може сягати мегабайта; це очікувано і впливає лише на браузер самого адміна.