Разработка кастомного скрипта вместо готового плагина: подход и пример | IT-Gig

Когда плагин — не решение: инженерный подход к разработке скрипта под нестандартную бизнес-задачу

Частый запрос — «нужен калькулятор на сайт» или «нужно, чтобы при заказе данные улетали в наш сервис». Стандартный первый порыв — поставить готовый плагин из каталога. Для типовых задач это правильный путь. Но как только требование хоть немного отклоняется от коробочного сценария — своя формула расчёта, нестандартная интеграция, специфичная логика валидации — готовый плагин начинает сопротивляться, и его донастройка через фильтры и хуки занимает больше времени, чем написание узкого скрипта с нуля.

1. Когда плагин действительно не подходит

Три типичных сигнала: плагин перекрывает 20% нужной функциональности, но тянет за собой сотни ненужных настроек, вызовов скриптов и таблиц в базе данных, которые замедляют сайт; логика расчёта или бизнес-процесса специфична для заказчика и не укладывается в предустановленные сценарии плагина без взлома его внутреннего API; требуется интеграция с внутренним сервисом заказчика, для которого готового коннектора не существует в принципе. В этих случаях написание узкого скрипта под конкретную задачу в итоге обходится дешевле, чем месяцы подгонки чужого плагина под нетиповой сценарий.

2. Проектирование: разделение ответственности

Даже небольшой скрипт стоит проектировать с разделением на три слоя: интерфейс (JavaScript, отвечает только за ввод данных и отображение результата), бизнес-логика (PHP на стороне сервера, где происходит сам расчёт или обработка) и хранение (мета-поля записи или отдельная таблица в базе, если данных много). Смешивание расчётной логики прямо в JS-коде — частая ошибка: это не только небезопасно (любой пользователь может открыть консоль браузера и увидеть логику ценообразования или подменить результат перед отправкой), но и усложняет поддержку, если формулу нужно будет менять в будущем.

3. Пример: калькулятор стоимости на сайте услуг

Клиентская часть отправляет введённые пользователем параметры без перезагрузки страницы:

fetch(ajaxUrl, { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'action=it_gig_calc&area=' + area + '&complexity=' + complexity }).then(r => r.json()).then(data => { resultEl.textContent = data.price; });

Серверная часть в WordPress регистрируется через стандартный AJAX-хук и полностью владеет логикой расчёта, скрытой от клиента:

add_action('wp_ajax_it_gig_calc', 'it_gig_calc_handler'); add_action('wp_ajax_nopriv_it_gig_calc', 'it_gig_calc_handler'); function it_gig_calc_handler() { $area = floatval($_POST['area'] ?? 0); $complexity = sanitize_text_field($_POST['complexity'] ?? 'base'); $rate = $complexity === 'premium' ? 1500 : 900; wp_send_json(['price' => round($area * $rate)]); }

Такая архитектура позволяет менять формулу расчёта в одном месте на сервере, не трогая фронтенд, и не даёт возможности подменить итоговую цену на стороне клиента перед отправкой заявки.

4. Интеграция с внешними API

Когда скрипт должен передавать данные во внешний сервис (CRM, склад, платёжный шлюз), ключевой вопрос — что делать при недоступности этого сервиса. Прямой синхронный вызов API из обработчика формы означает, что временная недоступность стороннего сервиса приведёт к потере заявки клиента. Более надёжный паттерн — сначала сохранить заявку локально (в таблицу или как запись CPT), затем попытаться отправить во внешний сервис, и при неудаче поставить задачу в очередь на повтор через wp_schedule_single_event с экспоненциальной задержкой между попытками, вместо того чтобы полагаться на то, что внешний API ответит с первого раза.

5. Поддерживаемость важнее лаконичности

Скрипт, написанный «на один раз», обычно живёт на сайте годами. Поэтому даже для небольшого кастомного решения фиксирую: логирование ошибок в отдельный файл или таблицу (а не молчаливый @ перед функцией), понятные имена хуков и функций с префиксом проекта во избежание конфликтов с другими плагинами, и минимальное описание логики прямо в коде или отдельным файлом — чтобы через год, когда потребуется правка, не пришлось заново реверс-инжинирить собственное решение.

6. Частые ошибки при разработке кастомных скриптов

Отсутствие проверки прав доступа в AJAX-обработчике — самая распространённая уязвимость самописных скриптов. Хук wp_ajax_nopriv_*, открытый для неавторизованных пользователей, обязан валидировать и санитизировать каждое входящее значение так, будто оно заведомо враждебно — без этого через тот же публичный AJAX-эндпоинт, который считает цену калькулятора, злоумышленник может отправлять произвольные запросы и, в зависимости от логики обработчика, читать или изменять данные, для которых эндпоинт не предназначался.

Вторая ошибка — синхронный вызов внешнего API прямо в обработчике формы без таймаута. Если сторонний сервис отвечает медленно или зависает, PHP-процесс, обслуживающий запрос пользователя, будет ждать ответа до истечения max_execution_time, удерживая воркер PHP-FPM занятым — при нескольких одновременных заявках это может исчерпать пул воркеров и положить весь сайт, а не только форму с интеграцией.

Третья — хранение чувствительных ключей API прямо в коде темы, который потом случайно попадает в публичный репозиторий или передаётся другому подрядчику вместе с исходниками. Ключи и токены должны храниться в константах wp-config.php, которые не версионируются вместе с кодом темы, а не в файле, который увидит любой, получивший доступ к репозиторию.

Четвёртая — отсутствие идемпотентности при повторной отправке. Если пользователь дважды нажимает кнопку отправки формы из-за медленного ответа сервера, а обработчик не проверяет дубликаты, во внешнюю систему или в базу данных улетают две одинаковые заявки — на стороне отдела продаж это выглядит как ошибка сайта, даже если причина чисто клиентская.

Теги:

✕
[wp_chatgpt_assistant]
Скопировано!