Skip to content

Instantly share code, notes, and snippets.

@Isa3v
Last active March 26, 2019 13:51
Show Gist options
  • Save Isa3v/708da55277cbf29876c9056a63530314 to your computer and use it in GitHub Desktop.
Save Isa3v/708da55277cbf29876c9056a63530314 to your computer and use it in GitHub Desktop.
Сортировка элементов по польз. полю раздела (Bitrix, Cron)

Сортировка элементов по польз. полю раздела (Bitrix, Cron)

Задача:

У раздела добавить поле, под куски в названии товара, влияющие на его сортировку. Написать скрипт, который раз в день (часов в 7-8 утра) будет пробегаться по товарам и изменять их сортировку с 500 на 100 для товаров, начинающихся с этих фраз раздела. Можно привязать его к скрипту загрузки каталога.

Решение:

Добавляем скрипт например в ..bitrix/php_interface/ называм его sortByTag.php

У скрипта нужно поменять только 2 поля:

  • public $iblockID = 14; - маняем цифру на ID нужного инфоблока
  • public $nameUF = 'UF_SORTBYTAG'; - название пользовательского поля по которому будем сортировать.

В крон добавляем команду:

/usr/bin/php ПУТЬ ДО САЙТА/bitrix/php_interface/sortByTag.php >> ПУТЬ ДО САЙТА/bitrix/php_interface/sortByTag.log

После скрипт в выбранное время будет обновляться сортировка у нужных элеиментов, а у остальных сбрасываться до 500

<?
//Крон не читает глобальные переменные
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__) . "/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php";
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
@set_time_limit(0);
@ignore_user_abort(true);
//Подключаем инфоблоки. Но вроде и без этого работает.
Bitrix\Main\Loader::includeModule("iblock");
$startTime = microtime(true);
?>
<?/******************start CLASS**********************/?>
<?
class sortByUserField {
//ID инфоблока
public $iblockID = 14;
//Название польз. поля
public $nameUF = 'UF_SORTBYTAG';
//Получаем ID всех разделов инфоблока с польз полем
function getSections() {
//через SectionTable не выдаст польз. поля
$result = \Bitrix\Iblock\Model\Section::compileEntityByIblock($this->iblockID);
$result = $result::getList(array(
"select" => array($this->nameUF, "ID"),
'filter' => array('IBLOCK_ID' => $this->iblockID, '!=' . $this->nameUF => ''),
))->fetchAll();
return $result;
}
function getItems($sectionID) {
//Получаем все элементы раздела
$result = \Bitrix\Iblock\ElementTable::getList(array(
'select' => array('ID', 'NAME', 'SORT'),
'filter' => array(
'IBLOCK_ID' => $this->iblockID,
'IBLOCK_SECTION_ID' => $sectionID
),
))->fetchAll();
return $result;
}
//Получаем элементы раздела и фильтруем по тегу
function getByTag($arItem, $needle) {
//Удаляем лишние пробелы
$needle = trim($needle);
//Оставляем в результате только элементы начинающиеся на польз. поле
$query = '';
foreach ($arItem as $key => $value) {
if (!preg_match('/^' . $needle . '/', $arItem[$key]['NAME'])) {
unset($arItem[$key]);
}else{
if(next($arItem)){
$query .= $value['ID'].',';
}else{
$query .= $value['ID'];
}
}
}
$result['ITEMS'] = $arItem;
$result['QUERY'] = $query;
return $result;
}
}
?>
<?/********************end CLASS**********************/?>
<?/********************start UPDATE**********************/?>
<?
// Наш новый класс
$result = new sortByUserField;
//Получаем разделы инфоблока с поль. свойством
$arSections = $result->getSections();
global $DB;
$sqlQuery = '';
$countElementQuery = '';
foreach ($arSections as $key => $section) {
//Элементы:
$arItems = $result->getItems($section['ID']);
// Ищем по тегу:
$arItemsTag = $result->getByTag($arItems, $section[$result->nameUF])['QUERY'];
if(!empty($arItemsTag)){
//Запрос на сброс сортировки
$DB->Query("UPDATE `b_iblock_element` SET `SORT` = '500' WHERE `IBLOCK_ID` = ".$result->iblockID." AND `IBLOCK_SECTION_ID` = ".$section['ID']." AND `SORT` != 500". PHP_EOL);
//Запрос на установку сортировки
$DB->Query("UPDATE `b_iblock_element` SET `SORT` = '100' WHERE `IBLOCK_ID` = ".$result->iblockID." AND `IBLOCK_SECTION_ID` = ".$section['ID']." AND `ID` IN (".$arItemsTag.")". PHP_EOL);
}else{
$errors[] = 'В разделе '.$section['ID'].' Не найдено не одного элемента с "'. $section[$result->nameUF] . '" в названии' . PHP_EOL;
}
}
?>
<?/********************end UPDATE**********************/?>
<?/**********************DEBUG************************/?>
<?
echo "----------------------".date("Y-m-d")."--------------------------". PHP_EOL;
echo date("Y-m-d H:i:s") . ' - Время выполнения скрипта: ' . round(microtime(true) - $startTime, 4) . ' сек.'. PHP_EOL;
foreach ($errors as $error) {
echo '// WARNING: '.$error;
}
echo "-----------------------------------------------------------". PHP_EOL;
?>
<?/**********************DEBUG************************/?>
<?
require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_after.php";
?>
@Isa3v
Copy link
Author

Isa3v commented Mar 26, 2019

Update: Из за изменения запросов к API на запросы к БД время работы скрипта меньше 10 секунд. Потому можно использовать и без крона

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment