1C-Bitrix Size Filter: Stock Check and Caching
The standard catalog.smart.filter component cannot filter products by the presence of a specific size among trade offers. Result: the user clicks on size 42, but the page is empty because the item is out of stock. Conversion loss in clothing and footwear categories can reach 30% — that's hundreds of thousands of rubles in lost profit monthly. We solve this problem in 2–3 working days.
We are a team of certified developers with 10 years of experience with Bitrix and Bitrix24. We implement the filter turnkey: from data structure design to deployment on a production server. We guarantee correct stock handling and high speed through tagged caching.
Problems with Standard Size Filtering
The first problem is lack of stock consideration. The standard filter shows all sizes from the trade offer infoblock, even those with zero stock. The user selects a size, sees an empty page, and leaves. The second is performance. Querying thousands of offers without caching can take up to 2 seconds, which is unacceptable for an online store. The third is incorrect size grouping (e.g., S/M/L should appear in a defined order, not alphabetically).
We solve all three problems: we filter by PROPERTY_SIZE with CATALOG_QUANTITY > 0, implement tagged caching with agent-based invalidation, and sort sizes by the order in the list property.
Data Architecture for Sizes
Product (catalog infoblock)
└── Trade Offers (trade offer infoblock)
├── PROPERTY_SIZE = "S" CATALOG_QUANTITY = 3
├── PROPERTY_SIZE = "M" CATALOG_QUANTITY = 0
└── PROPERTY_SIZE = "L" CATALOG_QUANTITY = 7
The filter for size M with "Only in stock" enabled should not show this product — trade offer M is out of stock.
How to Store Sizes?
Three typical approaches. The choice depends on the catalog:
| Storage Method | Example | When to Use |
|---|---|---|
| Text property (list) | S, M, L, XL | Simple catalogs, fixed size charts |
| Numeric property | 36, 37, 38... | Shoes, clothing with numeric sizes, need range filtering |
| Complex sizes | EU 42 / US 9, 32/34 | Cross-brand conversion, multiple standards |
We recommend the first option: it offers convenient sorting via a list property and a simple UI. For more details on Bitrix properties, see the official documentation. General caching principles are described in the Wikipedia article.
How to Get Sizes with Stock Consideration?
The function below collects all sizes that exist in at least one active trade offer with non-zero stock, and sorts them by the order from the property setting.
function getAvailableSizes(int $offersIblockId): array
{
$sizes = [];
$res = CIBlockElement::GetList(
[],
[
'IBLOCK_ID' => $offersIblockId,
'ACTIVE' => 'Y',
'>CATALOG_QUANTITY' => 0,
],
['PROPERTY_SIZE'],
false,
['PROPERTY_SIZE']
);
while ($item = $res->Fetch()) {
$sizeId = $item['PROPERTY_SIZE_ENUM_ID'];
$sizeValue = $item['PROPERTY_SIZE_VALUE'];
if ($sizeId && !isset($sizes[$sizeId])) {
$sizes[$sizeId] = [
'id' => $sizeId,
'xmlId' => $item['PROPERTY_SIZE_ENUM_XML_ID'],
'value' => $sizeValue,
'sort' => 0,
];
}
}
if (!empty($sizes)) {
$enumRes = CIBlockPropertyEnum::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => $offersIblockId, 'CODE' => 'SIZE']
);
$sortMap = [];
while ($enum = $enumRes->Fetch()) {
$sortMap[$enum['ID']] = intval($enum['SORT']);
}
foreach ($sizes as &$size) {
$size['sort'] = $sortMap[$size['id']] ?? 999;
}
usort($sizes, fn($a, $b) => $a['sort'] <=> $b['sort']);
}
return array_values($sizes);
}
Catalog Filtering by Size with Stock Consideration
function getProductIdsBySize(
int $catalogIblockId,
int $offersIblockId,
array $sizeXmlIds,
bool $onlyInStock = true
): array {
if (empty($sizeXmlIds)) return [];
$offerFilter = [
'IBLOCK_ID' => $offersIblockId,
'ACTIVE' => 'Y',
'PROPERTY_SIZE' => $sizeXmlIds,
];
if ($onlyInStock) {
$offerFilter['>CATALOG_QUANTITY'] = 0;
}
$productIds = [];
$res = CIBlockElement::GetList(
[],
$offerFilter,
false,
false,
['PROPERTY_CML2_LINK']
);
while ($row = $res->GetNext()) {
if ($pid = intval($row['PROPERTY_CML2_LINK_VALUE'])) {
$productIds[$pid] = true;
}
}
return array_keys($productIds);
}
UI: Size Grid
We display sizes as checkboxes in a grid layout. Active sizes are highlighted, others have a gray border.
$availableSizes = getAvailableSizes(OFFERS_IBLOCK_ID);
$selectedSizes = array_map('htmlspecialchars', (array)($_GET['SIZE'] ?? []));
?>
<div class="filter-block filter-block--sizes">
<h3 class="filter-block__title">Size</h3>
<div class="size-grid">
<?php foreach ($availableSizes as $size): ?>
<?php $isSelected = in_array($size['xmlId'], $selectedSizes); ?>
<label class="size-option <?= $isSelected ? 'is-selected' : '' ?>">
<input type="checkbox"
name="SIZE[]"
value="<?= htmlspecialchars($size['xmlId']) ?>"
<?= $isSelected ? 'checked' : '' ?>>
<span class="size-label"><?= htmlspecialchars($size['value']) ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
Why Caching Dimensions Matters
The list of available sizes rarely changes — only when goods arrive or are written off. Without caching, each catalog request queries thousands of offers. Our tagged caching approach speeds up filter loading by 3 times compared to no cache. Filter response time drops from 0.9 to 0.3 seconds for a catalog with 50,000 products. This saves up to 15% of user bounce rate, increasing profit.
$cacheId = 'available_sizes_' . OFFERS_IBLOCK_ID;
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(600, $cacheId, '/catalog/filter/')) {
$availableSizes = $cache->getVars();
} else {
$availableSizes = getAvailableSizes(OFFERS_IBLOCK_ID);
$cache->startDataCache();
$cache->endDataCache($availableSizes);
}
For invalidation, we set an agent that updates stock every 10 minutes — the cache is cleared automatically.
What's Included
| Stage | Content |
|---|---|
| Analysis | Study catalog, size charts, filter requirements |
| Design | Choose storage method, design cache |
| Development | PHP logic, component template, CSS/JS |
| Testing | Verification on real data, load testing |
| Documentation | Architecture, data schema, deployment guide |
| Training | Knowledge transfer to your team (1–2 hours online) |
| Support | 30 days of warranty support after launch |
Process
- Analysis — study the catalog, size charts, filter requirements.
- Design — choose storage method, design the cache.
- Development — write functions for size retrieval, filtering, UI.
- Testing — verify on real data.
- Deployment — deploy to production server, configure cache invalidation.
Implementation Timeline
Basic implementation (without stock check): from 4 hours. Full version with stock, caching, and custom UI: 2–3 working days. Complex scenarios (multiple size charts, cross-brand conversion): up to 5 days. Cost is calculated individually: we evaluate complexity, catalog volume, number of size charts. Contact us — we'll prepare a quote within one day.
Our experience: over 50 filter projects in Bitrix, certified specialists. Request a consultation — we'll discuss your task without obligation.







