Как сэкономить 90% времени менеджеров на массовых операциях в Битрикс
Менеджеру нужно обновить цены на 500 товаров — вручную это 4 часа работы. Стандартный список Битрикса даёт только пять действий: активировать, деактивировать, удалить, изменить раздел, экспорт. Кастомных операций нет. Мы реализуем массовые действия, которые экономят до 90% времени: обновление цен, наценок, свойств, синхронизация с 1С и маркетплейсами.
Наша команда занимается разработкой административных интерфейсов для Битрикс более 7 лет. За это время выполнено более 50 проектов, включая каталоги на 100 000+ товаров. Какие сценарии встречаются чаще всего? Массовое изменение цен (наценка/скидка), копирование свойств из одного товара в другой, генерация SEO-полей, обновление остатков по файлу или API. В этой статье разберём, как добавить кастомную кнопку в список элементов инфоблока, написать обработчик на PHP и защитить операцию от CSRF и ошибок. Окупаемость такой операции — несколько месяцев за счёт ускорения работы менеджеров в 10 раз.
Как добавить кастомное действие в контекстное меню?
Стандартный список инфоблока строится компонентом bitrix:iblock.admin.element.list. Для добавления новой кнопки не нужно редактировать системные файлы — используйте JavaScript-инъекцию или событие OnAdminListDisplay. JavaScript-инъекция в 3 раза быстрее в реализации, чем правка ядра, и не требует обновлений.
Пример: добавляем кнопку «Обновить цены» через JavaScript:
document.addEventListener('DOMContentLoaded', function () { var toolbar = document.querySelector('.adm-toolbar-panel'); if (!toolbar) return; var btn = document.createElement('input'); btn.type = 'button'; btn.value = 'Обновить цены'; btn.className = 'adm-btn'; btn.addEventListener('click', function () { var form = document.getElementById('list_form'); var action = document.createElement('input'); action.type = 'hidden'; action.name = 'action'; action.value = 'bulk_price_update'; var target = document.createElement('input'); target.type = 'hidden'; target.name = 'target_url'; target.value = '/bitrix/admin/my_bulk_price_update.php'; form.appendChild(action); form.appendChild(target); form.submit(); }); toolbar.appendChild(btn); }); Обработчик массовой операции на PHP
Файл /bitrix/admin/my_bulk_price_update.php — точка входа. Он получает ID выбранных элементов через $_REQUEST['ID'][], проверяет права и выполняет обновление.
<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php'; $APPLICATION->SetTitle('Массовое обновление цен'); // Проверить права if (!\Bitrix\Main\Engine\CurrentUser::get()->isAdmin()) { die('Access denied'); } $ids = array_map('intval', (array)$_REQUEST['ID']); $ids = array_filter($ids); require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_after.php'; if (!empty($ids) && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm'])) { // Выполнить операцию $markup = (float)$_POST['markup']; foreach (array_chunk($ids, 50) as $chunk) { foreach ($chunk as $id) { $purchase = getPurchasePrice($id); if ($purchase > 0) { updateRetailPrice($id, $purchase * (1 + $markup / 100)); } } } LocalRedirect('/bitrix/admin/iblock_list_admin.php?IBLOCK_ID=' . MY_CATALOG_IBLOCK_ID . '&lang=ru'); } ?> <!-- Форма подтверждения --> <form method="post" action=""> <p>Выбрано товаров: <b><?= count($ids) ?></b></p> <label>Наценка (%): <input type="number" name="markup" value="40" min="0" max="500"> </label> <?php foreach ($ids as $id): ?> <input type="hidden" name="ID[]" value="<?= $id ?>"> <?php endforeach; ?> <input type="hidden" name="confirm" value="Y"> <?= bitrix_sessid_post() ?> <input type="submit" value="Обновить" class="adm-btn-green"> <a href="javascript:history.back()" class="adm-btn">Отмена</a> </form> <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php'; ?> Почему важно проверять права доступа?
Массовые операции могут изменять тысячи записей. Без контроля доступа один неосторожный клик удалит половину каталога. В каждом обработчике мы обязательно:
- Проверяем CSRF-токен через
check_bitrix_sessid(). - Проверяем права администратора (
isAdmin()) или через систему ролей Битрикс. - Валидируем переданные ID: они должны принадлежать ожидаемому инфоблоку — защита от подстановки чужих элементов.
Согласно официальной документации 1С-Битрикс, CAdminContextMenu позволяет добавлять произвольные пункты меню без изменения ядра.
Сравнение способов добавления кнопок
| Способ | Сложность | Гибкость | Требует правки ядра |
|---|---|---|---|
| JavaScript-инъекция | Низкая | Высокая (любая кнопка) | Нет |
Событие OnAdminListDisplay |
Средняя | Средняя (через CAdminContextMenu) | Нет |
| Правка админ-файлов | Высокая | Высокая | Да (запрещено при обновлениях) |
Мы рекомендуем JavaScript-инъекцию — это быстро, не трогает ядро и легко адаптируется под разные сценарии.
Типовые операции и их сложность
| Тип операции | Время разработки | Количество строк кода | Пример |
|---|---|---|---|
| Обновление одного свойства | 3 дня | 50-100 | Задать размер для группы товаров |
| Наценка/скидка на основе цены закупки | 5 дней | 100-200 | Увеличить цену на 20% |
| Сложная логика с несколькими полями | 10 дней | 200-500 | Импорт из Excel с маппингом полей |
Прогресс-бар для длительных операций
При обработке 1000+ элементов без прогресса пользователь подумает, что сайт завис. Реализуем AJAX-паттерн: операция разбивается на шаги по 50–100 записей, каждый шаг — AJAX-запрос. Скрипт возвращает {processed: N, total: M}, JavaScript обновляет прогресс-бар и запускает следующий шаг. Очередь храним в $_SESSION или b_option по временному ключу. AJAX-паттерн с прогресс-баром в 10 раз удобнее для пользователя, чем ожидание без обратной связи.
Пример на JavaScript:
function processBatch(ids, stepSize, total) { var processed = 0; function next() { if (processed >= total) { alert('Готово'); return; } var batch = ids.slice(processed, processed + stepSize); BX.ajax.post('/bitrix/admin/ajax_bulk.php', { IDs: batch, sessid: BX.bitrix_sessid() }, function(res) { var data = JSON.parse(res); processed += data.batchSize; // Обновить прогресс-бар document.getElementById('progress').style.width = (processed / total * 100) + '%'; next(); }); } next(); } Что входит в работу
- Анализ — изучаем каталог, выявляем узкие места, фиксируем требования.
- Проектирование — определяем список операций, права доступа, схему данных.
- Реализация — пишем код с использованием ORM, JS-инъекций, серверных обработчиков.
- Тестирование — проверяем на копии каталога с 10 000+ элементов, имитируем нагрузку.
- Деплой — выкатываем на боевой сервер, настраиваем мониторинг.
- Гарантия — 6 месяцев бесплатной поддержки по зафиксированным багам.
Свяжитесь с нами для оценки вашего проекта — пришлём предварительный расчёт в течение одного рабочего дня.
Типичные ошибки при разработке массовых операций
- Игнорирование лимитов памяти. При обработке 50 000 товаров без разбивки на части скрипт упадёт с 500-й ошибкой. Всегда используйте пагинацию.
- Пропуск валидации ID. Если в массиве
$_REQUEST['ID']окажутся элементы другого инфоблока, операция может испортить данные. Проверяйте черезCIBlockElement::GetListс фильтром. - Отсутствие CSRF-защиты. Злоумышленник может подсунуть ссылку с параметрами и запустить нежелательное действие. Обязательно проверяйте sessid.
Подробнее о защите от CSRF
Битрикс использует sessid, который проверяется функцией check_bitrix_sessid(). Всегда включайте этот вызов в свои обработчики. При AJAX-запросах передавайте sessid в параметрах.Закажите консультацию — подберём оптимальное решение для вашего каталога.







