D7-аналоги любимых функций в 1С-Битрикс

Новое ядро D7 в 1С-Битрикс: Управление сайтом решительно замещает старое. Все чаще использование привычных методов и классов приводит к предупреждению от IDE “Method/class is deprecated”. Предлагаю “знать врага в лицо” и провести небольшой обзор таких классов D7, которые уже сейчас можно и нужно использовать, чтобы не прослыть в среде разработчиков неотесанным неандертальцем. Но замечу, что ядро D7 – это не просто рефакторинг, это смена подхода к написанию кода.

В конце статьи собраны все аналоги, которые могут понадобиться разработчику.

Подключение стилей и скриптов

CMain::AddHeadScript , CMain::SetAdditionalCss , CMain::AddHeadString

Давным-давно в далекой-далекой версии Битрикса разработчики вставляли стили и скрипты шаблона в документ банальными тегами <script> и <link>. Потом в фаворе оказались названные выше отложенные функции. Сейчас устарели и они. Нынче на дворе 2016 год и подключать надо так:

// Old school
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH . "/js/fix.js");
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . "/styles/fix.css");
$APPLICATION->AddHeadString("<link href='http://fonts.googleapis.com/css?family=PT+Sans:400&subset=cyrillic' rel='stylesheet' type='text/css'>");

// 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://fonts.googleapis.com/css?family=PT+Sans:400&subset=cyrillic' rel='stylesheet' type='text/css'>");

Эти методы динамические, а класс реализует паттерн “одиночка” (Singletone) и обратиться к объекту можно через Bitrix\Main\Page\Asset::getInstance() .

По слухам, этот класс может быть в скором времени переписан, так что необходимо держать руку на пульсе.

Срочно в номер: на днях была опубликована документация по новому способу подключения JS и CSS в шаблонах компонентов.

Подключение модулей

CModule::IncludeModule , CModule::IncludeModuleEx

Уже многие выучили, что вместо старого доброго CModule для подключения модулей нужно применять новый бодрый Bitrix\Main\Loader .

// Old school
CModule::IncludeModule("iblock");
CModule::IncludeModuleEx("intervolga.tips");

// D7
use Bitrix\Main\Loader;

Loader::includeModule("iblock");
Loader::includeSharewareModule("intervolga.tips");

Локализация

GetMessage , IncludeModuleLangFile , IncludeTemplateLangFile

Чтобы быть стильным-модным-молодежным рекомендуется пользоваться следующим кодом для обращения к языковым файлам и переменным:

// Old school
IncludeTemplateLangFile(__FILE__);
echo GetMessage("INTERVOLGA_TIPS.TITLE");

// D7
use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);
echo Loc::getMessage("INTERVOLGA_TIPS.TITLE");

Настройки модулей

COption::SetOptionInt , COption::SetOptionString , COption::GetOptionInt , COption::GetOptionString , COption::RemoveOption

Претерпел изменения и код для работы с чтением и записью настроек модулей. На смену классу COption пришел Bitrix\Main\Config\Option :

// Old school
COption::SetOptionString("main", "max_file_size", "1024");
$size = COption::GetOptionInt("main", "max_file_size");
COption::RemoveOption("main", "max_file_size", "s2");

// D7
use Bitrix\Main\Config\Option;

Option::set("main", "max_file_size", "1024");
$size = Option::get("main", "max_file_size");
Option::delete("main", array(
    "name" => "max_file_size",
    "site_id" => "s2"
    )
);

Пропало разделение методов на int и string, а при удалении теперь используется массив-фильтр.

В новом классе есть несколько совершенно новых методов, не имеющих “старых” аналогов, так что самостоятельное изучение исходного кода приветствуется.

Кеширование

CPHPCache::StartDataCache , CPHPCache::InitCache , CPHPCache::GetVars , CPHPCache::EndDataCache , CPHPCache::AbortDataCache

Спасибо Андрею Загальскому за пример работы с кешированием в ядре D7 . Новый класс Bitrix\Main\Data\Cache почти ничем не отличается в обращении от старого CPHPCache .

// Old school
$cache = new CPHPCache();
if ($cache->InitCache($cacheTime, $cacheId, $cacheDir))
{
    $result = $cache->GetVars();
}
elseif($cache->StartDataCache())
{
    $result = array();
    // ...
    if ($isInvalid)
    {
        $cache->AbortDataCache();
    }
    // ...
    $cache->EndDataCache($result);
}

// D7
$сache = Bitrix\Main\Data\Cache::createInstance();
if ($сache->initCache($cacheTime, $cacheId, $cacheDir))
{
    $result = $сache->getVars();
}
elseif ($сache->startDataCache())
{
    $result = array();
    // ...
    if ($isInvalid)
    {
        $cache->abortDataCache();
    }
    // ...
    $сache->endDataCache($result);
}

События

AddEventHandler , RemoveEventHandler , RegisterModuleDependences , UnRegisterModuleDependences , GetModuleEvents

Теперь за кратко- и долгосрочную регистрацию обработчиков событий отвечает один класс: Bitrix\Main\EventManager .

// Old school
$handler = AddEventHandler("main",
    "OnUserLoginExternal",
    array(
        "Intervolga\\Test\\EventHandlers\\Main",
        "onUserLoginExternal"
    )
);
RemoveEventHandler(
    "main",
    "OnUserLoginExternal",
    $handler
);
RegisterModuleDependences(
    "main",
    "OnProlog",
    $this->MODULE_ID,
    "Intervolga\\Test\\EventHandlers",
    "onProlog"
);
UnRegisterModuleDependences(
    "main",
    "OnProlog",
    $this->MODULE_ID,
    "Intervolga\\Test\\EventHandlers",
    "onProlog"
);

$handlers = GetModuleEvents("main", "OnProlog", true);

// D7
use Bitrix\Main\EventManager;

$handler = EventManager::getInstance()->addEventHandler(
    "main",
    "OnUserLoginExternal",
    array(
        "Intervolga\\Test\\EventHandlers\\Main",
        "onUserLoginExternal"
    )
);
EventManager::getInstance()->removeEventHandler(
    "main",
    "OnUserLoginExternal",
    $handler
);
EventManager::getInstance()->registerEventHandler(
    "main",
    "OnProlog",
    $this->MODULE_ID,
    "Intervolga\\Test\\EventHandlers",
    "onProlog"
);
EventManager::getInstance()->unRegisterEventHandler(
    "main",
    "OnProlog",
    $this->MODULE_ID,
    "Intervolga\\Test\\EventHandlers",
    "onProlog"
);
$handlers = EventManager::getInstance()->findEventHandlers("main", "OnProlog");

Bitrix\Main\EventManager , так же как Bitrix\Main\Page\Asset , реализует паттерн Одиночка, обращаться к нему нужно через getInstance() .

Важное замечание: в обработчики, зарегистрированные с помощью addEventHandler в качестве аргумента будет передан объект события ( Bitrix\Main\Event ). Если хотите, чтобы передавались старые добрые аргументы, нужно использовать addEventHandlerCompatible . Аналогично с registerEventHandler и registerEventHandlerCompatible .

Файловая структура

CheckDirPath , DeleteDirFilesEx , RewriteFile

Тут нынче раздолье для ООП-программиста. Для работы с файлами, папками и всем прочим – отдельные классы, все типизировано и напоминает Java. Самые “главные” классы здесь – Bitrix\Main\IO\Directory и Bitrix\Main\IO\File (ну и немного Bitrix\Main\IO\Path ).

// Old school
CheckDirPath($_SERVER["DOCUMENT_ROOT"] . "/foo/bar/baz/");
RewriteFile(
    $_SERVER["DOCUMENT_ROOT"] . "/foo/bar/baz/1.txt",
    "hello from old school!"
);
DeleteDirFilesEx("/foo/bar/baz/");

// D7
use Bitrix\Main\Application;
use Bitrix\Main\IO\Directory;
use Bitrix\Main\IO\File;

Directory::createDirectory(
    Application::getDocumentRoot() . "/foo/bar/baz/"
);
File::putFileContents(
Application::getDocumentRoot() . "/foo/bar/baz/1.txt",
    "hello from D7"
);
Directory::deleteDirectory(
    Application::getDocumentRoot() . "/foo/bar/baz/"
);

Необходимо только запомнить, что DeleteDirFilesEx принимал путь от корня сайта, а его аналог принимает абсолютный путь к файлу от корня сервера.

Обратите внимание : вместо $_SERVER["DOCUMENT_ROOT"] сейчас можно использовать Bitrix\Main\Application::getDocumentRoot() .

Классы для работы с файловой системой умеют многое, в этом вы можете убедиться сами, изучив исходники.

Исключения

CMain::ThrowException , CMain::ResetException , CMain::GetException

Открою небольшой секрет: в нашем дружном коллективе возник локальный холивар. Мы спорили, стоит ли помещать в эту статью раздел про исключения и обработку ошибок. Ведь тут не просто одни методы заменили другие – тут изменился подход (о чем я говорил в начале статьи), были переосмыслены некоторые базовые принципы многих классов. Есть две причины, почему этот раздел все-таки опубликован:

  1. Это важная тема, и говоря о переходе на D7 про нее нельзя не упомянуть
  2. Автор статьи все-таки я :P

Итак, одним из наиболее существенных изменений в D7 стала обработка ошибок при помощи механизма исключений (полное соблюдение религии исключений в php ). Если происходит ошибка – выбрасываем исключение. Если хотим обработать ошибку – ловим исключение. Базовый класс для всех исключений в системе: Bitrix\Main\SystemException .

// Old school
global $APPLICATION;
$APPLICATION->ResetException();
$APPLICATION->ThrowException("Error");
//...
if ($exception = $APPLICATION->GetException())
{
    echo $exception->GetString();
}

// D7
use Bitrix\Main\SystemException;

try
{
    // ...
    throw new SystemException("Error");
}
catch (SystemException $exception)
{
    echo $exception->getMessage();
}

Отладка

AddMessage2Log , mydump

Ах, сколько раз выручал бывалого разработчика этот метод ( AddMessage2Log ). Неизменный товарищ при отладке ajax-запросов, крон-файлов и всего, невидимого глазу администратора. Но сегодня устарел и он, а на смену ему спешат два новых “молодца”:

// Old school
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/bitrix/log-intervolga.txt");

AddMessage2Log($_SERVER);
echo "<pre>" . mydump($_SERVER) . "</pre>";

// D7
use Bitrix\Main\Diag\Debug;

Debug::dumpToFile($_SERVER);
// or
Debug::writeToFile($_SERVER);

Debug::dump($_SERVER);

Первый для любителей var_dump , второй для адептов print_r ’а.

Так же в этом классе есть несколько совершенно новых методов, не имеющих аналогов в старом ядре. Например, методы для измерения времени:

// D7
use Bitrix\Main\Diag\Debug;
Debug::startTimeLabel("foo");
foo();
Debug::endTimeLabel("foo");

Debug::startTimeLabel("bar");
bar();
Debug::endTimeLabel("bar");
        
print_r(Debug::getTimeLabels());

Почтовые события

CEvent::Send , CEvent::SendImmediate

Отправка почтовых событий претерпела незначительные изменения. Вместо нескольких аргументов, метод теперь принимает ассоциативный массив настроек.

// Old school
CEvent::Send(
    "NEW_USER",
    "s1",
    array(
        "EMAIL" => "info@intervolga.ru",
        "USER_ID" => 42
    )
);

// D7
use Bitrix\Main\Mail\Event;
Event::send(array(
    "EVENT_NAME" => "NEW_USER",
    "LID" => "s1",
    "C_FIELDS" => array(
        "EMAIL" => "info@intervolga.ru",
        "USER_ID" => 42
    ),
));

Работа с GET- и POST-параметрами страницы

$_GET , $_POST , $_REQUEST

    нельзя(2).jpg

Чтобы избавиться от глобальных переменных в коде (суперглобальных в том числе) в D7 изобрели класс Bitrix\Main\HttpRequest . Забирать get- и post-переменные теперь можно через него.

// Old school
$name = $_POST["name"];
$email = htmlspecialchars($_GET["email"]);

// D7
use Bitrix\Main\Application;
$request = Application::getInstance()->getContext()->getRequest();

$name = $request->getPost("name");
$email = htmlspecialchars($request->getQuery("email"));

Конструировать объект самому не нужно, добраться до него можно через приложение и контекст (как в примере кода выше).

Работа с cookie

CMain::set_cookie , CMain::get_cookie

Класс CMain слишком много себе позволяет. Он и компоненты подключал, и CSS/JS регистрирует, и хлебные крошки собирает, и т.п. В этом разделе мы рассмотрим, куда “сбежали” методы работы с куками. В старом ядре было 2 метода: для создания и для получения кук. Теперь всё стало гораздо глубже: задавать куки нужно через класс “ответа сервера” – Bitrix\Main\HttpResponse , получать их нужно через класс “запроса к серверу” – Bitrix\Main\HttpRequest .

// Old school
global $APPLICATION;
$APPLICATION->set_cookie("TEST", 42, false, "/", "example.com");
// Cookie будет доступна только на следующем хите!
echo $APPLICATION->get_cookie("TEST");

// D7
use Bitrix\Main\Application;
use Bitrix\Main\Web\Cookie;
$cookie = new Cookie("TEST", 42);
$cookie->setDomain("example.com");
Application::getInstance()->getContext()->getResponse()->addCookie($cookie);
// Cookie будет доступна только на следующем хите!
echo Application::getInstance()->getContext()->getRequest()->getCookie("TEST");

Также работа с куками может вестись силами класса Bitrix\Main\Web\HttpClient , но это совсем другая история .

Важное замечание: запись куки, добавленной через D7, произойдет только при подключении эпилога (там вызывается метод Bitrix\Main\HttpResponse::flush() )

Работа со ссылками

CMain::GetCurPageParam , DeleteParam

Для работы со ссылками в ядре D7 есть отдельный класс: Bitrix\Main\Web\Uri . Правда, работа с ним не так “компактна”, как с его предшественником. Но это лишь следствие того, что в этом классе соблюдается принцип “1 метод – 1 ответственность”.

// Old school
global $APPLICATION;
$redirect = $APPLICATION->GetCurPageParam("foo=bar", array("baz"));

// D7
use Bitrix\Main\Application;
use Bitrix\Main\Web\Uri;

$request = Application::getInstance()->getContext()->getRequest();
$uriString = $request->getRequestUri();
$uri = new Uri($uriString);
$uri->deleteParams(array("baz"));
$uri->addParams(array("foo" => "bar"));
$redirect = $uri->getUri();

ORM-классы

Их реально много. Их просто нужно “знать в лицо”, так как это будет основной инструмент на многие годы, как когда-то был CIBlockElement::GetList сотоварищи. В таблице в конце статьи я приведу основные ORM-классы, на которые стоит обратить внимание уже сегодня.

Запросы к БД

CDatabase::Query

Хоть это и не рекомендуется, но возможность поработать с БД прямыми запросами в продукте остается. Теперь доступ получается не через глобальный объект $DB класса CDatabase , а через Bitrix\Main\DB\Connection . “Добираться” до подключения нужно через Bitrix\Main\Application :

// Old school
global $DB;
$record = $DB->Query("select 1+1;")->Fetch();
AddMessage2Log($record);

// D7
use Bitrix\Main\Application;
use Bitrix\Main\Diag\Debug;

$record = Application::getConnection()
->query("select 1+1;")
->fetch();
Debug::writeToFile($record);

Хозяйке на заметку : больше про ORM и работу с БД в D7 можно почерпнуть из другой нашей статьи .



Итоговая таблица аналогов старых методов и классов в новом ядре D7 (с примерами вызова)

Было (старое ядро)

Стало (новое ядро D7)

CMain::AddHeadScript

Bitrix\Main\Page\Asset::addJs

CMain::SetAdditionalCss

Bitrix\Main\Page\Asset::addCss

CMain::AddHeadString

Bitrix\Main\Page\Asset::addString

CModule::IncludeModule

Bitrix\Main\Loader::includeModule

CModule::IncludeModuleEx

Bitrix\Main\Loader::includeSharewareModule

GetMessage

Bitrix\Main\Localization\Loc::getMessage

IncludeModuleLangFile , IncludeTemplateLangFile

Bitrix\Main\Localization\Loc::loadMessages

COption::SetOptionInt , COption::SetOptionString ,

Bitrix\Main\Config\Option::set

COption::GetOptionInt , COption::GetOptionString

Bitrix\Main\Config\Option::get

COption::RemoveOption

Bitrix\Main\Config\Option::delete

CPHPCache::StartDataCache

Bitrix\Main\Data\Cache::startDataCache

CPHPCache::InitCache

Bitrix\Main\Data\Cache::initCache

CPHPCache::GetVars

Bitrix\Main\Data\Cache::getVars

CPHPCache::EndDataCache

Bitrix\Main\Data\Cache::endDataCache

CPHPCache::AbortDataCache

Bitrix\Main\Data\Cache::abortDataCache

AddEventHandler

Bitrix\Main\EventManager::addEventHandler (новый формат),
Bitrix\Main\EventManager::addEventHandlerCompatible

RemoveEventHandler

Bitrix\Main\EventManager::removeEventHandler (новый формат),
Bitrix\Main\EventManager::registerEventHandlerCompatible

RegisterModuleDependences

Bitrix\Main\EventManager::registerEventHandler

UnRegisterModuleDependences

Bitrix\Main\EventManager::unRegisterEventHandler

GetModuleEvents

Bitrix\Main\EventManager::findEventHandlers

CheckDirPath

Bitrix\Main\IO\Directory::createDirectory

DeleteDirFilesEx

Bitrix\Main\IO\Directory::deleteDirectory

RewriteFile

Bitrix\Main\IO\File::putFileContents

CMain::ThrowException

Bitrix\Main\SystemException

CMain::ResetException

Bitrix\Main\SystemException

CMain::GetException

Bitrix\Main\SystemException

AddMessage2Log

Bitrix\Main\Diag\Debug::dumpToFile,

Bitrix\Main\Diag\Debug::writeToFile

mydump

Bitrix\Main\Diag\Debug::dump

CEvent::Send

Bitrix\Main\Mail\Event::send

CEvent::SendImmediate

Bitrix\Main\Mail\Event::sendImmediate

$_REQUEST

Bitrix\Main\HttpRequest::get

$_GET

Bitrix\Main\HttpRequest::getQuery

$_POST

Bitrix\Main\HttpRequest::getPost

CMain::set_cookie

Bitrix\Main\HttpResponse::addCookie

CMain::get_cookie

Bitrix\Main\HttpRequest::getCookie

CMain::GetCurPageParam

Bitrix\Main\Web\Uri::addParams,

Bitrix\Main\Web\Uri::deleteParams,

Bitrix\Main\Web\Uri::getUri

DeleteParam

Bitrix\Main\Web\Uri::deleteParams,

Bitrix\Main\Web\Uri::getUri

CDatabase::Query

Bitrix\Main\DB\Connection::query

ORM-классы


Класс в старом ядре

Класс в новом ядре D7

Таблица БД

CUser

Bitrix\Main\UserTable

b_user

CFile

Bitrix\Main\FileTable

b_file

CGroup

Bitrix\Main\GroupTable

b_group

CSite

Bitrix\Main\SiteTable

b_lang

CIBlockElement

Bitrix\Iblock\ElementTable

b_iblock_element

CIBlock

Bitrix\Iblock\IblockTable

b_iblock

CIBlockProperty

Bitrix\Iblock\PropertyTable

b_iblock_property

CIBlockSection

Bitrix\Iblock\SectionTable

b_iblock_section

CIBlockPropertyEnum

Bitrix\Iblock\PropertyEnumerationTable

b_iblock_property_enum

CCatalogStore

Bitrix\Catalog\StoreTable

b_catalog_store

CCatalogProduct

Bitrix\Catalog\ProductTable

b_catalog_product

CCatalogGroup

Bitrix\Catalog\GroupTable

b_catalog_group

CSaleOrder

Bitrix\Sale\Internals\OrderTable

b_sale_order

CSaleBasket

Bitrix\Sale\Internals\BasketTable

b_sale_basket

CSaleOrderProps

Bitrix\Sale\Internals\OrderPropsTable

b_sale_order_props

CSaleOrderPropsValue

Bitrix\Sale\Internals\OrderPropsValueTable

b_sale_order_props_value

Выводы

oh no(2).jpg


Складывается интересная ситуация. Компания 1С-Битрикс активно рекламирует новое ядро D7, на каждой конференции все чаще слышны фразы “компонент/модуль полностью переписан на новом ядре, классах и т.п.”, старый код все чаще отмечается как @deprecated . Но при всем при этом никакой документации нет. Документация посвящена только старому ядру и если нужно познакомиться с D7 – то нужно держать руку на пульсе событий: читать исходники, форумы , блоги , общаться с техподдержкой, изучать официальные видеокурсы( Разработка на D7.Введение и D7. Разработка собственного модуля ). С одной стороны, это может повысить “порог вхождения” в “клуб программистов D7” и сделать их еще более бородатыми, с другой – может отпугнуть новичков.

Будем надеяться, что исчерпывающая документация по новому ядру все-таки появится и мы (программисты, пользователи и разработчики 1С-Битрикс: Управление сайтом) пойдем в светлое будущее, где уже маячат PHP 7, EcmaScript 6 и другие радости web-технологий.


P.S. спасибо Сергею Покоеву, Алексею Шкарупе и Степану Овчинникову за помощь в написании статьи.

UPD: спасибо Дмитрию Черноярову за дополнения по работе с $_GET, cookie и событиями.

UPD 2: на свет появилась документация по новому ядру d7 !

Комментарии (15)

...
  • Павел Машанов
  • 02.03.2016 13:15:01
Спасибо, отличная статья!

> Автор статьи все-таки я :P
Зритель наклоняется к одному из игроков в покер и шепчет: «только что сдающий раздал сам себе все четыре туза». Игрок отвечает: «Ну и что — сейчас же его очередь сдавать».
...
  • Михаил
  • 04.03.2016 08:27:01
Я бы сказал что статья просто офигенная!)
...
  • Прилепа Олег
  • 04.03.2016 12:04:54
Шикарно, автору огромный респект.
...
  • Алексей Попович
  • 04.03.2016 12:50:12
Супер!
...
  • Иван
  • 04.03.2016 20:43:47
немного подробнее про работу с запросами и файлами:
http://mrcappuccino.ru/blog/post/d7-application-and-context-objects
http://mrcappuccino.ru/blog/post/work-with-file-system-bitrix-d7
...
  • Panfilov Ivan
  • 15.03.2016 22:49:20
File::putFileContents(

Directory::deleteDirectory(

Directory::createDirectory(

зачем?

использовать стандартные функции http://php.net/manual/ru/ref.filesystem.php это слишком просто?
...
Directory::deleteDirectory удаляет рекурсивно (в отличие от rmdir, которая требует предварительной очистки директории)

File::putFileContents не только создает файл, но и все директории на пути к нему

А Directory::createDirectory по сути обертка над стандартным повторяющимся кодом mkdir($dir, BX_DIR_PERMISSIONS, true)
...
  • Pilezkiy Антон
  • 22.03.2016 22:18:53
А как в D7 сделать тэгированый кэш? Кто-нибудь разобрался?
...
  • Виталий
  • 26.04.2016 08:36:36
Добавление тега
$cache_manager = Bitrix\Main\Application::getInstance()->getTaggedCache();
$cache_manager->startTagCache('/path_cache');
$cache_manager->registerTag('tag');
$cache_manager->endTagCache();

Очистить по тегу
$cache_manager->clearByTag('tag');
...
  • Алексей Попович
  • 05.06.2016 09:00:20
А кто-то знает, как стандартные компоненты шаблона сайта в формате нового ядра должны выглядеть:

$APPLICATION->ShowTitle();
$APPLICATION->ShowHead();
$APPLICATION->ShowPanel();
...
Алексей, на данный момент (стабильная версия 16.0.13) аналоги науке неизвестны.
...
  • Сергей
  • 20.07.2016 21:21:44
Подскажите пожалуйста как сделать старый добрый getList на новом ядре элементов ИБ, с фильтрацией по свойству элемента и в целом как забрать свойства элемента попавшего в выборку
...
Сергей, к сожалению такой возможности пока не наблюдается.
Уверен, что над этим работают. Пока что можно использовать класс \Bitrix\Iblock\ElementTable для выбора элементов с фильтрацией, сортировкой, группировкой только по полям.
...
  • Nina R
  • 23.08.2016 08:41:08
Добавление/обновление элементов инфоблока в D7 заблокировано.
\Bitrix\Iblock\ElementTable::Add и \Bitrix\Iblock\ElementTable::Update
Выдает что-то типа предложения воспользоваться методами старого ядра.
Так что по инфоблокам пока в D7 лучше не работать.
...
  • Сайфуллин Руслна
  • 28.09.2016 10:42:32
Для получения Внутреннего кода владельца корзины
вместо CSaleBasket::GetBasketUserID()
теперь Bitrix\Sale\Fuser::getId()