DarkRiDDeR10 мин

Bitrix API. Элемент есть в админке, но не виден в каталоге

BitrixPHPДиагностика

Знакомая картина: скрипт вернул ID, в админке новый товар есть, а на сайте его нет. Первый импульс — «почистить кеш». Иногда это действительно помогает, но чаще кеш просто оказывается первым подозреваемым, потому что его легко назвать. Давайте сначала отделим факт записи от публичной видимости и пройдём путь теми же условиями, которыми живёт каталог.

Постановка проблемы

Админка и публичный компонент редко показывают одинаковую выборку. Админка может отобразить неактивный элемент, а каталог фильтрует по ACTIVE, датам активности, разделу, правам, цене, наличию и проектным свойствам. Поэтому вопрос «почему элемент не виден?» нельзя решать одной командой. Нужен короткий список слоёв и доказательство на каждом. Цена ошибки — повторная загрузка товара или очистка кеша вместо исправления данных.

Полезно сразу сохранить два разных наблюдения: «запись читается по ID без ограничений» и «запись попадает в публичную выборку». Между ними могут стоять несколько независимых условий. Если журнал хранит только успешный ID, а не фильтр и результат контрольного запроса, следующему разработчику останется лишь гадать, какая граница исключила товар.

Дерево диагностики: от результата Add к условиям публичного каталога
Начинаем не с кеша, а с самого раннего условия, которое может исключить элемент из публичной выборки.

Проверяем по слоям

СлойЧто проверяемКак получить доказательство
ЗаписьAdd вернул ID, LAST_ERROR пустЛог результата и внешний ID операции
ИнфоблокACTIVE, даты, символьный код, разделКонтрольная выборка с теми же базовыми фильтрами
СвойстваОбязательная связь, SKU, картинка, проектные флагиЧтение конкретных свойств для созданного ID
КаталогЦена, остаток, доступность — если компонент их требуетПроверка конфигурации каталога и товарных параметров
Публичный путьФильтр компонента, права, кеш и индексПовтор сценария от имени нужного пользователя

Контрольный запрос вместо догадки

Документация CIBlockElement::GetList описывает фильтры ACTIVE, ACTIVE_DATE и выбор нужных полей. Ниже не универсальный каталоговый запрос, а диагностическая проба. Она отвечает на первый важный вопрос: проходит ли наш элемент хотя бы базовые условия публичной выдачи. Если нет — проблему надо искать в данных, а не в шаблоне.

<?php

const PRODUCT_IBLOCK_ID = 12;

$result = CIBlockElement::GetList(
    [],
    [
        "IBLOCK_ID" => PRODUCT_IBLOCK_ID,
        "=ID" => $elementId,
        "ACTIVE" => "Y",
        "ACTIVE_DATE" => "Y",
    ],
    false,
    ["nTopCount" => 1],
    ["ID", "IBLOCK_ID", "NAME", "CODE", "ACTIVE", "DATE_ACTIVE_FROM", "DATE_ACTIVE_TO"]
);

$row = $result->Fetch();
if ($row === false) {
    throw new RuntimeException("Элемент не проходит базовый публичный фильтр");
}

Где здесь каталог

Элемент инфоблока и товарная часть каталога — соседние, но разные уровни. Если публичный компонент требует цену, остаток или связь торгового предложения с товаром, одного CIBlockElement::Add недостаточно. Документация каталога отдельно описывает товарные параметры; в старом коде можно встретить CCatalogProduct::Add, но текущая документация помечает его устаревшим и рекомендует модель \Bitrix\Catalog\Model\Product. Для исторического проекта это не повод переписывать всё за вечер, а повод явно зафиксировать используемую версию API и не смешивать создание элемента с догадкой о его товарном состоянии.

Мини-матрица симптомов

СимптомСамая частая причинаБезопасное следующее действие
Нет IDОшибка обязательного поля, свойства или правВывести LAST_ERROR и входной внешний ID
ID есть, базовый GetList пустACTIVE, дата, инфоблок или неверный IDСначала читать поля элемента без публичных фильтров
GetList есть, карточки нетДополнительный фильтр компонента, раздел, права, URLСравнить фильтр и маршрут компонента с контрольной выборкой
Карточка есть, нельзя купитьНе настроены параметры каталога, цена или остатокПроверить товарный слой отдельно от инфоблока
После изменения появляется не сразуКеш или индексПодтвердить корректность данных и только затем адресно обновлять кеш/индекс

Почему не стоит начинать с очистки кеша

Потому что очистка кеша скрывает различие между двумя ситуациями: данные корректны, но слой кеширования устарел; или данные с самого начала не удовлетворяют фильтру. В первом случае нужна адресная стратегия инвалидирования. Во втором — очистка не решит проблему, а только добавит шума. Хорошая диагностика оставляет после себя не только исправленный товар, но и понимание, какое условие не было выполнено.

Чек-лист перед закрытием задачи

  1. Зафиксировать ID созданного элемента и внешний идентификатор операции.
  2. Считать элемент без публичных ограничений и проверить, что ожидаемые поля и свойства сохранены.
  3. Повторить контрольную выборку с ACTIVE и ACTIVE_DATE.
  4. Проверить условия конкретного компонента: раздел, права, проектные фильтры, URL.
  5. Если это товар — отдельно проверить цену, остаток и доступность, не смешивая этот слой с данными инфоблока.
  6. Только после этого проверять кеш и индекс; зафиксировать, какое именно действие обновляет их в данном проекте.

Проверяемые источники

Итог

Фраза «элемент есть в админке» говорит только о том, что одна запись сохранилась. Для каталога этого недостаточно. Если идти от ID к базовой выборке, от неё к товарному слою и только затем к кешу, причина обычно находится быстро. И самое приятное: на следующей похожей задаче уже не нужно вспоминать магическую кнопку очистки — есть нормальный порядок проверки.