Разработка

Can't add custom restriction class successfully (доставка валит корзину)

Can't add custom restriction class successfully (доставка валит корзину)

Ошибка выбрасывается в момент, когда «Доставка» (точнее класс Bitrix\Sale\Services\Base\RestrictionManager) пытается инициализировать ограничения (restrictions), записанные в базе.** Как только для какого-нибудь ограничения не получилось:

 • подключить файл класса;

 • найти объявление этого класса;

 • создать экземпляр класса;

 • или класс не реализует нужный интерфейс,


 RestrictionManager::add() возвращает false, а RestrictionManager::init() бросает исключение
Can't add custom restriction class successfully (0)
 Отсюда весь стек, который вы видите.

Что обычно приводит к этой ситуации

-

	 В таблице b_sale_service_rstr (а значит и в административной части «Продажи → Доставка → Ограничения») осталась запись о кастомном ограничении, но сам модуль или файл с классом вы уже удалили / переименовали / отключили автозагрузку.





-

	 После обновления ядра Bitrix поменялось пространство имён штатного класса-ограничения, а в базе осталась старая строка (редкие случаи старых проектов).





-

	 В коде кто-то добавил своё ограничение, указав неправильное FQCN, поэтому при первом же заходе в оформление заказа исключение воспроизводится.

Как найти «сломанное» ограничение

-

	 Быстро через SQL/PhpMyAdmin:




	 SELECT ID,SERVICE_ID,CLASS_NAME FROM b_sale_service_rstr;




	 – Посмотрите строки, где CLASS_NAME явно не существует в системе (неподходящий namespace, буква пропущена и т.п.).





-

	 Небольшой скрипт на месте:




	 <?php use Bitrix\Main\Loader; Loader::includeModule('sale');




	 $res = Bitrix\Sale\Internals\ServiceRestrictionTable::getList(); while ($row = $res->fetch()) { if (!class_exists($row['CLASS_NAME'])) { echo "Не найден класс {$row['CLASS_NAME']} (ID ограничения {$row['ID']}, SERVICE_ID {$row['SERVICE_ID']})

	 "; } }





-

	 Интерфейс:

	 Админка → Продажи → Доставка → Ограничения (или «Оплаты → Ограничения»). При попытке открыть страницу с «битым» классом Bitrix тоже покажет ошибку — так вы поймёте, какая доставка / оплата затронута.

Что сделать

 • Если это ваш собственный модуль/класс – верните файл или поправьте namespace, чтобы autoload снова нашёл класс.


 • Если ограничение более не нужно – удалите запись из b_sale_service_rstr (или через интерфейс «Ограничения»).


 • Если это штатный битриксовый класс, который «переехал» после обновления, просто смените значение CLASS_NAME на актуальное (подсмотреть можно в файлах модуля sale).


 • После изменений очистите кэш: Админка → Настройки → Кэш → «Сбросить всё».


 Важно: перед правками сделайте резервную копию базы.


 После того, как «битой» записи в b_sale_service_rstr не останется, оформление заказа снова начнёт работать без исключения.

Частный случай:**

 Подобное сообщение об ошибке вызывает модуль corsik.yadelivery, который добавляет ограничение

<!--noindex-->[https://сайт.ru/bitrix/admin/perfmon_row_edit.php?lang=ru&table_name=b_module_to_module&pk%5BID%5D=1055](https://сайт.ru/bitrix/admin/perfmon_row_edit.php?lang=ru&table_name=b_module_to_module&pk%5BID%5D=1055)<!--/noindex-->



 Можно не использовать этот модуль - деинсталлировать. Или отключить обработчики этого модуля, добавив в содержимое поля MESSAGE_ID символ или цифру, и сбросить управляемый кеш на соседней вкладке.