Как сэкономить 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 в параметрах.Закажите консультацию — подберём оптимальное решение для вашего каталога.







