Почему не сбрасывается кеш при Автокешировании в собственных компонентах Битрикс

1С-Битрикс. Есть инфоблок. Задача: Вывести на страницу текст из свойства элемента.

Написал собственный компонент. Допустим так (укорочено для простоты):

// class.php
<?php
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

use Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__);

class ProductText extends CBitrixComponent
{
    public function executeComponent()
    {
        if($this->startResultCache()) {
        // или if($this->startResultCache($this->arParams['CACHE_TIME'], false, 'product.text/')) {

            if(!\Bitrix\Main\Loader::includeModule('iblock')) {
                $this->abortResultCache();
            }

            $iblock = \Bitrix\Iblock\Iblock::wakeUp($this->arParams['IBLOCK_ID']);
            $entity = $iblock->getEntityDataClass();

            $rs = $entity::getList(
                [
                    'filter' => $this->getFilter(),
                    'select' => $this->getSelect(),
                ],
            )->fetchObject();

            $this->arResult['ID'] = $rs->getId();
            $this->arResult['TEXT'] = $rs->getText() ? $rs->getText()->getValue() : '';

            if(empty($this->arResult)) {
                $this->abortResultCache();
            }
            
            $this->includeComponentTemplate();
        }
    }

    protected function getFilter() {...}
    protected function getSelect() {...}
}

Вызывается компонент просто:

$APPLICATION->IncludeComponent(
    "pppp:product.text", 
    ".default", 
    array(
        "IBLOCK_ID" => "9",
        "ID" => "46211",
        "COMPONENT_TEMPLATE" => ".default",
        "COMPOSITE_FRAME_MODE" => "A",
        "COMPOSITE_FRAME_TYPE" => "AUTO",
        "CACHE_TYPE" => "A",
        "CACHE_TIME" => "604800"
    ),
    false
);

Все работает, компилируется нужный шаблон с данными, кешируется, выводится;

Но если мы изменим название элемента инфоблока или значение в строковом свойстве элемента, то ничего не меняется, данные берутся из кеша. Только ручной сброс кеша помогает. Но хотелось бы автоматического...

Автокеширование включено, кеширование включено, композит выключен. Почему не срабатывает автоматический сброс кеша при Автокешировании?


Ответы (2 шт):

Автор решения: Виктор Карев

Автоматический сброс кэша не работает, потому что стандартные функции редактирования инфоблоков ничего не знают о вашем компоненте и его кэшах и не догадываются, что их нужно сбрасывать. Повесьте обработчик на события OnAfterIBlockElementAdd и OnAfterIBlockElementUpdate. Пусть он смотрит, не происходят ли изменения в вашем инфоблоке и при если да, то сбрасывает кэш.

→ Ссылка
Автор решения: Александр
$this->startResultCache()

После проверки старта кеша добавьте регистрацию тега для кеша (перед этим в админке необходимо включить управляемое кеширование, а в коде объявить глобальную переменную $CACHE_MANAGER).

if (defined("BX_COMP_MANAGED_CACHE")) {
    $CACHE_MANAGER->RegisterTag("iblock_id_{$this->arParams["IBLOCK_ID"]}");
}

Теперь кеш компонента будет сбрасываться автоматически после изменения инфоблока

Если нужно, чтобы сбрасывался кеш только при изменении конкретного элемента, то зарегистрируйте уникальный тэг для этого элемента по тому же принципу, как я показал выше, а через обработчики OnAfterIBlockElementUpdate, OnAfterIBlockElementAdd, OnAfterIBlockElementDelete сбрасывайте кеш

if (!defined("BX_COMP_MANAGED_CACHE")) {
    return true;
}

global $CACHE_MANAGER;
$CACHE_MANAGER->ClearByTag('my_element_tag');
→ Ссылка