Все знают чудесное событие из названия поста, OnBeforeBasketAdd, которое позволяет перед добавлением товара в корзину внедрить свою логику.Но все ли знают, что сами поля обработчик этого события изменить не может?
[spoiler]
Я вот повелся на документацию, где сказано следующее
OnBeforeBasketAdd - вызывается перед добавлением записи в корзину, может быть использовано для отмены или модификации данных.
Параметры
Ага-ага, модификация данных:)
Собственно, кусок кода в методе CAllSaleBasket::Add() говорит, что модифицировать ничего не получится.
Что этот код означает для разработчика? Что $arFields, ушедший внутрь ExecuteModuleEvent и $arFields, который попадет в ваш обработчик, будут несвязанными между собой переменными. И ваши тщетные потуги изменить, например, название товара (например задать товарному предложению красивое название основного товара, чтобы в корзине было понятно, что было куплено), - вобщем ваши потуги будут бессмыслены. Что положено в корзину - то только прямыми запросами можно поправить.
Я сказал прямые запросы? Не-не, это была шутка)
На самом деле, пока разработчики Битрикса не выпустят апдейт, исправляющий данную багу (или фичу, тут уж кому как), можно использовать следующий алгоритм. Немногоговномногокодный, но работающий.
Сразу оговорюсь, что есть более красивый и универсальный метод с помощью обработчиков, но я пока не протестировал его. Как оттестирую - то выложу.
А так мораль сей басни такова - был бы амперсанд перед $arFields - жили бы мы в Сочи.
UPD: Как и было обещано в комментах, в версии 11.0 баг закрыт, значения передаются по ссылке. Так что простым и легким решением будет просто обновиться до версии 11.0
[spoiler]
Я вот повелся на документацию, где сказано следующее
OnBeforeBasketAdd - вызывается перед добавлением записи в корзину, может быть использовано для отмены или модификации данных.
Параметры
&arFields | Массив полей записи корзины |
Ага-ага, модификация данных:)
Собственно, кусок кода в методе CAllSaleBasket::Add() говорит, что модифицировать ничего не получится.
$db_events = GetModuleEvents("sale", "OnBeforeBasketAdd";); while ($arEvent = $db_events->Fetch()) if (ExecuteModuleEvent($arEvent, $arFields)===false) return false; |
Что этот код означает для разработчика? Что $arFields, ушедший внутрь ExecuteModuleEvent и $arFields, который попадет в ваш обработчик, будут несвязанными между собой переменными. И ваши тщетные потуги изменить, например, название товара (например задать товарному предложению красивое название основного товара, чтобы в корзине было понятно, что было куплено), - вобщем ваши потуги будут бессмыслены. Что положено в корзину - то только прямыми запросами можно поправить.
Я сказал прямые запросы? Не-не, это была шутка)
На самом деле, пока разработчики Битрикса не выпустят апдейт, исправляющий данную багу (или фичу, тут уж кому как), можно использовать следующий алгоритм. Немного
- Копируем код функции Add2BasketByProductID к себе в php_interface куда-нибудь. Я вот скопировал ее вообще как метод класса, CustomHandlers::Add2BasketByProductID. Но можно просто переименовать.
- Внутри новенькой функции/метода делаем нужные нам изменения в $arFields, главное это сделать до строки $addres = CSaleBasket::Add($arFields);. Потом будет поздно.
- Ну и придется перенести системный компонент sale.basket.basket (а также sale.basket.basket.line и sale.basket.basket.small, если таковые используются) в свое пространство имен, и внутри них в моменте добавления товара подставить вызов своей новенькой функции вместо коробочной Add2BasketByProductID.
- Все, теперь поля можно менять, всю логику изменения следует вписывать внутрь новой функции добавления.
Сразу оговорюсь, что есть более красивый и универсальный метод с помощью обработчиков, но я пока не протестировал его. Как оттестирую - то выложу.
А так мораль сей басни такова - был бы амперсанд перед $arFields - жили бы мы в Сочи.
UPD: Как и было обещано в комментах, в версии 11.0 баг закрыт, значения передаются по ссылке. Так что простым и легким решением будет просто обновиться до версии 11.0