Битрикс: заметки по работе с кодом
Привет, любимые читатели Лохмача! На этой странице я буду размещать всяческие материалы, фрагменты кода и другие наработки, которые очень часто необходимы мне для решения насущных задач с CMS 1С-Битрикс.
Эта статья не претендует на оригинальность. Многие методы я просто взял из официальной документации, чтобы они были всегда под рукой. Несмотря на это, здесь собраны некоторые фишки собственного производства, которые, возможно, будут полезны и вам.
Методы и сценарии
- Как подключить пролог Битрикс
- Узнать, где находится шаблон компонента
- Получить список товаров по своему фильтру
- Получить все товары, находящиеся в корзине
- Получить все свойства товара по его ID
- Изменить значение свойства товара по его ID
- Установить стоимость доставки товаров по своим условиям
Как подключить пролог Битрикс
Подключаем "prolog_before.php" для использования Bitrix API и его синтаксиса. Также активируем основные модули:
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
CModule::IncludeModule("iblock");
CModule::IncludeModule("main");
CModule::IncludeModule("sale");
Узнать, где находится шаблон компонента
Эта конструкция позволит узнать, в какой папке на сервере располагается шаблон указанного нами компонента Битрикс:
$component = new CBitrixComponent();
$component -> InitComponent("bitrix:news.list", ".default"); // Имя компонента и шаблон
$component -> initComponentTemplate();
echo $component -> __template -> GetFolder();
Получить список товаров по своему фильтру
Получаем и перебираем массив элементов по собственному фильтру:
$filterItems = CIBlockElement::GetList(array(), array("=AVAILABLE" => "Y", "ACTIVE" => "Y"), false, false, array());
while($item = $filterItems -> Fetch()){
echo $item["ID"]."<br>"; // Выводим ID товара
// echo "<pre>"; print_r($item); echo "</pre>"; // Раскомментируйте, если надо показать весь массив данных
}
Параметры этого метода описаны в официальной документации:
https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php
Получить все товары, находящиеся в корзине
Получаем и перебираем массив товаров, которые находятся в корзине:
$basketItems = CSaleBasket::GetList(array(), array("FUSER_ID" => CSaleBasket::GetBasketUserID(), "LID" => SITE_ID, "ORDER_ID" => "NULL"), false, false, array());
while($item = $basketItems -> Fetch()){
echo $item["PRODUCT_ID"]."<br>"; // Выводим ID товара
// echo "<pre>"; print_r($item); echo "</pre>"; // Раскомментируйте, если надо показать весь массив данных
}
Параметры и возвращаемые значения описаны в документации:
https://dev.1c-bitrix.ru/api_help/sale/classes/csalebasket/csalebasket__getlist.4d82547a.php
Получить все свойства товара по его ID
С помощью этого кода мы можем получить массив со всеми свойствами товара по его ID:
$res = CIBlockElement::GetByID($item["PRODUCT_ID"]); // Идентификатор элемента
$el = $res -> GetNextElement() -> GetProperties();
echo "<pre>"; print_r($el); echo "</pre>";
Изменить значение свойства товара по его ID
Изменяем значение любого свойства товара по его ID:
CIBlockElement::SetPropertyValueCode($ELEMENT_ID, $PROPERTY_CODE, $PROPERTY_VALUE);
Параметры:
- Идентификатор редактируемого товара.
- Числовой или символьный код изменяемого свойства.
- Значение или идентификатор значения редактируемого свойства. Второе указывается, если свойство имеет тип "Список" (см. скриншот).

Как сказано в официальной документации, метод, описанный выше (SetPropertyValueCode), производит один дополнительный запрос к БД, чтобы получить код инфоблока, к которому принадлежит элемент. Поэтому, если этот код нам известен, то предпочтительней использовать другой способ:
CIBlockElement::SetPropertyValues($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUE, $PROPERTY_CODE);
И еще, я заметил, когда производил склейку свойств элементов этим методом, что фильтр товаров на сайте никак не реагирует на эти изменения. Другими словами, не видит их, и, соответственно, возвращает неверные результаты фильтрации. Полагаю, дело в том, что при использовании этих методов не происходит переиндексации элементов для поиска.
Покопавшись какое-то время в сети, я пришел к заключению, что параметр "bUpdateSearch" метода "Update", который включен по умолчанию, как раз устраняет эту проблему. Поэтому всем, кто не нашел решения получше, предлагаю использовать этот код. Расположить его лучше сразу после строки с вызовом "SetPropertyValueCode" или "SetPropertyValues".
$cbe = new CIBlockElement;
$cbe -> Update($ELEMENT_ID, false);
Установить стоимость доставки товаров по своим условиям
А этот трюк будет полезен тем, кто разрабатывает собственные сценарии доставки. Заключается он в том, что вы можете сформировать цену на доставку товаров по своему алгоритму, а затем передать ее в админку так, как это делают штатные службы Битрикс.
Выглядит это примерно следующим образом: предположим, на странице оформления заказа вы используете свой сценарий расчета стоимости доставки, написанный, допустим, на JS. Все вычисления он производит исходя из различных условий: отдаленность, вес, габариты, количество товара, дата, время доставки и прочее. Говоря иначе, на стороне клиента вы имеете сформированную стоимость доставки, полностью готовую для передачи в админку, как только случится заветный клик "Оформить заказ". Вот тут, собственно, и возникает вопрос: как передать эти расчеты в ядро движка, чтобы все работало правильно, как при использовании стандартных служб доставки Битрикс.
Как ни странно, но для реализации такой задачи нам потребуется совсем немного:
- Создаем единственную службу доставки со стандартными настройками и нулевой стоимостью.
- Переходим в ваш JS-сценарий и редактируем его таким образом, чтобы при каждом изменении условий, которые влияют на стоимость доставки, происходила запись этой стоимости в куки-файл нашего покупателя.
- Следуем по маршруту "/bitrix/modules/sale/lib/delivery/" и открываем документ с именем "calculationresult.php". Находим в нем функцию "setDeliveryPrice" и в ее начале присваиваем переменной "$price" значение нашей куки. Занавес, овации.
Подозреваю, здесь нет необходимости долго разжевывать логику этого действа. Принцип работы такой: на странице оформления заказа мы производим запись стоимости доставки в куки-файл клиента, а в момент формирования заказа подставляем эти данные туда, откуда они улетают по своему маршруту, даже не подозревая, что их подменили.
Чтобы не придаваться воспоминаниям о том, как создавать и считывать cookie, приведу фрагменты кода, которые необходимо внедрить, следуя описанию выше.
Записываем/перезаписываем куку в вашем JS-сценарии всякий раз, когда меняется стоимость доставки:
document.cookie = "delPrice="+ delPrice +"; path=/; max-age=864000";
А так должна выглядеть функция "setDeliveryPrice" после того, как мы подкинем в нее нашу малышку:
public function setDeliveryPrice($price) {
if($_COOKIE["delPrice"]){$price = $_COOKIE["delPrice"];}
$this->deliveryPrice = $price;
}
На этом я хочу завершить свое повествование. Надеюсь, эта справка была информативна и полезна. Я обязательно буду публиковать здесь новые наработки по мере их поступления, а вы, в свою очередь, можете делиться своими в комментариях.