Кастомизация (переопределение) методов решения
Для того, чтобы переопределить метод в API решения, нужно создать такой же публичный статический метод в пространстве имён Astdesign\Marketpro\Custom.
Это можно сделать и в своих модулях/папках, а можно разместить нужные классы в папке bitrix/modules/astdesign.marketpro/lib/custom (тогда будет работать автозагрузка классов).
Рассмотрим переопределение метода на конкретном примере. Задача - на странице результатов поиска выводить разделы каталога. За страницу поиска в решении отвечает метод \Astdesign\Marketpro\Api\Catalog::searchPage. Кастомизируем его, создав файл bitrix/modules/astdesign.marketpro/lib/custom/api/catalog.php.
Содержимое файла:
<?php
namespace Astdesign\Marketpro\Custom\Api;
use Astdesign\Marketpro\Solution;
use Astdesign\Marketpro\Utils\Options;
use Astdesign\Marketpro\Utils\Search\Correction;
class Catalog
{
public static function searchPage($data = [])
{
Options::set('checkCustomMethodSkip', true);
$result = \Astdesign\Marketpro\Api\Catalog::searchPage($data);
if (!empty($result['products']['items'])) {
$query = trim(htmlspecialcharsbx($data['query']));
if (!$query || strlen($query) < 3) {
return $result;
}
if (Solution::getOption("useSearchCorrection", "N") === "Y") {
$query = Correction::getInstance()->correct($query);
}
$sectionSearchRes = \Astdesign\Marketpro\Custom\Utils\Search::innerSearchSection($query);
if (!empty($sectionSearchRes)) {
$result['sections']['items'] = $sectionSearchRes;
}
}
return $result;
}
}В данном примере используется метод Options::set('checkCustomMethodSkip', true); , который позволяет избежать зацикливания при вызове оригинальных методов решения. Его нужно использовать в кастомных методах при каждом вызове оригинальных методов.
В приведённом примере мы для начала вызываем оригинальный метод страницы поиска, который возвращает нам результат, а уже потом мы его модифицируем под свои задачи.
Как это работает внутри
Каждый метод решения, который можно переопределить, начинается с проверки: решение подставляет в имя своего класса Custom — Astdesign\Marketpro\Api\Catalog превращается в Astdesign\Marketpro\Custom\Api\Catalog — и, если такой метод существует и вызываем, отдаёт управление ему. Результат проверки кешируется в пределах запроса, так что накладных расходов почти нет.
Отсюда правила:
имя и пространство имён должны совпадать с оригиналом, отличаясь только вставкой
Custom;метод должен быть публичным и статическим;
переопределить можно только те методы, в которых эта проверка есть — если в начале метода нет
checkCustomMethod, перехватить его не получится.
Зачем в примере checkCustomMethodSkip
Строка Options::set('checkCustomMethodSkip', true) перед вызовом оригинала обязательна, если вы хотите дополнить штатный метод, а не заменить его целиком. Без неё оригинальный метод на входе снова увидит ваш переопределённый и вызовет его — получится бесконечная рекурсия.
Флаг одноразовый: решение сбрасывает его при первой же проверке. Поэтому ставьте его непосредственно перед вызовом оригинала, а не в начале своего метода.
Что переживает обновление
Папка lib/custom исключается из пакета обновления, поэтому ваши классы там остаются. Если размещаете переопределения в своём модуле, обновление их тем более не тронет — но тогда позаботьтесь об автозагрузке классов сами.