Подмена URL элементов/разделов инфоблока

Данный функционал может потребоваться, если у вас действующий сайт и к нему подключено решение (приложение) в виде второго сайта, при этом они должны использовать один и тот же инфоблок. На действующем сайта у вас один принцип формирования ЧПУ, а в решении он другой (жёстко задан frontend частью).

Создаём файл bitrix/modules/astdesign.marketpro/lib/custom/utils/iblock.php

Содержимое файла:

<?php

namespace Astdesign\Marketpro\Custom\Utils;

use \Astdesign\Marketpro\Utils\Options;

/**
 * Class IBlock
 * @package Astdesign\Marketpro\Utils
 */
class IBlock
{
    /**
     * @param $res \CIBlockResult
     * @param $iblock
     * @throws \Bitrix\Main\ArgumentException
     * @throws \Bitrix\Main\ObjectPropertyException
     * @throws \Bitrix\Main\SystemException
     */
    public static function setIblockUrlTemplate(&$res, $iblock)
    {
        if ($iblock == 55) {
            $res->strDetailUrl = "#SITE_DIR#products/#ELEMENT_ID#/";
            $res->strListUrl = "#SITE_DIR#catalog/";
            $res->strSectionUrl = "#SITE_DIR#catalog/#SECTION_CODE#/";
        } elseif ($iblock == 63) {
            $res->strDetailUrl = "#SITE_DIR#brands/#ELEMENT_CODE#/";
            $res->strListUrl = "#SITE_DIR#brands/";
        } else {
            Options::set('checkCustomMethodSkip', true);
            \Astdesign\Marketpro\Utils\IBlock::setIblockUrlTemplate($res, $iblock);
        }
        return $res;
    }

    public static function getIblockUrlTemplate($iblock)
    {
        if ($iblock == 55) {
            return [
                'LIST_PAGE_URL' => "#SITE_DIR#catalog/",
                'DETAIL_PAGE_URL' => "#SITE_DIR#products/#ELEMENT_ID#/",
                'SECTION_PAGE_URL' => "#SITE_DIR#catalog/#SECTION_CODE#/"
            ];
        } else {
            Options::set('checkCustomMethodSkip', true);
            return \Astdesign\Marketpro\Utils\IBlock::getIblockUrlTemplate($iblock);
        }
    }
}

В двух приведённых методах мы переопределяем ЧПУ инфоблока (от действующего сайта) и меняем правило формирования ссылок на то, которое нужно frontend части решения.

Почему в примере return $res

Решение подставляет результат вашего метода на место своего: возвращённое значение записывается в $res. Если метод ничего не вернёт, решение решит, что кастомизации нет, и подставит свои шаблоны ЧПУ. Поэтому return $res в конце обязателен — как и Options::set('checkCustomMethodSkip', true) перед вызовом оригинала в ветке else, иначе получится бесконечная рекурсия. Подробнее про механизм — в статье «Кастомизация (переопределение) методов решения».

Не зашивайте ID инфоблоков

В примере стоят числа 55 и 63 — это ID инфоблоков конкретного сайта. На другой установке они будут другими, поэтому такой код не переносится: посмотрите свои в Контент → Инфоблоки → Типы инфоблоков.

Лучше вообще не писать числа:

  • инфоблоки решения ищите по коду — \Astdesign\Marketpro\Solution::getIblockByCode('catalog'). Так делает само решение, и при переносе на другой сайт код продолжит работать;

  • «чужой» инфоблок действующего сайта, ради которого и нужна подмена, ищите по его символьному коду штатными средствами Битрикса, а ID получайте уже из него.

Тогда единственное, что придётся править при переносе, — сами шаблоны адресов.