Полезные ссылки

Модули

События

1C

Возможность интеграции с старыми версиями модуля обмена

// В "Командная PHP-строка":
echo COption::SetOptionString("catalog", "DEFAULT_SKIP_SOURCE_CHECK", "Y" );
echo COption::SetOptionString("sale", "secure_1c_exchange", "N" );

Платежные системы

Получение списка платежных систем D7

$paysystem = [];
$db_list = \Bitrix\Sale\PaySystem\Manager::getList(
    [
        'select' => ['*'],
        'filter' => [
          '=ACTIVE' => 'Y'
        ]
    ]
);
while ($db_el = $db_list->fetch()) {
    $db_el['LOGOTIP'] = CFile::ResizeImageGet($db_el['LOGOTIP'], ['width' => 500, 'height' => 500], BX_RESIZE_IMAGE_PROPORTIONAL, true);
    $paysystem[] = $db_el;
}
print_r($paysystem);

Службы доставки

Получение списка служб доставок D7

$delivery = [];
$list = Delivery\Services\Manager::getActiveList();
foreach ($list as $service) {
    if ($service['CLASS_NAME'] == '\Bitrix\Sale\Delivery\Services\EmptyDeliveryService') {
        continue;
    }
    $service['PROPS_GROUP_ID'] = 'DELIVERY';
    $service['PRICE'] = $service['CONFIG']['MAIN']['PRICE'];
    $service['LOGOTIP'] = CFile::ResizeImageGet($service['LOGOTIP'], ['width' => 500, 'height' => 500], BX_RESIZE_IMAGE_PROPORTIONAL, true);
    $delivery[] = $service;
}
print_r($delivery);

JS и CSS

Подключить JS или CSS D7

В шаблоне компонента

$this->addExternalCss("/local/styles.css");
$this->addExternalJS("/local/liba.js");

В любом месте

\Bitrix\Main\Page\Asset::getInstance()->addCss("/local/styles.css");
\Bitrix\Main\Page\Asset::getInstance()->addJs("/local/liba.js");

Модуль

Получить путь к корневой директории модуля

Например в скрипте в директории, которая находится в корневой директории модуля:

$module_absolute_path = str_replace("\\", "/", dirname(__DIR__ . '\\..\\'));
$module_relative_path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $module_absolute_path);

Корзина

Добавление товара в корзину D7

if (Loader::includeModule('sale')) {
    $product_id = 1;
    $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());
    $basketItem = $basket->createItem('catalog', $product_id);
    $basketItem->setFields(
        [
            'QUANTITY' => 4,
            'CURRENCY' => Bitrix\Currency\CurrencyManager::getBaseCurrency(),
            'LID' => Bitrix\Main\Context::getCurrent()->getSite(),
            'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider'
        ]
    );
    $basket->save();
    print_r($basket->getListOfFormatText());
}

Обновление товара в корзине D7

if (Loader::includeModule('sale')) {
    $product_id = 1;
    $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());
    $basketItem = $basket->getExistsItem('catalog', $product_id);
    $basketItem->setField('QUANTITY', $basketItem->getQuantity() + $quantity);
    $basket->save();
    print_r($basket->getListOfFormatText());
}

Получение списка товаров корзины текущего пользователя D7

if (Loader::includeModule('sale')) {
    $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());
    $db_list = Basket::getList([
        'select' => ['*'],
        'filter' => [
            '=FUSER_ID' => Fuser::getId(),
            '=ORDER_ID' => null,
            '=LID' => Context::getCurrent()->getSite(),
            '=CAN_BUY' => 'Y',
        ]
    ]);
    while ($db_el = $db_list->fetch())
    {
        print_r($db_el);
    }
}

Получение списка товаров корзины текущего пользователя и связанных с ними элементов инфоблоков

$items = [];
        
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(\Bitrix\Sale\Fuser::getId(), \Bitrix\Main\Application::getInstance()->getContext()->getSite());

// <DISCOUNTS> : apply
$discounts_context = new \Bitrix\Sale\Discount\Context\Fuser(\Bitrix\Sale\Fuser::getId());
$discounts = Discount::buildFromBasket($basket, $discounts_context);
$result = $discounts->calculate()->getData();
$basket->applyDiscount($result['BASKET_ITEMS']);
// </DISCOUNTS>

$basket_items = $basket->getBasketItems();

foreach ($basket_items as $obj) {
    $item = [];
    $item['PRODUCT_ID'] = $obj->getProductId();
    $item['PRICE'] = $obj->getPrice();
    $item['SUM_PRICE'] = $obj->getFinalPrice();
    $item['CURRENCY'] = $obj->getCurrency();
    $item['QUANTITY'] = $obj->getQuantity();
    $item['WEIGHT'] = $obj->getWeight();
    $item['FORMATTED_PRICE'] = \CCurrencyLang::CurrencyFormat($item['PRICE'], $item['CURRENCY']);
    $item['SUM_FORMATTED_PRICE'] = \CCurrencyLang::CurrencyFormat($item['SUM_PRICE'], $item['CURRENCY']);
    
    // Получение IBLOCK_ID элемента с которым связан продукт
    $db_iblock_list = \CIBlockElement::GetById($item['PRODUCT_ID']);
    if ($db_iblock_el = $db_iblock_list->GetNext()) {
        $item['PRODUCT_IBLOCK_ID'] = $db_iblock_el['IBLOCK_ID'];
    }
    unset($db_iblock_list);
    
    $allowed_fields_iblock = [
        'ID',
        'IBLOCK_ID',
        'NAME',
        'PREVIEW_PICTURE',
        'DETAIL_PAGE_URL',
    ]; // Если необходимо получить все свойства: ['ID', 'IBLOCK_ID', '*']
    
    // Получение всех полей элемента с которым связан продукт
    $db_iblock_list = \CIBlockElement::GetList(
        [],
        ['IBLOCK_ID' => $item['PRODUCT_IBLOCK_ID'], 'ID' => $item['PRODUCT_ID']],
        false,
        false,
        $allowed_fields_iblock
    );
    if ($db_iblock_el = $db_iblock_list->GetNext()) {
        // Получение картинки и изменение ее размеров
        $db_iblock_el['PREVIEW_PICTURE'] = \CFile::ResizeImageGet($db_iblock_el["PREVIEW_PICTURE"], ['width' => 500, 'height' => 500], BX_RESIZE_IMAGE_PROPORTIONAL, true);
        $item['PRODUCT'] = $db_iblock_el;
    }
    unset($db_iblock_list);
    
    $items[] = $item;
}

print_r($items);

Получение информации о корзине текущего пользователя D7

$info = [];

if (Loader::includeModule('sale')) {

    $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());

    $info['PRICE'] = $basket->getPrice();
    $info['PRICE_WITHOUT_DISCOUNTS'] = $basket->getBasePrice();
    $info['WEIGHT'] = $basket->getWeight();
    $info['VAT_RATE'] = $basket->getVatRate();
    $info['VAT_SUM'] = $basket->getVatSum();
    $info['FORMATTED_PRICE'] = CCurrencyLang::CurrencyFormat($info['PRICE'], CCurrency::GetBaseCurrency());
    $info['FORMATTED_PRICE_WITHOUT_DISCOUNTS'] = CCurrencyLang::CurrencyFormat($info['PRICE_WITHOUT_DISCOUNTS'], CCurrency::GetBaseCurrency());
    $info['ITEMS_QUANTITY'] = $basket->getQuantityList();
    $info['QUANTITY'] = count($info['ITEMS_QUANTITY']);
}

print_r($info);

Применение скидок к корзине

$basket = Basket::loadItemsForFUser(\Bitrix\Sale\Fuser::getId(), \Bitrix\Main\Application::getInstance()->getContext()->getSite());
$discounts_context = new \Bitrix\Sale\Discount\Context\Fuser(\Bitrix\Sale\Fuser::getId());
$discounts = Discount::buildFromBasket($basket, $discounts_context);
$result = $discounts->calculate()->getData();
$basket->applyDiscount($result['BASKET_ITEMS']);

Удаление товара из корзины текущего пользователя D7

$msg['status'] = false;

if (Loader::includeModule('sale')) {

    $product_id = 1;

    if($product_id) {

        $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());

        if ($basketItem = $basket->getExistsItem('catalog', $product_id)) {

            $basketItem->delete();
            $basket->save();

            $msg['status'] = true;
        }
    }
}

print_r($msg);

Изменение количества товара в корзине текущего пользователя D7

$msg['status'] = false;

if (Loader::includeModule('sale')) {

    $product_id = 1;
    $quantity = 1;

    if($product_id && $quantity) {

        $basket = Basket::loadItemsForFUser(Fuser::getId(), Context::getCurrent()->getSite());

        if ($basketItem = $basket->getExistsItem('catalog', $product_id)) {

            // Обновление товара в корзине
            $basketItem->setField('QUANTITY', $quantity);
            $basket->save();

            $msg['status'] = true;
            $msg['action'] = 'update';

        } else {

            // Добавление товара в корзину
            $basketItem = $basket->createItem('catalog', $product_id);
            $basketItem->setFields(
                [
                    'QUANTITY' => $quantity,
                    'CURRENCY' => Bitrix\Currency\CurrencyManager::getBaseCurrency(),
                    'LID' => Bitrix\Main\Context::getCurrent()->getSite(),
                    'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider'
                ]
            );
            $basket->save();

            $msg['status'] = true;
            $msg['action'] = 'add';
        }
    }
}

print_r($msg);

Обработчики событий

Пример создания и удаления долгосрочного обработчика события

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->registerEventHandler("main", "OnAfterEpilog", "mymodule", "\MyClass\MyClassBase", "myFunction");
$eventManager->unRegisterEventHandler("main", "OnAfterEpilog", "mymodule", "\MyClass\MyClassBase", "myFunction");

Пример создания и удаления краткосрочного обработчика события

$eventManager = \Bitrix\Main\EventManager::getInstance();
$handler = $eventManager->addEventHandler("main", "OnAfterEpilog", array("\MyClass\MyClassBase", "myFunction"));
$eventManager->removeEventHandler("main", "OnAfterEpilog", $handler);
$handlers = $eventManager->findEventHandlers("main", "OnAfterEpilog");

Замена отсутствующих картинок в инфоблоке заглушками

function replaceEmptyPictures($id) {
	$db_list = CIBlockElement::GetByID($id);
	if ($db_el = $db_list->GetNext()) {
		$fields = array();
		
		if (empty($db_el["DETAIL_PICTURE"])) {
			$fields["DETAIL_PICTURE"] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"] . "/local/assets/empty.png");
		}
		
		if (empty($db_el["PREVIEW_PICTURE"])) {
			$fields["PREVIEW_PICTURE"] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"] . "/local/assets/empty.png");
		}
		
		if (!empty($fields)) {
			$element = new CIBlockElement();
			$element->Update($db_el["ID"], $fields);
		}
	}
}

function OnAfterIBlockElementAddHandler(&$arFields) {
	replaceEmptyPictures($arFields["ID"]);
}

function OnAfterIBlockElementUpdateHandler(&$arFields) {
	replaceEmptyPictures($arFields["ID"]);
}

Создание собственного события

// В качестве аргумента, в функцию-обработчик будет передан объект $event
// Дополнительные параметры передаются с помощью методов setParameter() и setParameters() объекта $event
// Получить дополнительные параметры возможно с помощью метода getParameter() и getParameters() объекта $event
$event = new \Bitrix\Main\Event("main", "CustomEventName");
$event->send();

Добавление полей в почтовые шаблоны события SALE_NEW_ORDER

define('CATALOG_IBLOCK_ID', 1);

AddEventHandler("sale", "OnOrderNewSendEmail", "handlerOnOrderNewSendEmail");

function handlerOnOrderNewSendEmail($orderID, &$eventName, &$arFields) {

    $order = CSaleOrder::GetByID($orderID);
    $order_props = CSaleOrderPropsValue::GetOrderProps($orderID);

    $name = "";
    $last_name = "";
    $phone = "";
    $country_name = "";
    $city_name = "";
    $street_name = "";
    $house_name = "";
    $flat_name = "";
    $delivery_name = "";
    $pay_system_name = "";

    while ($arProps = $order_props->Fetch()) {
        if ($arProps["CODE"] == "NAME") {
            $name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "LASTNAME") {
            $last_name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "PHONE") {
            $phone = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "COUNTRY") {
            $country_name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "CITY") {
            $city_name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "STREET") {
            $street_name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "HOUSE") {
            $house_name = htmlspecialchars($arProps["VALUE"]);
        }
        if ($arProps["CODE"] == "FLAT") {
            $flat_name = htmlspecialchars($arProps["VALUE"]);
        }
    }

    $arDeliv = CSaleDelivery::GetByID($order["DELIVERY_ID"]);
    if ($arDeliv) {
        $delivery_name = $arDeliv["NAME"];
    }

    $arPaySystem = CSalePaySystem::GetByID($order["PAY_SYSTEM_ID"]);
    if ($arPaySystem) {
        $pay_system_name = $arPaySystem["NAME"];
    }

    $arFields["FULL_NAME"] = "$name $last_name";
    $arFields["PHONE"] = $phone;
    $arFields["DELIVERY_NAME"] = $delivery_name;
    $arFields["PAY_SYSTEM_NAME"] = $pay_system_name;
    $arFields["FULL_ADDRESS"] = "$country_name $city_name $street_name $house_name $flat_name";
    $arFields["USER_DESCRIPTION"] = $order["USER_DESCRIPTION"];
    
    // Формирование списка заказанных товаров
    if (CModule::IncludeModule('sale') && CModule::IncludeModule('iblock')) {
        $arFields['ORDER_LIST'] = '';

        $basket = CSaleBasket::GetList(
            ['NAME' => 'ASC'],
            ['ORDER_ID' => $orderID],
            false,
            false,
            ['PRODUCT_ID', 'ID', 'NAME', 'QUANTITY', 'PRICE', 'CURRENCY']
        );

        while ($db_el = $basket->GetNext()) {
            $article = '';

            $article_db_list = CIBlockElement::GetProperty(CATALOG_IBLOCK_ID, $db_el['PRODUCT_ID'], [], ['CODE' => 'EMARKET_ARTICLE']);
            if ($article_db_el = $article_db_list->GetNext()) {
                $article = $article_db_el['VALUE'];
            }

            $arFields['ORDER_LIST'] .=
                'Артикул: ' . $article . ', '
                . 'ID: ' . $db_el['ID'] . ', '
                . 'Название: ' . $db_el['NAME'] . ', '
                . 'Количество: ' . $db_el['QUANTITY'] . ', '
                . 'Стоимость: ' . SaleFormatCurrency($db_el['PRICE'], $db_el['CURRENCY'])
                . "\n";
        }
    }
}

Обработка полей и шаблона перед отправкой письма почтового события

function OnBeforeEventSendHandler(&$arFields, &$arTemplate) {
	// TODO
}
AddEventHandler('main', 'OnBeforeEventSend', 'OnBeforeEventSendHandler');