Скрипт обновления свойства инфоблока
Для начала напишем скрипт, который будет обновлять значение свойства. Получаем ID элементов нужного инфоблока и, зная эти ID, определяем остатки товара на складах с ID 6 и 13. Если остатки есть, у элемента свойство "В наличии" обновляется на значение "Да". Если остатков нет — на "Нет".
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
$dbGoods = CIBlockElement::GetList(
false,
[
'IBLOCK_ID' => '4', // ID инфоблока
'ACTIVE' => 'Y' // Только активные
],
false,
false,
['ID']
);
while ($arGood = $dbGoods->Fetch()) {
$hasOnStore = 0; // Счетчик наличия
$storeRes = CCatalogStoreProduct::GetList(
false,
[
"PRODUCT_ID" => $arGood['ID'],
'STORE_ID' => [6, 13] // ID нужных складов
],
false,
false,
["AMOUNT"] // Нужно только количество
);
while ($arStoreParam = $storeRes->Fetch()) {
$hasOnStore += $arStoreParam['AMOUNT'];
}
$propertyValue = $hasOnStore > 0 ? 'Да' : 'Нет';
CIBlockElement::SetPropertyValues(
$arGood['ID'],
4, // ID инфоблока
$propertyValue, // Значение "Да" или "Нет"
'ATT_NAL_FIL' // Код нужного свойства
);
}
Запускаем этот скрипт в командной PHP-строке, проверяем его работоспособность и убедимся, что выполнение занимает меньше 10 минут.
Если скрипт отрабатывает долго, лучше не вешать его на агента, а запускать напрямую через crontab средствами сервера. В моем случае, при каталоге с более чем 60 000 товаров, скрипт выполняется за 20–30 секунд.
Создание агента в 1С-Битрикс
Сначала добавляем функцию агента в init.php (лучше через include_once отдельным файлом). Модуль инфоблоков подключать здесь не нужно. В моем случае агент будет называться (точнее, функция агента) UpdateAvPropAgent.
function UpdateAvPropAgent()
{
$dbGoods = CIBlockElement::GetList(
false,
[
'IBLOCK_ID' => '4',
'ACTIVE' => 'Y'
],
false,
false,
['ID']
);
while ($arGood = $dbGoods->Fetch()) {
$hasOnStore = 0;
$storeRes = CCatalogStoreProduct::GetList(
false,
[
"PRODUCT_ID" => $arGood['ID'],
'STORE_ID' => [6, 13]
],
false,
false,
["AMOUNT"]
);
while ($arStoreParam = $storeRes->Fetch()) {
$hasOnStore += $arStoreParam['AMOUNT'];
}
$propertyValue = $hasOnStore > 0 ? 'Да' : 'Нет';
CIBlockElement::SetPropertyValues(
$arGood['ID'],
4, // ID инфоблока
$propertyValue, // Значение "Да" или "Нет"
'ATT_NAL_FIL' // Код нужного свойства
);
}
return 'UpdateAvPropAgent();';
}
Далее идем в админку сайта: "Настройки → Настройки продукта → Агенты" и добавляем нового агента:
- Устанавливаем время следующего запуска (можно оставить пустым, но лучше указать что-то — поле перезапишется после ближайшего запуска агента).
- Отмечаем, что агент использует модуль "iblock".
- Вписываем функцию агента так же, как назвали её в
init.php:UpdateAvPropAgent();(обязательно с (); на конце). - Указываем интервал выполнения. На скриншоте показан запуск каждые 60 секунд, но это слишком часто — лучше раз в час (3600 секунд).
Активируем агента в командной PHP-строке:
CAgent::AddAgent("UpdateAvPropAgent();");
Важно: обязательно переведите выполнение всех агентов на cron, чтобы сайт не замедлялся из-за хитов пользователей.
Как не создавать хаос в init.php
Встречаются проекты, где init.php разрастается до 5000 строк и более. Небольшая рекомендация, чтобы этого избежать.
Рядом с этим файлом создайте отдельные директории handlers, agents, functions и т.д., и подключайте файлы из них. Пример:
$arrInitFiles = [
// АГЕНТЫ
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/agents/Говорящее_Название_Агента.php",
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/agents/Говорящее_Название_Агента2.php",
// ОБРАБОТЧИКИ
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/handlers/Говорящее_Название_Обработчика.php",
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/handlers/Говорящее_Название_Обработчика2.php",
// ФУНКЦИИ
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/functions/Говорящее_Название_Функции.php",
$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/functions/Говорящее_Название_Функции2.php"
];
foreach ($arrInitFiles as $initFile) {
if (file_exists($initFile)) {
include_once($initFile);
}
}
Внутри каждого подключаемого файла обязательно оставляйте подробные комментарии о том, что делает конкретный код и как он работает.