iliziumlion
7/19/2018 - 6:11 AM

Bitrix cheat sheets

Bitrix cheat sheets

Шаблон

Пролог/подключение языковых файлов (header.php/footer.php)
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
IncludeTemplateLangFile(__FILE__);
?>

Язык шаблона
<html lang="<?=LANGUAGE_ID?>">

Заголовки
<title><?$APPLICATION->ShowTitle();?></title>
<h1><?$APPLICATION->ShowTitle(false,false);?></h1>

Мета данные для head
<?$APPLICATION->ShowHead();?>

Панель в <body>
<?$APPLICATION->ShowPanel();?>

Стили
<?$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH.'/css/style.css');?>

Скрипты
<?$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH.'/js/script.js');?>

--
D7
--
<?
use Bitrix\Main\Page\Asset;
Asset::getInstance()->addJs(SITE_TEMPLATE_PATH . "/js/fix.js");
Asset::getInstance()->addCss(SITE_TEMPLATE_PATH . "/styles/fix.css");
Asset::getInstance()->addString("<link href='http://...' rel='stylesheet' type='text/css'>");
?>

Путь до шаблона
<?=SITE_TEMPLATE_PATH?>
_______________________________________________________________

Включаемая область
<?
$APPLICATION->IncludeComponent(
    "bitrix:main.include", 
    "", 
    array(
        "AREA_FILE_SHOW" => "sect", 
        "AREA_FILE_SUFFIX" => "inc", 
        "AREA_FILE_RECURSIVE" => "Y", 
        "EDIT_TEMPLATE" => ""
    ),
    false
);
?>

Из файла
<?
$APPLICATION->IncludeComponent(
    "bitrix:main.include",
    "",
    array(
        "AREA_FILE_SHOW" => "file",
        "AREA_FILE_SUFFIX" => "inc",
        "EDIT_TEMPLATE" => "",
        "PATH" => "/include/name.php"
    )
);
?>
_______________________________________________________________

Проверки url

<?
if ($GLOBALS["APPLICATION"]->GetCurPage() == "/") {} // если в корне

if (CSite::InDir('/about/')) {} // раздел и подразделы

if (strstr($GLOBALS["APPLICATION"]->GetCurPage(), "page")) {} // проверка на совпадение
?>
_______________________________________________________________

Свойства разделов/страницы

<?
if ($APPLICATION->GetProperty("FULL_WIDTH") == "Y") {}
?>

<?
$APPLICATION->SetPageProperty("keywords", "...");
?>
_______________________________________________________________

Фильтр для вывода элементов у которых значение свойства равно определенному значению

<?
global $arFilter;

$arFilter = array(
    "IBLOCK_ID" => 9,
    "ACTIVE" => "Y",
    "PROPERTY_NTV_VALUE" => "Да",
);
// в компоненте "FILTER_NAME" => "arFilter",
?>

Для свойств типа "список"
<?
$enum_list = CIBlockPropertyEnum::GetList(
    array("SORT" => "ASC", "NAME" => "ASC"), 
    array("IBLOCK_ID" => 2, "CODE" => "PROPNAME", "VALUE" => "да")
); 
$arEnumIsMain = $enum_list->GetNext(); 

global $arrFilter;
$arrFilter = array(
    "PROPERTY" => array("PROPNAME" => $arEnumIsMain["ID"])
);
?>
_______________________________________________________________

Пример фильтра для CIBlockElement::GetList по списку

<?
CIBlockElement::GetList(
    array(), // arOrder
    array(
        "IBLOCK_ID" => $arResult["IBLOCK_ID"], 
        "ACTIVE" => "Y", 
        "PROPERTY_SHOW_IN_POPULAR_VALUE" => array("Да")
    ), // arFilter
    false, // arGroupBy
    false, // arNavStartParams
    array() // arSelectFields
);
?>
_______________________________________________________________

Редактирование елементов

<?
$this->AddEditAction(
    $ar_result['ID'], 
    $arItem['EDIT_LINK'], 
    CIBlock::GetArrayByID($arParams['IBLOCK_ID'], "ELEMENT_EDIT")
);
$this->AddDeleteAction(
    $ar_result['ID'], 
    $arItem['DELETE_LINK'], 
    CIBlock::GetArrayByID($arParams['IBLOCK_ID'], "ELEMENT_DELETE"), 
    array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM'))
);
?>

<li id="<?=$this->GetEditAreaId($arItem['ID']);?>"></li>
_______________________________________________________________

Буферизация средствами php

<?
ob_start();
// Код компонента
$GLOBALS['NAME'] = ob_get_contents();
ob_end_clean();
// Вывод $GLOBALS['NAME']
?>
_______________________________________________________________

Буферизация средствами Bitrix

<?
$this->SetViewTarget('NAME');
// Код компонента...
$this->EndViewTarget();
// Вывод $APPLICATION->ShowViewContent("NAME");
?>
_______________________________________________________________

Навигация Следующая - Предыдущая статья.

result_modifier.php
<?
    $arSort = array(
        $arParams["SORT_BY1"] => $arParams["SORT_ORDER1"],
        $arParams["SORT_BY2"] => $arParams["SORT_ORDER2"],
    );
    $arSelect = array("ID", "NAME", "DETAIL_PAGE_URL");
    $arFilter = array (
        "IBLOCK_ID" => $arResult["IBLOCK_ID"],
        // Можно ограничить секцией
        // "SECTION_CODE" => $arParams["SECTION_CODE"], или "SECTION_ID" => $arResult["IBLOCK_SECTION_ID"],
        "ACTIVE" => "Y",
        "CHECK_PERMISSIONS" => "Y",
    );
    // выбирать по 1 соседу с каждой стороны от текущего
    $arNavParams = array(
        "nPageSize" => 1,
        "nElementID" => $arResult["ID"],
    );
    $arItems = array();
    $rsElement = CIBlockElement::GetList($arSort, $arFilter, false, $arNavParams, $arSelect);
    $rsElement->SetUrlTemplates($arParams["DETAIL_URL"]);

    while($obElement = $rsElement->GetNextElement())
        $arItems[] = $obElement->GetFields();
        
    if (count($arItems)==3):
        $arResult["TORIGHT"] = array("NAME" => $arItems[0]["NAME"], "URL" => $arItems[0]["DETAIL_PAGE_URL"]);
        $arResult["TOLEFT"] = array("NAME" => $arItems[2]["NAME"], "URL" => $arItems[2]["DETAIL_PAGE_URL"]);
    elseif (count($arItems)==2):
        if ($arItems[0]["ID"] != $arResult["ID"])
            $arResult["TORIGHT"] = Array("NAME" => $arItems[0]["NAME"], "URL" => $arItems[0]["DETAIL_PAGE_URL"]);
        else
            $arResult["TOLEFT"] = Array("NAME" => $arItems[1]["NAME"], "URL" => $arItems[1]["DETAIL_PAGE_URL"]);
    endif;
    // $arResult["TORIGHT"] и $arResult["TOLEFT"] массивы с информацией о соседних элементах
?>

Вывод в компоненте
<?
    if (is_array($arResult["TOLEFT"])) {
?>
        <a id="pre_page" href="<?=$arResult["TOLEFT"]["URL"]?>"> < <?=$arResult["TOLEFT"]["NAME"]?></a>
<?
    }
    if (is_array($arResult["TORIGHT"])) {
?>
        <a id="next_page" href="<?=$arResult["TORIGHT"]["URL"]?>"><?=$arResult["TORIGHT"]["NAME"]?> > </a>
<?
    }
?>
_______________________________________________________________

Путь к картинке по id

<?
$arOnePhoto = CFile::GetFileArray($PHOTO);
// $arOnePhoto['SRC']
?>
_______________________________________________________________

Если пoльзoвaтeль имeeт прaвa aдминистрaтoрa

<?
if ($USER->Isadmin()) {}
?>
_______________________________________________________________

Пoлучeниe кoличeствa тoвaрoв в нaличии

<?
$ar_res = CCatalogProduct::GetByID($arelement['ID']); 
// $ar_res['QUANTITY']
?>
_______________________________________________________________

Вывод пользовательского свойства раздела типа файл

<? 
$db_list = CIBlockSection::GetList(
    array($by => $order), 
    array("IBLOCK_ID" => 8, "ID" => $arSection['ID']), 
    true,
    array("UF_NAME_IMG")
);

while($ar_result = $db_list->GetNext()):   
    foreach($ar_result["UF_NAME_IMG"] as $PHOTO):
        echo CFile::GetPath($PHOTO);
    endforeach; 
endwhile;
?>

Вывод пользовательского свойства раздела типа список

<?
$sectionProps = array();
$db_list = CIBlockSection::GetList(
    array("SORT"=>"ASC"), 
    array("IBLOCK_ID" => $arResult["IBLOCK_ID"], "ID" => $arResult["ID"]), 
    true, 
    array("UF_PROPS")
);

while($ar_result = $db_list->GetNext()):   
    foreach($ar_result["UF_PROPS"] as $UF_ID):
        $rsEnum = CUserFieldEnum::GetList(array(), array("ID" => $UF_ID));
        $sectionProps[] = $rsEnum->GetNext();
    endforeach;
endwhile;
?>
_______________________________________________________________

Свойства элемента по id

<?
$db_props = CIBlockElement::GetProperty(IBLOCK_ID, ELEMENT_ID, "sort", "asc", array());
$PROPS = array();
while($ar_props = $db_props->Fetch())
    $PROPS[$ar_props['CODE']] = $ar_props['VALUE'];
?>
_______________________________________________________________

Замена стандартного выделения слов в поиске

\www\bitrix\modules\search\classes\general\search.php:317

$str_result = str_replace("%/^%", "</b>", str_replace("%^%","<b>", $str_result));
_______________________________________________________________

Получение элементов инфоблока

<?
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE");
$arFilter = Array("IBLOCK_ID" => 19, "ACTIVE_DATE" => "Y", "ACTIVE" => "Y");
$res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect);
while($ob = $res->GetNextElement()) {
    $arFields = $ob->GetFields();
    print_r($arFields);
}
?> 
_______________________________________________________________

AJAX подгрузка компонентов

<?
define('STOP_STATISTICS', true);
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
$GLOBALS['APPLICATION']->RestartBuffer();

[ajax code]
?>
_______________________________________________________________

Дополнительные пункты меню

.left.menu_ext.php

<?
if (CModule::IncludeModule("iblock")) {
    global $APPLICATION;
    $aMenuLinksExt = $APPLICATION->IncludeComponent(
        "bitrix:menu.sections",
        "",
        Array(
            "CACHE_TIME" => "3600",
            "CACHE_TYPE" => "A",
            "DEPTH_LEVEL" => "4",
            "DETAIL_PAGE_URL" => "#SECTION_CODE#/#ELEMENT_CODE#",
            "IBLOCK_ID" => "3",
            "IBLOCK_TYPE" => "content",
            "ID" => $_REQUEST["ID"],
            "IS_SEF" => "Y",
            "SECTION_PAGE_URL" => "#SECTION_CODE#/",
            "SECTION_URL" => "",
            "SEF_BASE_URL" => "/services/"
        )
    );
    $aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
}
?>

C элементами

<?
if (CModule::IncludeModule("iblock")) {

    $aMenuLinksNew = Array();
    $IBLOCK_ID = 3;
    $ctlg_sections = CIBlockSection::GetList(
        Array("ID" => "ASC", " ACTIVE" => "Y"),
        Array("IBLOCK_ID" => $IBLOCK_ID),
        true,
        Array('ID', 'NAME', 'CODE', 'DEPTH_LEVEL')
    );

    while ($ar_fields = $ctlg_sections->GetNext()) {

        array_push(
            $aMenuLinksNew, 
            array(
                $ar_fields['NAME'], 
                $ar_fields['CODE']."/", 
                array(), 
                array(
                    "FROM_IBLOCK" => "1", 
                    "IS_PARENT" => $ar_fields['ELEMENT_CNT'], 
                    "DEPTH_LEVEL" => $ar_fields["DEPTH_LEVEL"]
                ), 
                "",
            ) 
        );

        // elements
        $arSelect = array("ID", "NAME", "CODE");
        $arFilter = array(
            "IBLOCK_ID"=> $IBLOCK_ID, 
            "SECTION_ID" => $ar_fields['ID'], 
            "ACTIVE_DATE"=>"Y", 
            "ACTIVE"=>"Y"
        );
        $res = CIBlockElement::GetList(array(), $arFilter, false, array("nPageSize" => 5000), $arSelect);
        while ($ob = $res->GetNextElement()) {
            $arFields = $ob->GetFields();
            array_push(
                $aMenuLinksNew, 
                array(
                    $arFields['NAME'], 
                    $ar_fields['CODE']."/".$arFields['CODE']."/", 
                    array(), 
                    array(
                        "FROM_IBLOCK"=>"1", 
                        "IS_PARENT"=>"", 
                        "DEPTH_LEVEL"=>"2"
                    ), 
                    "",
                )
            );
        }
 
    }

    $aMenuLinks = array_merge($aMenuLinksNew, $aMenuLinks);
}
?>
____________________________________________________________

Image resize

<?
$arFilters = array(
    array(
        "name" => "watermark", 
        "position" => "tr", 
        "size" => "small", 
        "file" => $_SERVER["DOCUMENT_ROOT"]."/waterm.png"
    )
);  //если нужен водяной знак

// НЕ пропорционально
$renderImage = CFile::ResizeImageGet(
    $PHOTO, 
    array("width" => 200, "height" => 200), 
    $resizeType = BX_RESIZE_IMAGE_EXACT, 
    $bInitSizes = false, 
    $arFilters
); 

// пропорционально
$renderImage = CFile::ResizeImageGet(
    $PHOTO, 
    array("width" => 1200, "height" => 1000), 
    $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL, 
    $bInitSizes = false, 
    $arFilters
);

// $renderImage['src']
?>
_______________________________________________________________

Пример news.list с вкладками и бесконечной подгрузкой по кнопке

portfolio.php
<?
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");
if (isset($_GET['idtab'])) $idtab = $_GET['idtab']; // id активного раздела (для фильтра)
?>

<?$APPLICATION->IncludeComponent(
    "bitrix:news.list",
    "portfolio",
    Array(
        "ACTIVE_DATE_FORMAT" => "d.m.Y",
        "ADD_SECTIONS_CHAIN" => "N",
        "AJAX_MODE" => "N",
        "AJAX_OPTION_ADDITIONAL" => "",
        "AJAX_OPTION_HISTORY" => "N",
        "AJAX_OPTION_JUMP" => "N",
        "AJAX_OPTION_STYLE" => "Y",
        "CACHE_FILTER" => "N",
        "CACHE_GROUPS" => "Y",
        "CACHE_TIME" => "36000000",
        "CACHE_TYPE" => "A",
        "CHECK_DATES" => "Y",
        "COMPONENT_TEMPLATE" => "portfolio",
        "DETAIL_URL" => "",
        "DISPLAY_BOTTOM_PAGER" => "Y", // для генерации PAGER_ 
        "DISPLAY_DATE" => "Y",
        "DISPLAY_NAME" => "Y",
        "DISPLAY_PICTURE" => "Y",
        "DISPLAY_PREVIEW_TEXT" => "Y",
        "DISPLAY_TOP_PAGER" => "N",
        "FIELD_CODE" => array(0=>"",1=>"",),
        "FILTER_NAME" => "",
        "HIDE_LINK_WHEN_NO_DETAIL" => "N",
        "IBLOCK_ID" => "8",
        "IBLOCK_TYPE" => "design",
        "INCLUDE_IBLOCK_INTO_CHAIN" => "N",
        "INCLUDE_SUBSECTIONS" => "Y",
        "MESSAGE_404" => "",
        "NEWS_COUNT" => "6",
        "PAGER_BASE_LINK_ENABLE" => "N",
        "PAGER_DESC_NUMBERING" => "N",
        "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000",
        "PAGER_SHOW_ALL" => "N",
        "PAGER_SHOW_ALWAYS" => "N",
        "PAGER_TEMPLATE" => ".default",
        "PAGER_TITLE" => "Новости",
        "PARENT_SECTION" => $idtab, // фильтр по конкретному разделу
        "PARENT_SECTION_CODE" => "",
        "PREVIEW_TRUNCATE_LEN" => "",
        "PROPERTY_CODE" => array(0=>"",1=>"",),
        "SET_BROWSER_TITLE" => "N",
        "SET_LAST_MODIFIED" => "N",
        "SET_META_DESCRIPTION" => "N",
        "SET_META_KEYWORDS" => "N",
        "SET_STATUS_404" => "N",
        "SET_TITLE" => "N",
        "SHOW_404" => "N",
        "SORT_BY1" => "ACTIVE_FROM",
        "SORT_BY2" => "SORT",
        "SORT_ORDER1" => "DESC",
        "SORT_ORDER2" => "ASC"
    )
);?>

template.php

<?
foreach($arResult["ITEMS"] as $arItem):
    $this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
    $this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
    ?>
    <div id="<?=$this->GetEditAreaId($arItem['ID']);?>"><?=$arItem["NAME"]?></div>
<?
endforeach;
?>

index.php с компонентом

<?
CModule::IncludeModule("iblock");
$newsCounter = CIBlockElement::GetList(array(), array("IBLOCK_ID" => 8, "ACTIVE" => "Y"), array());
?>
<div class="ptabs ptabs_active" data-id="" data-count="<?=$newsCounter?>">Все</div>
<?
$ptabs = CIBlockSection::GetList(array($by=>$order), array('IBLOCK_ID' => 8, 'GLOBAL_ACTIVE' => 'Y'), true);
while ($ar_result = $ptabs->GetNext()) {
    $newsCounter = CIBlockElement::GetList(
        array(), array("IBLOCK_ID" => 8, "ACTIVE" => "Y", "SECTION_ID"=>$ar_result['ID']), array()
    );
    ?>
    <div class="ptabs" data-id="<?=$ar_result['ID']?>" data-count="<?=$newsCounter?>">
        <?=$ar_result['NAME']?> (id:<?=$ar_result['ID']?>)
    </div>
    <?
}
?>

<div>
    <div class="potfolio__list"><?$APPLICATION->IncludeFile("/portfolio.php");?></div>  
    <a href="#" class="show-more">Показать еще</a>
</div>

script.js

<script>
$(document).ready(function(){
    function checkCount(cnt){
        if (currentPage * 6 >= cnt) {
            $('.show-more').hide();
        } else {
            $('.show-more').show();
        }
    }
    var currentPage = 1;
    var path = '/portfolio.php?ajax=Y';
    var count = $('.ptabs_active').data('count');
    checkCount(count);
    $('.ptabs').on('click', function() {
        $('.preloader').fadeIn(0);
        $('.ptabs').removeClass('ptabs_active');
        $(this).addClass('ptabs_active');
        var idtab = $(this).data('id');
        $.get(path, {idtab: idtab}, function(data) {
            $('.potfolio__list').html(data);
            count = $('.ptabs_active').data('count');
            currentPage = 1;
            checkCount(count);
            setTimeout(function() {
                $('.preloader').fadeOut(100);
            }, 500);
        });
    });

    $('.show-more').click(function(e) {
        $('.preloader').fadeIn(0);
        var idtab = $('.ptabs_active').data('id');
        $.get(path, {PAGEN_1: ++currentPage, idtab:idtab}, function(data){
            $('.potfolio__list').append(data);
            checkCount(count);
            setTimeout(function(){
                $('.preloader').fadeOut(100);
            }, 500);
        });
        e.preventDefault();
    });
}
</script>

Если нет возможности узнать общее кол-во (например умный фильтр со scu) проще скрывать по условию:

<?
if ($arResult["NAV_RESULT"]->nEndPage > 1 && $arResult["NAV_RESULT"]->NavPageNomer < $arResult["NAV_RESULT"]->nEndPage):
?>
Показать еще
<?endif;?>
_______________________________________________________________

Получить поля SEO для элемента

<?
CModule::IncludeModule("iblock");
$ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues(
    $arCurElem["IBLOCK_ID"], // ID инфоблока
    $arCurElem["ID"] // ID элемента
);
$arElMetaProp = $ipropValues->getValues();
echo '<pre>'; print_r ($arElMetaProp); echo '</pre>';
?>

Поля SEO для раздела

<?
CModule::IncludeModule("iblock");
 
$rsSection = CIBlockSection::GetList(
    array(),
    array(
        "IBLOCK_ID"=>$arParams['IBLOCK_ID'],
        "ACTIVE"=>"Y",
        "=CODE"=>$arParams["SECTION_CODE"]
    ),
    false
);
 
if($arSection = $rsSection->GetNext()){
 
    $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues(
        $arSection["IBLOCK_ID"],
        $arSection["ID"]
    );
    $arSection["IPROPERTY_VALUES"] = $ipropValues->getValues();
    echo "<pre>"; print_r($arSection); echo '</pre>';
}
?>
_______________________________________________________________

Получение всего списка highload блоков

<?
use Bitrix\Highloadblock\HighloadBlockTable as HLBT;
$MY_HL_BLOCK_ID = 3;
CModule::IncludeModule('highloadblock');
function GetEntityDataClass($HlBlockId) {
    if (empty($HlBlockId) || $HlBlockId < 1) return false;
    $hlblock = HLBT::getById($HlBlockId)->fetch();   
    $entity = HLBT::compileEntity($hlblock);
    $entity_data_class = $entity->getDataClass();
    return $entity_data_class;
}
$entity_data_class = GetEntityDataClass($MY_HL_BLOCK_ID);
$rsData = $entity_data_class::getList(array(
   'select' => array('*')
));
while ($el = $rsData->fetch()) {
    print_r($el);
}
?>

или

<?
if (CModule::IncludeModule('highloadblock')) {
    $Date = date(CDatabase::DateFormatToPHP(FORMAT_DATETIME));
    $arHLBlock = Bitrix\Highloadblock\HighloadBlockTable::getById(3)->fetch();
    $obEntity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($arHLBlock);
    $strEntityDataClass = $obEntity->getDataClass();
    $resData = $strEntityDataClass::getList(array(
        'select' => array('*'),
    ));
    while ($arItem = $resData->Fetch()) {
        echo "<pre>"; print_r($arItem); echo "</pre>";
    }
}
?>
_______________________________________________________________

Добавление номера страницы в title

каталог/section.php
<?
    CModule::IncludeModule("iblock");
    $arSection = array();
    if ($arResult["VARIABLES"]["SECTION_ID"]>0) {
        $arFilter = array('IBLOCK_ID'=>$arParams["IBLOCK_ID"], 'GLOBAL_ACTIVE'=>'Y', "ID" => $arResult["VARIABLES"]["SECTION_ID"]);
    } elseif(strlen(trim($arResult["VARIABLES"]["SECTION_CODE"]))>0) {
      $arFilter = array('IBLOCK_ID'=>$arParams["IBLOCK_ID"], 'GLOBAL_ACTIVE'=>'Y', "=CODE" => $arResult["VARIABLES"]["SECTION_CODE"]);
    }
    $db_list = CIBlockSection::GetList(array(), $arFilter, true, array("ID", "NAME", "IBLOCK_ID", "DEPTH_LEVEL", "IBLOCK_SECTION_ID", "CODE"));

    while($section = $db_list->GetNext())
        $arSection = $section;

    $arSelect = array("ID");

    if ($arParams["LIST_BROWSER_TITLE"]) $arSelect = array_merge($arSelect, (array)$arParams["LIST_BROWSER_TITLE"]);
    if ($arParams["LIST_META_KEYWORDS"]) $arSelect = array_merge($arSelect, (array)$arParams["LIST_META_KEYWORDS"]);
    if ($arParams["LIST_META_DESCRIPTION"]) $arSelect = array_merge($arSelect, (array)$arParams["LIST_META_DESCRIPTION"]);

    $arSectionFull = CIBlockSection::GetList(
        array(), 
        array("ID" => $arSection["ID"], "IBLOCK_ID"=> $arSection["IBLOCK_ID"]), 
        false, 
        $arSelect, 
        false
    )->GetNext();

    if ($_GET["PAGEN_1"]) $page = GetMessage('PAGE').$_GET["PAGEN_1"];

    if ($arParams["LIST_BROWSER_TITLE"] && $arSectionFull[$arParams["LIST_BROWSER_TITLE"]]) $APPLICATION->SetPageProperty("title", $arSectionFull[$arParams["LIST_BROWSER_TITLE"]].$page);

    // new title
    $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues(
        $arSection["IBLOCK_ID"],
        $arSection["ID"]
    );
    
    $arSection["IPROPERTY_VALUES"] = $ipropValues->getValues();
    $APPLICATION->SetPageProperty("title", $arSection["IPROPERTY_VALUES"]["SECTION_META_TITLE"].$page);
?>

Детальная

<?
if(CModule::IncludeModule("iblock")){
    $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues(
        $arParams['IBLOCK_ID'],
        $ElementID
    );
    
    $arElMetaProp = $ipropValues->getValues();

    $title = $arElMetaProp["ELEMENT_META_TITLE"] ? $arElMetaProp["ELEMENT_META_TITLE"] : $APPLICATION->GetTitle();
    $description = $arElMetaProp["ELEMENT_META_DESCRIPTION"] ? $arElMetaProp["ELEMENT_META_DESCRIPTION"] : $APPLICATION->GetProperty("description");

    if($_GET["PAGEN_2"]){
        $APPLICATION->SetPageProperty('title', $title.". Страница ".$_GET["PAGEN_2"].".");
        $APPLICATION->SetPageProperty('description', $description.". Страница ".$_GET["PAGEN_2"].".");
    }
}
?>
_______________________________________________________________

HTTPS

dbconn.php
$_SERVER["HTTPS"] = "On";
_______________________________________________________________

CAPTCHA

template.php

<?
$code =  $APPLICATION->CaptchaGetCode();
?>
<img src="/bitrix/tools/captcha.php?captcha_code=<?=$code?>">
<input id="captcha_word" name="captcha_word" type="text" placeholder="Введите слово на картинке">
<input name="captcha_code" value="<?=$code?>" type="hidden">

Проверка

<?
if (!$APPLICATION->CaptchaCheckCode($_POST["captcha_word"], $_POST["captcha_code"])) {
    // Неправильное значение
} else {
    // Правильное значение
}
?>

Пример обновления

<div class="captcha__update">обновить картинку</div>
<script>
$('.captcha__update').click(function(){
    $.getJSON('<?=$path?>/reload_captcha.php', function(data) {
         $('.captcha__img').attr('src','/bitrix/tools/captcha.php?captcha_sid='+data);
         $('.captcha__validate').val(data);
    });
});
</script>

reload_captcha.php
<?
echo json_encode($APPLICATION->CaptchaGetCode());
?>
_______________________________________________________________

Вывод переменных до их определения

Добавляем ссылку в h1 в шаблоне компонента header.php:
<?$APPLICATION->ShowViewContent('news');?><!-- content -->

Добавляем в шаблон компонента:
<?$this->SetViewTarget('news');?>
    <!-- content -->
<?$this->EndViewTarget();?>
_______________________________________________________________

Генерация url с заменой параметров и сохранением старых

<?=$APPLICATION->GetCurPageParam ('sort=price&method=asc', array('sort', 'method'))?>
_______________________________________________________________

Добавление полей к шаблону письма

<?
AddEventHandler("sale", "OnOrderNewSendEmail", "bxModifySaleMails");

function bxModifySaleMails($orderID, &$eventName, &$arFields)
{
    $arOrder = CSaleOrder::GetByID($orderID);

    $order_props = CSaleOrderPropsValue::GetOrderProps($orderID);

    $city_name = "";  
    $address = "";

    while ($arProps = $order_props->Fetch()){

        if ($arProps["CODE"] == "PHONE") $phone = htmlspecialchars($arProps["VALUE"]);

        if ($arProps["CODE"] == "INDEX") $index = $arProps["VALUE"];   
        if ($arProps["CODE"] == "ADDRESS") $address = $arProps["VALUE"];

        if ($arProps["CODE"] == "LOCATION") {
            $arLocs = CSaleLocation::GetByID($arProps["VALUE"]);
            $country_name =  $arLocs["COUNTRY_NAME_ORIG"];
            $city_name = $arLocs["CITY_NAME_ORIG"];
        }

        /* юр лицо */
        if ($arProps["CODE"] == "COMPANY") $company = $arProps["VALUE"];  
        if ($arProps["CODE"] == "COMPANY_ADR") $company_adr = $arProps["VALUE"];
        if ($arProps["CODE"] == "INN") $inn = $arProps["VALUE"];
        if ($arProps["CODE"] == "KPP") $kpp = $arProps["VALUE"];
        if ($arProps["CODE"] == "CONTACT_PERSON") $contact_person = $arProps["VALUE"];
        if ($arProps["CODE"] == "FAX") $fax = $arProps["VALUE"];
    }

    // служба доставки
    $arDeliv = CSaleDelivery::GetByID($arOrder["DELIVERY_ID"]);
    if ($arDeliv) $delivery_name = $arDeliv["NAME"];

    // получаем название платежной системы   
    $arPaySystem = CSalePaySystem::GetByID($arOrder["PAY_SYSTEM_ID"]);
    if ($arPaySystem) $pay_system_name = $arPaySystem["NAME"];

    // добавляем новые поля в массив результатов
    $arFields["ORDER_DESCRIPTION"] = $arOrder["USER_DESCRIPTION"] ? $arOrder["USER_DESCRIPTION"] : "-";
    $arFields["PHONE"] =  $phone ? $phone : "-";
    $arFields["DELIVERY_NAME"] =  $delivery_name ? $delivery_name : "-";
    $arFields["PAY_SYSTEM_NAME"] =  $pay_system_name ? $pay_system_name : "-";
    $arFields["FULL_ADDRESS"] = $city_name." ".$address;

    $arFields["COMPANY"] = $company ? $company : "-";
    $arFields["COMPANY_ADR"] = $company_adr ? $company_adr : "-";
    $arFields["INN"] = $inn ? $inn : "-";
    $arFields["KPP"] = $kpp ? $kpp : "-";
    $arFields["CONTACT_PERSON"] = $contact_person ? $contact_person : "-";
    $arFields["FAX"] = $fax ? $fax : "-";

}
?>
_______________________________________________________________

Размещаем некэшируемую область в кэшируемом компоненте

result_modifier.php

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?$this->__component->SetResultCacheKeys(array("CACHED_TPL"));?>

component_epilog.php

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?
echo preg_replace_callback(
    "/#VOTE_ID_([\d]+)#/is".BX_UTF_PCRE_MODIFIER,
    create_function('$matches', 
        'ob_start();
        /*тут код который не хотим кэшировать*/
        $retrunStr = @ob_get_contents();
        ob_get_clean();
        return $retrunStr;'
    ),
    $arResult["CACHED_TPL"]
);
?>

(в некэшируемом коде вместо обычного $APPLICATION пишем $GLOBALS["APPLICATION"], для видимости объекта внутри временной функции)

template.php

В начало
<?ob_start();?>
В конец
<?
$this->__component->arResult["CACHED_TPL"] = @ob_get_contents();
ob_get_clean();
?>

добавляем маркер
<? echo "#VOTE_ID_1#"; ?>
(регулярка #VOTE_ID_([\d]+)# для примера, удобно использовать $matches[1] для ID и т.п.)
_______________________________________________________________

AJAX сравнение

header.php

<script>
    var SITE_DIR = '<?=SITE_DIR?>';
    var CATALOG_COMPARE_LIST = new Object();
    CATALOG_COMPARE_LIST.defaultText = "Сравнить";
    CATALOG_COMPARE_LIST.activeText = "В сравнении";
</script>
<?// сравнение
foreach ($_SESSION["CATALOG_COMPARE_LIST"][2]["ITEMS"] as $value) { 
    ?>
    <script>CATALOG_COMPARE_LIST[<?=$value["ID"]?>] = true;</script>    
    <?
}
?>

template.php

В начало
<?ob_start();?>
В конец
<?
$this->__component->arResult["CACHED_TPL"] = @ob_get_contents();
ob_get_clean();
?>
Маркер
<? echo "#COMPARE_FAV_ID_".$arItem['ID']."#"; ?>

component_epilog.php 

<?
echo preg_replace_callback(
    "/#COMPARE_FAV_ID_([\d]+)#/is".BX_UTF_PCRE_MODIFIER,
    create_function('$matches', 
        'ob_start();
        ?>
        <div class="btn-c">
            <a href="#" class="add-compare ctrl-radio <?if(!empty($_SESSION["CATALOG_COMPARE_LIST"][2]["ITEMS"][$matches[1]])):?> ctrl-radio_checked<?endif?>" data-id="<?=$matches[1]?>" >
                <i class="ctrl-radio__ico"></i>
                <span class="add-compare__ttl">
                    <?if (!empty($_SESSION["CATALOG_COMPARE_LIST"][2]["ITEMS"][$matches[1]])):?>
                        В сравнении
                    <?else:?>
                        Сравнить
                    <?endif?>
                </span>
            </a>
        </div>
        <?
        $returnStr = @ob_get_contents();
        ob_get_clean();
        return $returnStr;'
    ),
$arResult["CACHED_TPL"]);
?>

result_modifier.php

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?$this->__component->SetResultCacheKeys(array("CACHED_TPL"));?>

script.js 

<script>
    // compare
    $('body').on('click', '.add-compare', function(e){
        e.preventDefault();

        var compareButton = $(this),
            product_id = compareButton.data('id');

        if (CATALOG_COMPARE_LIST[product_id]) {
            compareButton.removeClass('ctrl-radio_checked').find('.add-compare__ttl').text(CATALOG_COMPARE_LIST.defaultText);
            $.ajax({
                url: SITE_DIR + 'catalog/?action=DELETE_FROM_COMPARE_LIST&id=' + product_id,
                type: 'post',
                success: function (data) {
                    $('.bx_catalog-compare-list').replaceWith(data);
                }
            });
            delete CATALOG_COMPARE_LIST[product_id];
        } else {
            compareButton.addClass('ctrl-radio_checked').find('.add-compare__ttl').text(CATALOG_COMPARE_LIST.activeText);
            $.ajax({
                url: SITE_DIR + 'catalog/?action=ADD_TO_COMPARE_LIST&id=' + product_id,
                type: 'post',
                success: function (data) {
                    $('.bx_catalog-compare-list').replaceWith(data);
                }
            });
            CATALOG_COMPARE_LIST[product_id] = true;
        }
    });

    $('body').on('click', '.bx_catalog_compare_form [data-id]', function() {
        var delId = $(this).data('id');
        delete CATALOG_COMPARE_LIST[delId];
        $('.add-compare[data-id='+delId+']').removeClass('ctrl-radio_checked').find('.add-compare__ttl').text(CATALOG_COMPARE_LIST.defaultText);
    });
</script>

sections.php

<?
if ($_REQUEST["action"]=="ADD_TO_COMPARE_LIST" || $_REQUEST["action"]=="DELETE_FROM_COMPARE_LIST") {
    $APPLICATION->RestartBuffer();
    if ($arParams["USE_COMPARE"]=="Y") {
        $APPLICATION->IncludeComponent(
            "bitrix:catalog.compare.list",
            "",
            array(
                "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
                "IBLOCK_ID" => $arParams["IBLOCK_ID"],
                "NAME" => $arParams["COMPARE_NAME"],
                "DETAIL_URL" => $arResult["FOLDER"].$arResult["URL_TEMPLATES"]["element"],
                "COMPARE_URL" => $arResult["FOLDER"].$arResult["URL_TEMPLATES"]["compare"],

            ),
            $component
        );
    }
    die();
}
?>
_______________________________________________________________

AJAX избранное

header.php

<script>
    var SITE_DIR = '<?=SITE_DIR?>';
    var DELAY_LIST = new Object();
</script>

template.php

В начало
<?ob_start();?>
В конец
<?
$this->__component->arResult["CACHED_TPL"] = @ob_get_contents();
ob_get_clean();
?>
Маркер
<? echo "#COMPARE_FAV_ID_".$arItem['ID']."#"; ?>

component_epilog.php

<?
echo preg_replace_callback(
    "/#COMPARE_FAV_ID_([\d]+)#/is".BX_UTF_PCRE_MODIFIER,
    create_function('$matches', 'ob_start();
    ?>
        <? global $favourites; ?>
        <a href="#" class="b-popular-tiles__fav btn-fav add-delay<?
            if (in_array($matches[1], $favourites)):
                ?> btn-fav_active js-check_checked<?
            endif;
            ?>" data-id="<?=$matches[1]?>">
                <i class="icon png-icons btn-fav__ico"></i>
                <span class="add-delay__ttl">
                    <?if (in_array($matches[1], $favourites)):?>
                        В избранном
                    <?else:?>
                        В избранное
                    <?endif?>
                </span>
        </a>
    <?
    $returnStr = @ob_get_contents();
    ob_get_clean();
    return $returnStr;'),
$arResult["CACHED_TPL"]);
?>

result_modifier.php

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?$this->__component->SetResultCacheKeys(array("CACHED_TPL"));?>

script.js

<script>

    $('body').on('click', '.add-delay', function(e){
        e.preventDefault();

        var delayButton = $(this),
            product_id = delayButton.data('id'),
            productPrice = parseFloat(delayButton.parents('.product-item').find('.cur-price').text().replace(/ /g,''));

        if (DELAY_LIST[product_id]) {
            delayButton.removeClass('btn-fav_active js-check_checked').find('.add-delay__ttl').html('В избранное');
            $.post(SITE_DIR + 'ajax/addDelay.php?action=DELAY_DELETE&id=' + product_id);
            delete DELAY_LIST[product_id];
        } else {
            delayButton.addClass('btn-fav_active js-check_checked').find('.add-delay__ttl').html('В избранном');
            $.post(SITE_DIR + 'ajax/addDelay.php?action=DELAY_ADD&id=' + product_id + '&PRICE=' + productPrice);
            DELAY_LIST[product_id] = true;
        }

        $('#head-favourite__info').html(Object.keys(DELAY_LIST).length);
    });

</script>

ajax/addDelay.php

<? 
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

if (CModule::IncludeModule("sale") && CModule::IncludeModule("catalog") && CModule::IncludeModule("iblock")) {

    $productID = htmlspecialchars($_REQUEST["id"]);
    $productPrice = htmlspecialchars($_REQUEST["PRICE"]);

    if ($_REQUEST['action'] == 'DELAY_ADD') {
        $res = CIBlockElement::GetList(Array(), array("ID" => $productID), false, Array(), array("NAME"));
        if ($ob = $res->Fetch())
            $name = $ob['NAME'];

        // $ar_res = CPrice::GetBasePrice($productID);

        $arFields = array(
            "PRODUCT_ID" => $productID,
            "PRICE" => $productPrice,
            "CURRENCY" => 'RUB',
            // "PRICE" => $ar_res["PRICE"],            
            // "CURRENCY" => $ar_res["CURRENCY"],
            "QUANTITY" => 1,
            "LID" => LANG,
            "DELAY" => "Y",
            "NAME" => $name,
        );

        CSaleBasket::Add($arFields);
    }

    if ($_REQUEST['action'] == 'DELAY_DELETE') {
        $arFilter = array(
            "FUSER_ID" => CSaleBasket::GetBasketUserID(),
            "LID" => SITE_ID,
            "ORDER_ID" => "NULL",
            "DELAY" => "Y",
            "PRODUCT_ID" => $productID,
        );

        $dbBasketItems = CSaleBasket::GetList(array(), $arFilter, false, false, array("ID"));
        if ($arItems = $dbBasketItems->Fetch()) {
            CSaleBasket::Delete($arItems['ID']);
        }
    }

    $cntDelay = array();
    $dbBasketItems = CSaleBasket::GetList(array(), array("FUSER_ID" => CSaleBasket::GetBasketUserID(), "LID" => SITE_ID, "ORDER_ID" => "NULL", "DELAY" => "Y"), false, false, array("ID"));
    while ($arItems = $dbBasketItems->Fetch()) {
        $cntDelay[] = $arItems;
    }

    echo count($cntDelay);

}
?>
_______________________________________________________________

Добавление доп свойств к заказу

catalog.element script.js
<script>
function getServices(){
    var services = 'получаем свойства';
    return services;
}

window.JCCatalogElement.prototype.SendToBasket = function()
{
    if (!this.canBuy)
        return;

    this.InitBasketUrl();
    this.FillBasketProps();

    /* доп свойства */
    this.basketParams.addServices = getServices();

    BX.ajax.loadJSON(
        this.basketUrl,
        this.basketParams,
        BX.proxy(this.BasketResult, this)
    );

};
</script>

init.php

<?
AddEventHandler("sale", "OnOrderNewSendEmail", "bxModifySaleMails");
function bxModifySaleMails($orderID, &$eventName, &$arFields)
{

    $additional_information = '';

    $cntBasketItems = CSaleBasket::GetList(
        array(
            "NAME" => "ASC",
            "ID" => "ASC"
        ),
        array(
            "ORDER_ID" => $orderID
        ), 
        false,
        false,
        array()
    );

    $itemIds = array();
    $itemNames = array();

    while ($arItems = $cntBasketItems->Fetch()){
        $itemIds[] = $arItems["ID"];
        $itemNames[$arItems["ID"]] = $arItems["NAME"];
    }
    
    if(!empty($itemIds)) $additional_information .= "Дополнительные услуги:<br>";

    $db_res = CSaleBasket::GetPropsList(
        array(),
        array("ORDER_ID" => $orderID, "BASKET_ID"=>$itemIds,"CODE"=>"ST_ADD_SERV")
    );

    while ($ar_res = $db_res->Fetch()) {

        $additional_information .= $itemNames[$ar_res["BASKET_ID"]]." : ".$ar_res["VALUE"]."<br>";

    }

    $arFields["ADDITIONAL_INFORMATION"] = $additional_information;

    $arOrder = CSaleOrder::GetByID($orderID);
    $order_props = CSaleOrderPropsValue::GetOrderProps($orderID);
    
    $full_address = "";

    while ($arProps = $order_props->Fetch()){
        if ($arProps["CODE"] == "COMPANY") $company = htmlspecialchars($arProps["VALUE"]);

        if ($arProps["CODE"] == "EMAIL") $email = htmlspecialchars($arProps["VALUE"]);

        if ($arProps["CODE"] == "PHONE") $phone = htmlspecialchars($arProps["VALUE"]);

        if ($arProps["CODE"] == "LOCATION") {
            $arLocs = CSaleLocation::GetByID($arProps["VALUE"]);
            if($arLocs["COUNTRY_NAME_ORIG"]) $full_address .= $arLocs["COUNTRY_NAME_ORIG"];
            if($arLocs["REGION_NAME_ORIG"]) $full_address .= ", ".$arLocs["REGION_NAME_ORIG"];
            //if($arLocs["CITY_NAME_ORIG"]) $full_address .= ", ".$arLocs["CITY_NAME_ORIG"];

            $parameters = array();
            $parameters['filter']['=CODE'] = $arLocs["CODE"];
            $parameters['filter']['NAME.LANGUAGE_ID'] = "ru";
            $parameters['limit'] = 1;
            $parameters['select'] = array('LNAME' => 'NAME.NAME');
            $arVal = Bitrix\Sale\Location\LocationTable::getList( $parameters )->fetch();
            if($arVal[ 'LNAME' ]) $full_address .= ", ".$arVal[ 'LNAME' ];
        }

        if ($arProps["CODE"] == "ADDRESS") $address = $arProps["VALUE"];

        if ($arProps["CODE"] == "REQUISITES") {
            $requisites = "";
            if (!empty($arProps["VALUE"])) {
                $files = explode(", ",$arProps["VALUE"]);
                foreach ($files as $file) {
                    $requisites .= "<a href='".SITE_SERVER_NAME.CFile::GetPath($file)."'>Скачать</a><br>";
                }
            }
        }
    }

    // тип плательщика
    $db_ptype = CSalePersonType::GetList(Array("SORT" => "ASC"), Array("LID"=>SITE_ID));
    while ($ptype = $db_ptype->Fetch())
        if($ptype["ID"]==$arOrder["PERSON_TYPE_ID"]) $personType = $ptype["NAME"];

    // название службы доставки
    $arDeliv = CSaleDelivery::GetByID($arOrder["DELIVERY_ID"]);
    if ($arDeliv) $delivery_name = $arDeliv["NAME"];

    // название платежной системы   
    $arPaySystem = CSalePaySystem::GetByID($arOrder["PAY_SYSTEM_ID"]);
    if ($arPaySystem) $pay_system_name = $arPaySystem["NAME"];

    // добавляем новые поля в массив результатов
    $arFields["ORDER_DESCRIPTION"] = "Комментарий: ".$arOrder["USER_DESCRIPTION"]."<br>";
    $arFields["ORDER_P_TYPE"] = "Тип плательщика: ".$personType."<br>";
    $arFields["ORDER_PHONE"] = "Телефон: ".$phone."<br>";
    $arFields["ORDER_EMAIL"] = "E-mail: ".$email."<br>";
    $arFields["DELIVERY_NAME"] = "Доставка: ".$delivery_name."<br>";
    $arFields["PAY_SYSTEM_NAME"] = "Оплата: ".$pay_system_name."<br>";
    $arFields["ADDRESS"] = "Адрес доставки: ".$address."<br>";
    $arFields["FULL_ADDRESS"] = "Местоположение: ".$full_address."<br>";
    $arFields["COMPANY"] = "Компания: ".$company."<br>";
    $arFields["REQUISITES"] = "Реквизиты: ".$requisites."<br>";
}
?>

в старых версиях создаем новый компонент
/bitrix/components/site-hit/catalog.element/component.php

<?
if ($successfulAdd) {
    if ($_REQUEST["addServices"]) {
        $product_properties[] = array(
            "NAME" => "Дополнительные услуги",
            "CODE" => "ST_ADD_SERV",
            "VALUE" => $_REQUEST["addServices"],
            "SORT" => "1000"
        );
    }
    if (!Add2BasketByProductID($productID, $QUANTITY, $arRewriteFields, $product_properties)) {
        if ($ex = $APPLICATION->GetException())
            $strError = $ex->GetString();
        else
            $strError = GetMessage("CATALOG_ERROR2BASKET");
        $successfulAdd = false;
    }
}
?>

в новых версиях создаем новый компонент и наследуем от /bitrix/modules/iblock/lib/component/base.php
class CatalogElementComponent extends Element

<?
    protected function addProductToBasket($productId, $action)
    {
        /** @global \CMain $APPLICATION */
        global $APPLICATION;

        $successfulAdd = true;
        $errorMsg = '';

        $quantity = 0;
        $productProperties = array();
        $iblockId = (int)\CIBlockElement::GetIBlockByID($productId);

        if ($iblockId > 0)
        {
            $productCatalogInfo = \CCatalogSku::GetInfoByIBlock($iblockId);
            if (!empty($productCatalogInfo) && $productCatalogInfo['CATALOG_TYPE'] == \CCatalogSku::TYPE_PRODUCT)
            {
                $productCatalogInfo = false;
            }
            if (!empty($productCatalogInfo))
            {
                if ($this->arParams['ADD_PROPERTIES_TO_BASKET'] === 'Y')
                {
                    $productIblockId = ($productCatalogInfo['CATALOG_TYPE'] == \CCatalogSku::TYPE_CATALOG
                        ? $productCatalogInfo['IBLOCK_ID']
                        : $productCatalogInfo['PRODUCT_IBLOCK_ID']
                    );
                    $iblockParams = $this->storage['IBLOCK_PARAMS'][$productIblockId];
                    if ($productCatalogInfo['CATALOG_TYPE'] !== \CCatalogSku::TYPE_OFFERS)
                    {
                        if (!empty($iblockParams['CART_PROPERTIES']))
                        {
                            $productPropsVar = $this->request->get($this->arParams['PRODUCT_PROPS_VARIABLE']);
                            if (is_array($productPropsVar))
                            {
                                $productProperties = \CIBlockPriceTools::CheckProductProperties(
                                    $productIblockId,
                                    $productId,
                                    $iblockParams['CART_PROPERTIES'],
                                    $productPropsVar,
                                    $this->arParams['PARTIAL_PRODUCT_PROPERTIES'] === 'Y'
                                );
                                if (!is_array($productProperties))
                                {
                                    $errorMsg = Loc::getMessage('CATALOG_PARTIAL_BASKET_PROPERTIES_ERROR');
                                    $successfulAdd = false;
                                }
                            }
                            else
                            {
                                $errorMsg = Loc::getMessage('CATALOG_EMPTY_BASKET_PROPERTIES_ERROR');
                                $successfulAdd = false;
                            }
                        }
                    }
                    else
                    {
                        $skuAddProps = $this->request->get('basket_props') ?: '';
                        if (!empty($iblockParams['OFFERS_CART_PROPERTIES']) || !empty($skuAddProps))
                        {
                            $productProperties = \CIBlockPriceTools::GetOfferProperties(
                                $productId,
                                $productIblockId,
                                $iblockParams['OFFERS_CART_PROPERTIES'],
                                $skuAddProps
                            );
                        }
                    }
                }
            }
            else
            {
                $errorMsg = Loc::getMessage('CATALOG_PRODUCT_NOT_FOUND');
                $successfulAdd = false;
            }

            if ($this->arParams['USE_PRODUCT_QUANTITY'])
            {
                $quantity = (float)$this->request->get($this->arParams['PRODUCT_QUANTITY_VARIABLE']);
            }

            if ($quantity <= 0)
            {
                $ratioIterator = \CCatalogMeasureRatio::getList(
                    array(),
                    array('PRODUCT_ID' => $productId),
                    false,
                    false,
                    array('PRODUCT_ID', 'RATIO')
                );
                if ($ratio = $ratioIterator->Fetch())
                {
                    $intRatio = (int)$ratio['RATIO'];
                    $floatRatio = (float)$ratio['RATIO'];
                    $quantity = $floatRatio > $intRatio ? $floatRatio : $intRatio;
                }
            }

            if ($quantity <= 0)
            {
                $quantity = 1;
            }
        }
        else
        {
            $errorMsg = Loc::getMessage('CATALOG_PRODUCT_NOT_FOUND');
            $successfulAdd = false;
        }

        $rewriteFields = $this->getRewriteFields($action);

        if ($successfulAdd)
        {
            /* */
            if($_REQUEST["optionsprice"]){
                $productProperties[] = array(
                    "NAME" => "Сумма дополнителных опций (за ед.товара)",
                    "CODE" => "PICKED_OPTIONS_PRICE",
                    "VALUE" => $_REQUEST["optionsprice"]." руб.",
                    "SORT" => "1000"
                );
            }
            if($_REQUEST["edge"] && $_REQUEST["edgeprice"]){
                $productProperties[] = array(
                    "NAME" => "Обработка края",
                    "CODE" => "PICKED_EDGE",
                    "VALUE" => $_REQUEST["edge"],
                    "SORT" => "1100"
                );
            }
            if($_REQUEST["edges"] && $_REQUEST["edgesprice"]){
                $productProperties[] = array(
                    "NAME" => "Отстрочка края",
                    "CODE" => "PICKED_EDGES",
                    "VALUE" => $_REQUEST["edges"],
                    "SORT" => "1200"
                );
            }
            if($_REQUEST["bracing"] && $_REQUEST["bracingprice"]){
                $productProperties[] = array(
                    "NAME" => "Крепления",
                    "CODE" => "PICKED_BRACING",
                    "VALUE" => $_REQUEST["bracing"],
                    "SORT" => "1300"
                );
            }
            if($_REQUEST["logo"] && $_REQUEST["logoprice"]){
                $productProperties[] = array(
                    "NAME" => "Логотип",
                    "CODE" => "PICKED_LOGO",
                    "VALUE" => $_REQUEST["logo"],
                    "SORT" => "1400"
                );
            }
            if($_REQUEST["extra"] && $_REQUEST["extraprice"]){
                $productProperties[] = array(
                    "NAME" => "Дополнительно",
                    "CODE" => "PICKED_EXTRA",
                    "VALUE" => $_REQUEST["extra"],
                    "SORT" => "1500"
                );
            }
            /* */

            if (!Add2BasketByProductID($productId, $quantity, $rewriteFields, $productProperties))
            {
                if ($ex = $APPLICATION->GetException())
                {
                    $errorMsg = $ex->GetString();
                }
                else
                {
                    $errorMsg = Loc::getMessage('CATALOG_ERROR2BASKET');
                }

                $successfulAdd = false;
            }
        }

        return array($successfulAdd, $errorMsg);
    }
?>
_______________________________________________________________

Добавление наценки в корзине (пример с добавлением суммы из выбранных свойств товара)

<?
\Bitrix\Main\EventManager::getInstance()->addEventHandler( 
    'sale', 
    'OnBeforeSaleBasketItemSetField', 
    'changePrice' 
);

function changePrice(\Bitrix\Main\Event $event) 
{ 
    $name = $event->getParameter('NAME'); 
    $value = $event->getParameter('VALUE'); 
    $item = $event->getParameter('ENTITY');

    if ($name === 'PRICE') { 
        $basketPropertyCollection = \Bitrix\Sale\BasketPropertiesCollection::load($item);
        $basketId = $basketPropertyCollection->getBasketId();
        $db_res = CSaleBasket::GetPropsList(
            array(
                    "SORT" => "ASC",
                    "NAME" => "ASC"
                ),
            array("BASKET_ID" => $basketId)
        );
        while ($ar_res = $db_res->Fetch()) {
            if ($ar_res["CODE"] == "PICKED_OPTIONS_PRICE") $value += floatval($ar_res["VALUE"]);
        }
        $event->addResult( 
            new \Bitrix\Main\EventResult( 
                \Bitrix\Main\EventResult::SUCCESS, array('VALUE' => $value) 
            ) 
        ); 
    }
}
?>
_______________________________________________________________

PHP 7

1) Меняем версию на хостинге
2) Меняем mod_php5.c в .htaccess
3) /bitrix/php_interface/dbconn.php
define("BX_USE_MYSQLI", true);
4) /bitrix/.settings.php 
className: 'className' => '\\Bitrix\\Main\\DB\\MysqliConnection',
...
'handled_errors_types' => 4437,
'exception_errors_types' => 4437,
5) на сервере отключить вывод E_DEPRECATED
_______________________________________________________________

Логи

dbconn.php
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/log.txt");

AddMessage2Log("Сообщение");
_______________________________________________________________

Список сработавших почтовых событий

(Настройки → Инструменты → SQL-запрос)

select * from b_event 
  where event_name like '%form%' 
  order by date_insert desc