Modifying standard components via 1C-Bitrix result_modifier

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Customizing Standard Components via result_modifier in 1C-Bitrix

result_modifier.php — a file inside the component template folder that executes after the component itself runs but before the template renders. At this point $arResult is already populated with data — you can add, modify, or remove any data before output. This is the primary mechanism for customizing standard components without touching the core.

How the mechanism works

Component execution sequence:

1. component.php (component logic, populates $arResult)
2. result_modifier.php (modifies $arResult within the template)
3. template.php (renders HTML)
4. component_epilog.php (post-processing after render)

result_modifier.php lives inside the template folder:

/local/templates/{site_template}/components/bitrix/catalog.element/default/result_modifier.php

Or inside a copied component template:

/local/components/bitrix/catalog.element/templates/default/result_modifier.php

If you created a component template through the administrative interface (Settings → Components → Component Templates), result_modifier.php is created in the template copy automatically.

What is available in result_modifier

The following are available in the file:

  • $arResult — the component result, an array of data
  • $arParams — component parameters (from the template call or set automatically)
  • $this — the component object (CBitrixComponent)
  • All global 1C-Bitrix objects: $USER, $APPLICATION, $DB

Practical applications

Adding data from an external source to a product card:

In catalog.element, $arResult does not contain, for example, the average rating from a reviews table. Adding it:

// result_modifier.php for bitrix:catalog.element
\Bitrix\Main\Loader::includeModule('iblock');

$productId = $arResult['ID'];

// Fetch rating from a custom reviews table
$rating = ReviewTable::getAggregateByProduct($productId);
$arResult['AVERAGE_RATING']  = $rating['avg'] ?? 0;
$arResult['REVIEWS_COUNT']   = $rating['count'] ?? 0;

Now in template.php this data is available via $arResult['AVERAGE_RATING'].

Enhancing the product list (catalog.section): adding warehouse stock data:

// result_modifier.php for bitrix:catalog.section / bitrix:catalog.smart.filter
\Bitrix\Main\Loader::includeModule('catalog');

$productIds = array_column($arResult['ITEMS'], 'ID');

// Fetch stock levels for the primary warehouse
$stocks = \Bitrix\Catalog\StoreProductTable::getList([
    'filter' => [
        'PRODUCT_ID'   => $productIds,
        'STORE.ACTIVE' => 'Y',
        'STORE.XML_ID' => 'MAIN_WAREHOUSE',
    ],
    'select' => ['PRODUCT_ID', 'AMOUNT'],
])->fetchAll();

$stockMap = array_column($stocks, 'AMOUNT', 'PRODUCT_ID');

foreach ($arResult['ITEMS'] as &$item) {
    $item['MAIN_STOCK'] = $stockMap[$item['ID']] ?? 0;
    $item['IN_STOCK']   = $item['MAIN_STOCK'] > 0;
}
unset($item);

Substituting price based on user group:

// result_modifier.php for bitrix:catalog.element
global $USER;

$userGroups = $USER->GetUserGroupArray();
$isWholesale = in_array(WHOLESALE_GROUP_ID, $userGroups);

if ($isWholesale && isset($arResult['CATALOG_PRICE_2'])) {
    // Show wholesale price instead of retail
    $arResult['DISPLAY_PRICE'] = $arResult['CATALOG_PRICE_2'];
} else {
    $arResult['DISPLAY_PRICE'] = $arResult['CATALOG_PRICE_1'] ?? 0;
}

Building breadcrumbs with custom data:

// Adding SEO breadcrumbs from the section
if (!empty($arResult['SECTION'])) {
    $arResult['SEO_BREADCRUMBS'] = buildSeoJsonLd(
        $arResult['SECTION']['PATH'],
        $arResult['NAME']
    );
}

Performance: cache inside result_modifier

result_modifier.php executes on every component render. If it contains heavy queries — wrap them in a cache:

// result_modifier.php
$cacheId  = 'product_extra_' . $arResult['ID'];
$cacheDir = '/product_extra/';
$ttl      = 3600;

$cache = \Bitrix\Main\Data\Cache::createInstance();

if ($cache->initCache($ttl, $cacheId, $cacheDir)) {
    $extraData = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $extraData = fetchHeavyProductData($arResult['ID']); // your slow query

    $cache->endDataCache($extraData);
}

$arResult['EXTRA'] = $extraData;

Important: if the component itself uses cache (most catalog components do), then result_modifier.php does not execute when the response is served from cache — only template.php runs with the cached $arResult. Keep this in mind: data added to $arResult inside result_modifier.php is cached together with $arResult.

Limitations of result_modifier

result_modifier.php is not the place for side-effect operations: creating database records, sending notifications, or changing state. It is for reading and transforming $arResult only. For side effects after rendering — use component_epilog.php.

You cannot modify SQL queries already executed by the component — you can only augment the result with new queries. If you need to change data retrieval logic, you will need to override the component itself via /local/components/.

Debugging

If result_modifier.php is not being applied — check:

  1. The file path: it must be in the template folder used in the component call
  2. The component is not being served entirely from cache (in that case result_modifier.php is not called for cached data — only template.php runs)
  3. No syntax errors in the file — execution errors are silently ignored in production mode
// At the top of result_modifier.php for debugging
// Verify that the file is actually being executed:
if (defined('LOG_RESULT_MODIFIER')) {
    file_put_contents('/tmp/rm_debug.log', date('H:i:s') . ' ' . __FILE__ . "\n", FILE_APPEND);
}

Scope of work: analyzing the $arResult structure of the target component, writing result_modifier.php, adding cache coverage — typically 4–16 hours depending on the complexity of the data source.