-
Notifications
You must be signed in to change notification settings - Fork 96
Постоянный обмен с 1С — как избежать сброса кэша
Техническая реализация заключается в следующем:
Отменяем сброс кэша при импорте каталога и при редактировании элемента каталога. Для этого модифицируется файл bitrix\modules\main\classes\general\cache.php ядра Битрикс (меняем метод ClearByTag):
function ClearByTag($tag)
{
if (function_exists('isClearCacheDenied')){
$clearDenied = isClearCacheDenied();
}
else{
$clearDenied = false;
}
if(defined("BX_COMP_MANAGED_CACHE") && !$clearDenied)
{
// Можно включить логирование сброса по тегу инфоблока (в данном примере это iblock_id_41)
if ($tag == 'iblock_id_41'){
// \Bitrix\Main\Diag\Debug::writeToFile($tag, date('Y-m-d H:i:s ') . "Кэш сброшен с тегом", "/bitrix/tmp/Cache_ClearByTag.log");
}
$this->taggedCache->clearByTag($tag);
}
}
Пример определения функции для отмены сброса кэша:
function isClearCacheDenied () {
$requestUri = $_SERVER["REQUEST_URI"];
if (strpos($requestUri, "/bitrix/admin") !== false
&& (strpos($requestUri, "/bitrix/admin/1c_exchange") !== false || strpos($requestUri, "IBLOCK_ID=".IBLOCK_ID_CATALOG) !== false)
)
{
return true;
}
return false;
}
В шаблонах компонентов списка товаров и детальной страницы товара вместо значений цен подставляется шаблон #price-ITEM_ID#, где ITEM_ID это ID элемента инфоблока каталога товаров.
После формирования html-кода страницы по событию OnEndBufferContent шаблоны цен заменяются на актуальные цены из базы данных, с учетом скидок, конвертации валюты и прочего стандартного функционала Битрикс.
Пример замены шаблонов цен:
/**
* Замена шаблонов цен при выводе контента
*/
Main\EventManager::getInstance()->addEventHandler(
'main',
'OnEndBufferContent',
'replacePrices'
);
function replacePrices(&$content){
$bufferHandler = new BufferHandler($content);
$bufferHandler->replacePrices();
$content = $bufferHandler->content;
}
class BufferHandler{
public $content;
private $priceCode;
public function __construct($content)
{
\Bitrix\Main\Loader::IncludeModule('catalog');
$this->content = $content;
$data = catalogHelper::getCityData();
$this->priceCode = $data['PRICE'];
}
public function replacePrices()
{
$pattern = '/#price-([0-9]*)#/i';
$this->replacePattern($pattern);
$pattern = '/#price-discount-([0-9]*)#/i';
$this->replacePattern($pattern, true);
}
private function replacePattern($pattern, $isDiscount = false)
{
$arMatches = array();
$countMatches = preg_match_all($pattern, $this->content, $arMatches);
if ($countMatches > 0 && count($arMatches[1]) > 0) {
$arPriceCodes = array($this->priceCode);
$arResult["PRICES"] = CIBlockPriceTools::GetCatalogPrices(CATALOG_ID, $arPriceCodes);
foreach($arResult["PRICES"] as &$value)
{
if (!$value['CAN_VIEW'] && !$value['CAN_BUY'])
continue;
$arSelect[] = $value["SELECT"];
}
$arOrder = array();
$arFilter = array('IBLOCK_ID' => CATALOG_ID, 'ID' => $arMatches[1]);
$arSelectFields = array("ID", "IBLOCK_ID");
$arSelectFields = array_merge($arSelectFields, $arSelect);
$rsElements = CIBlockElement::GetList($arOrder, $arFilter, FALSE, FALSE, $arSelectFields);
while($arItem = $rsElements->Fetch())
{
$arPrices = CIBlockPriceTools::GetItemPrices(CATALOG_ID, $arResult["PRICES"], $arItem);
$priceValue = $arPrices[$this->priceCode]['VALUE'];
$pricePrintValue = $arPrices[$this->priceCode]['PRINT_VALUE'];
$priceDiscountValue = $arPrices[$this->priceCode]['DISCOUNT_VALUE'];
$pricePrintDiscountValue = $arPrices[$this->priceCode]['PRINT_DISCOUNT_VALUE'];
$key = array_search($arItem['ID'], $arMatches[1]);
if ($isDiscount){
// Цена со скидкой
$this->content = str_replace($arMatches[0][$key], $pricePrintDiscountValue, $this->content);
}
else{
// Цена без скидки
$this->content = str_replace($arMatches[0][$key], $pricePrintValue, $this->content);
}
}
}
}
}
Для возможности ручного сброса кэша создается скрипт (/bitrix/admin/clear_catalog_cache.php), по обращению к которому сбрасывается кэш каталога товаров, без сброса кэша других инфоблоков. Доступ к скрипту должен быть только у авторизованных пользователей сайта с правами администратора.
Пример файла сброса кэша:
<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
$cache_manager = Bitrix\Main\Application::getInstance()->getTaggedCache();
$cache_manager->ClearByTag("iblock_id_".CATALOG_ID);
Welcome to the bitrix.exam2 wiki! Битрикс, подготовка к экзамену 2 https://github.com/donitz1609/bitrix.exam2