Стандартный компонент bitrix:catalog.section
из коробки показывает только элементы с ACTIVE = 'Y'
. Нужно, чтобы в публичном каталоге (или в админ-витрине) были видны и отключённые товары, например для страницы «Скоро в продаже» либо для внутренних проверок склада.

Почему товары с ACTIVE = 'N'
не попадают в выборку
В иерархии D7-компонентов фильтр собирается в методе
protected function getFilter()
у базового класса \Bitrix\Iblock\Component\ElementList
, от которого наследуется CatalogSectionComponent
. Там жёстко добавляется пара условий:
'ACTIVE' => 'Y',
'ACTIVE_DATE' => 'Y',
Поэтому все деактивированные элементы отсеиваются на уровне SQL и до шаблона не доходят.
Решение за один шаг: переопределяем только getFilter()
Раз компонент полностью классовый, нам не нужен component.php
. Достаточно создать собственный компонент-обёртку в /local/components
и подменить один-единственный метод.
/local/components/my_company/catalog.section.inactive/
└── class.php
Шаг 1. Копируем базовый класс
Скопируйте содержимое ядрового \bitrix\components\bitrix\catalog.section\class.php
целиком в class.php
новой папки — это гарантирует 100 % совместимость со всеми обновлениями тайп-хинтов и приватных свойств.
Если хотите минимализм, можно унаследоваться от ядрового класса и держать в файле только переопределённые методы. Ниже показана именно «короткая» версия.
<?php
use Bitrix\Main\Loader;
/**
* Расширенный catalog.section.
* Показывает активные и неактивные элементы.
*/
class CatalogSectionInactiveComponent extends CatalogSectionComponent
{
/**
* Снимаем ограничение ACTIVE='Y'
* и сохраняем остальную бизнес-логику фильтра.
*/
protected function getFilter()
{
// 1. Базовый набор условий
$filterFields = parent::getFilter();
// 2. Не трогаем Big Data lazy-load
if ($this->getAction() === 'bigDataLoad')
{
return $filterFields;
}
// 3. Убираем «лишнее» ограничение
unset($filterFields['ACTIVE']);
/* 4. Оставляем служебные условия родителя
(INCLUDE_SUBSECTIONS, SECTION_ID и т.п.) */
$filterFields['INCLUDE_SUBSECTIONS'] =
$this->arParams['INCLUDE_SUBSECTIONS'] === 'N' ? 'N' : 'Y';
if ($this->arParams['INCLUDE_SUBSECTIONS'] === 'A')
{
$filterFields['SECTION_GLOBAL_ACTIVE'] = 'Y';
}
if (!isset($this->arParams['BY_LINK']) || $this->arParams['BY_LINK'] !== 'Y')
{
if ($this->arResult['ID'])
{
$filterFields['SECTION_ID'] = $this->arResult['ID'];
}
elseif (!$this->arParams['SHOW_ALL_WO_SECTION'])
{
$filterFields['SECTION_ID'] = 0;
}
else
{
unset(
$filterFields['INCLUDE_SUBSECTIONS'],
$filterFields['SECTION_GLOBAL_ACTIVE']
);
}
}
return $filterFields; // и получаем товары с Y *и* N
}
}
Копипаст или наследование?
* Наследование (пример выше) короче и чище, но при «ломающих» изменениях ядра может понадобиться доработка.
* Полная копия гарантирует стабильность независимо от версии, но требует следить за апдейтами и объёмнее в поддержке.
Шаг 2. Шаблон компонента (опционально)
Обычный шаблон catalog.section
уже готов; добавим лишь визуальную отметку для неактивных:
<?php foreach ($arResult['ITEMS'] as $item):
$inactive = $item['ACTIVE'] === 'N'; ?>
<div class="product<?=$inactive ? ' product--inactive' : ''?>">
<a href="<?=$item['DETAIL_PAGE_URL']?>"><?=$item['NAME']?></a>
<?php if ($inactive): ?>
<span class="badge badge-secondary">Скоро в наличии</span>
<?php endif; ?>
</div>
<?php endforeach; ?>
.product--inactive {opacity:.55;position:relative}
.product--inactive .badge {position:absolute;top:.5rem;left:.5rem}
Шаг 3. Подключение на странице
<?php
$APPLICATION->IncludeComponent(
'my_company:catalog.section.inactive',
'.default',
[
'IBLOCK_TYPE' => 'catalog',
'IBLOCK_ID' => 12,
'SECTION_ID' => 23,
'PAGE_ELEMENT_COUNT' => 30,
'PRICE_CODE' => ['BASE'],
'CACHE_TYPE' => 'A',
'CACHE_TIME' => 3600000,
// остальные параметры родительского catalog.section
]
);
Компонент выводит все элементы (Y + N) без дополнительных флагов. Хотите оставить стандартную логику — подключайте «родной» ядровый компонент.
Важные нюансы продакшена
Тема | Что учесть |
---|---|
Права доступа | Неактивные товары могут быть скрыты сознательно. Защитите вывод if ($USER->IsAdmin()) … либо публикуйте отдельную страницу. |
SEO | Роботы увидят отключённые карточки. Добавьте noindex или перенаправление 302, если они не должны индексироваться. |
Кеширование | Чистка кеша при смене активности остаётся на Bitrix, поэтому дополнительные действия не нужны. |
Производительность | Отсутствие фильтра ACTIVE увеличит выборку. Используйте постраничку и выводите только нужные поля (SELECT ). |
Итог
- Минимальное вмешательство — изменён один метод в наследнике.
- Совместимость со всеми фишками
catalog.section
: пейджинг, Smart Filter, SKU-выборки, lazy-load. - Гибкость — в нужных точках можно легко вернуть стандартное поведение, подключив ядровый компонент.
Таким образом, за несколько строк кода мы получаем полноценный каталог, где менеджер видит всё, а клиент — только то, что действительно доступно к покупке.