Skip to content

Instantly share code, notes, and snippets.

@ilyalazarev31
Created November 21, 2019 05:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilyalazarev31/a060092d5c1dbc001f4669e244f302f0 to your computer and use it in GitHub Desktop.
Save ilyalazarev31/a060092d5c1dbc001f4669e244f302f0 to your computer and use it in GitHub Desktop.
Функция получения минимальной цены раздела в SEO шаблонах {=minpricesection}

Функция получения минимальной цены раздела в SEO шаблонах

Image


  • init.d7.php - на d7 ядре версия, которая скорее всего не будет на < 17 версии работать. Но она быстрее в 4-7 раз,
  • init.php - знакомый CIBlockElement. Легче понять, все знакомое, но создает кучу запросов ненужных.

Примерные тесты:

Версия Кол-во запросов Время
d7 100 0.354429
old bitrix 100 2.833784
<?
/**
* Несмотря на сложность функции в отличии от старого ядра, эта функция работает в 4-7 раз быстрее!
* Парсер "{=minpricesection $id|null} минимальной цены товаров раздела"
* @param id - или указываем id раздеа или функция сама получает через \Bitrix\Iblock\Template\Entity\Base
* @param priceGroup - нужно указать какую цену запрашиваем. По дефолту базовая (1)
* @return string
*/
if (\Bitrix\Main\Loader::includeModule('iblock')) {
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
"iblock",
"OnTemplateGetFunctionClass",
["FunctionMinPriceSection", "eventHandler"]
);
//подключаем файл с определением класса FunctionBase
include_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/iblock/lib/template/functions/fabric.php");
class FunctionMinPriceSection extends \Bitrix\Iblock\Template\Functions\FunctionBase
{
//Обработчик события на вход получает имя требуемой функции
public static function eventHandler($event)
{
$parameters = $event->getParameters();
$functionName = $parameters[0];
if ($functionName === "minpricesection") {
//обработчик должен вернуть SUCCESS и имя класса
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
"\\FunctionMinPriceSection"
);
}
}
public function onPrepareParameters(\Bitrix\Iblock\Template\Entity\Base $entity, array $parameters)
{
$arguments = [];
// Перехватываем id элемента/раздела, чтобы можно было обращаться к его свойствам
$this->data['id'] = $entity->getId();
foreach ($parameters as $parameter) {
$arguments[] = $parameter->process($entity);
}
return $arguments;
}
//собственно функция выполняющая "магию"
public function calculate($parameters)
{
$priceGroup = '1'; // base or number
\Bitrix\Main\Loader::includeModule("catalog");
\Bitrix\Main\Loader::includeModule('currency');
$sectionID = (!empty(reset($parameters)) ? reset($parameters) : $this->data['id']);
// Получаем основной раздел
$section = \Bitrix\Iblock\SectionTable::getList([
'filter' => ['ID' => $sectionID],
'select' => ['LEFT_MARGIN', 'RIGHT_MARGIN', 'IBLOCK_ID', 'ID']
])->fetchRaw();
// Собираем все подразделы
$subSections = \Bitrix\Iblock\SectionTable::getList([
'filter' => [
'>=LEFT_MARGIN' => $section['LEFT_MARGIN'],
'<=RIGHT_MARGIN' => $section['RIGHT_MARGIN'],
'=IBLOCK_ID' => $section['IBLOCK_ID'],
],
'select' => ['ID']
]);
while ($section = $subSections->fetch()) {
$arSectionsID[] = $section['ID'];
}
// Составляем запрос для получения элементво привязанных к секциям
$elementSection = new Bitrix\Main\Entity\Query('\Bitrix\Iblock\SectionElementTable');
$elementSection->addSelect('IBLOCK_ELEMENT_ID')->setFilter(['=IBLOCK_SECTION_ID' => $arSectionsID])->registerRuntimeField(
'SECTION',
[
'data_type' => '\Bitrix\Iblock\SectionTable',
'reference' => [
'=this.IBLOCK_SECTION_ID' => 'ref.ID',
],
'join_type' => 'inner'
]
);
// Выполняем запрос
$resElementsID = \Bitrix\Main\Application::getConnection()->query($elementSection->getQuery());
while ($elementsID = $resElementsID->fetch()) {
$arElementsID[] = $elementsID['IBLOCK_ELEMENT_ID'];
}
$arItem = \Bitrix\Iblock\ElementTable::getList(
[
'filter' => ['=ID' => $arElementsID],
'order' => ['PriceTable.PRICE_SCALE' => 'asc'],
'select' => [
'PriceTable.PRICE_SCALE', // Сумма конвертируется в базовую валюту
],
'limit' => 1,
'runtime' => [
new \Bitrix\Main\Entity\ReferenceField(
'PriceTable',
\Bitrix\Catalog\PriceTable::class,
['=this.ID' => 'ref.PRODUCT_ID', $priceGroup => 'ref.CATALOG_GROUP_ID'],
['join_type' => 'RIGHT']
)
]
]
)->fetchRaw();
if (!empty($arItem)) {
// Получаем форматированную цену в базовой валюте
$minPriceSection = \CCurrencyLang::CurrencyFormat(reset($arItem), \Bitrix\Currency\CurrencyManager::getBaseCurrency());
}
return $minPriceSection;
}
}
}
<?
/**
* Парсер "{=minpricesection $id|null} минимальной цены товаров раздела"
* @param id - или указываем id раздеа или функция сама получает через \Bitrix\Iblock\Template\Entity\Base
* @param priceGroup - нужно указать какую цену запрашиваем. По дефолту базовая (1)
* @return string
*/
if (\Bitrix\Main\Loader::includeModule('iblock')) {
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
"iblock",
"OnTemplateGetFunctionClass",
["FunctionMinPriceSection", "eventHandler"]
);
//подключаем файл с определением класса FunctionBase
include_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/iblock/lib/template/functions/fabric.php");
class FunctionMinPriceSection extends \Bitrix\Iblock\Template\Functions\FunctionBase
{
//Обработчик события на вход получает имя требуемой функции
public static function eventHandler($event)
{
$parameters = $event->getParameters();
$functionName = $parameters[0];
if ($functionName === "minpricesection") {
//обработчик должен вернуть SUCCESS и имя класса
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
"\\FunctionMinPriceSection"
);
}
}
public function onPrepareParameters(\Bitrix\Iblock\Template\Entity\Base $entity, array $parameters)
{
$arguments = [];
// Перехватываем id элемента/раздела, чтобы можно было обращаться к его свойствам
$this->data['id'] = $entity->getId();
foreach ($parameters as $parameter) {
$arguments[] = $parameter->process($entity);
}
return $arguments;
}
//собственно функция выполняющая "магию"
public function calculate($parameters)
{
$priceGroup = '1';// base or number
$sectionID = (!empty(reset($parameters)) ? reset($parameters) : $this->data['id']);
$arItems = \CIBlockElement::GetList(["CATALOG_PRICE_{$priceGroup}" => "ASC"], ["SECTION_ID" => $sectionID, "ACTIVE" => "Y", 'INCLUDE_SUBSECTIONS' => 'Y']);
$item = $arItems->Fetch();
if (!empty($item)) {
$minPriceSection = \CCurrencyLang::CurrencyFormat((int) $item["CATALOG_PRICE_{$priceGroup}"], $item["CATALOG_CURRENCY_{$priceGroup}"], true);
}
return $minPriceSection;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment