Новое ядро D7 в 1С-Битрикс: Управление сайтом решительно замещает старое. Все чаще использование привычных методов и классов приводит к предупреждению от IDE “Method/class is deprecated”. Предлагаю “знать врага в лицо” и провести небольшой обзор таких классов D7, которые уже сейчас можно и нужно использовать, чтобы не прослыть в среде разработчиков неотесанным неандертальцем. Но замечу, что ядро D7 – это не просто рефакторинг, это смена подхода к написанию кода.
В конце статьи собраны все аналоги, которые могут понадобиться разработчику.
1 2 3 4 5 6
<?php
//Подключение стилей и скриптов
CMain::AddHeadScript , CMain::SetAdditionalCss , CMain::AddHeadString
?>
Давным-давно в далекой-далекой версии Битрикса разработчики вставляли стили и скрипты шаблона в документ банальными тегами script и link. Потом в фаворе оказались названные выше отложенные функции. Сейчас устарели и они. Нынче на дворе 2016 год и подключать надо так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<?php
// 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 BitrixMainPageAsset;
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) и обратиться к объекту можно через BitrixMainPageAsset::getInstance() .
?>
По слухам, этот класс может быть в скором времени переписан, так что необходимо держать руку на пульсе.
Срочно в номер: на днях была опубликована документация по новому способу подключения JS и CSS в шаблонах компонентов.
1 2 3 4 5 6 7
<?php
<p class="zag_1">Подключение модулей</p>
CModule::IncludeModule , CModule::IncludeModuleEx
?>
Уже многие выучили, что вместо старого доброго CModule для подключения модулей нужно применять новый бодрый BitrixMainLoader.
1 2 3 4 5 6 7 8 9 10 11 12 13
<?php
// Old school
CModule::IncludeModule("iblock");
CModule::IncludeModuleEx("picht.tips");
GetMessage, IncludeModuleLangFile, IncludeTemplateLangFile
Чтобы быть стильным-модным-молодежным рекомендуется пользоваться следующим кодом для обращения к языковым файлам и переменным:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?php
// Old school
IncludeTemplateLangFile(__FILE__);
echo GetMessage("INTERVOLGA_TIPS.TITLE");
BitrixMainEventManager , так же как BitrixMainPageAsset , реализует паттерн Одиночка, обращаться к нему нужно через getInstance().
Важное замечание: в обработчики, зарегистрированные с помощью addEventHandler в качестве аргумента будет передан объект события ( BitrixMainEvent ). Если хотите, чтобы передавались старые добрые аргументы, нужно использовать addEventHandlerCompatible . Аналогично с registerEventHandler и registerEventHandlerCompatible .
Файловая структура
CheckDirPath , DeleteDirFilesEx , RewriteFile
Тут нынче раздолье для ООП-программиста. Для работы с файлами, папками и всем прочим – отдельные классы, все типизировано и напоминает Java. Самые “главные” классы здесь – BitrixMainIODirectory и BitrixMainIOFile (ну и немного BitrixMainIOPath ).
// 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 BitrixMainApplication;
use BitrixMainIODirectory;
use BitrixMainIOFile;
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"] сейчас можно использовать BitrixMainApplication::getDocumentRoot() .
Классы для работы с файловой системой умеют многое, в этом вы можете убедиться сами, изучив исходники.
Исключения
CMain::ThrowException , CMain::ResetException , CMain::GetException
Открою небольшой секрет: в нашем дружном коллективе возник локальный холивар. Мы спорили, стоит ли помещать в эту статью раздел про исключения и обработку ошибок. Ведь тут не просто одни методы заменили другие – тут изменился подход (о чем я говорил в начале статьи), были переосмыслены некоторые базовые принципы многих классов. Есть две причины, почему этот раздел все-таки опубликован:
Это важная тема, и говоря о переходе на D7 про нее нельзя не упомянуть
Автор статьи все-таки я :P
Итак, одним из наиболее существенных изменений в D7 стала обработка ошибок при помощи механизма исключений (полное соблюдение религии исключений в php ). Если происходит ошибка – выбрасываем исключение. Если хотим обработать ошибку – ловим исключение. Базовый класс для всех исключений в системе: BitrixMainSystemException .
// Old school
global $APPLICATION;
$APPLICATION->ResetException();
$APPLICATION->ThrowException("Error");
//...
if ($exception = $APPLICATION->GetException())
{
echo $exception->GetString();
}
Ах, сколько раз выручал бывалого разработчика этот метод ( AddMessage2Log ). Неизменный товарищ при отладке ajax-запросов, крон-файлов и всего, невидимого глазу администратора. Но сегодня устарел и он, а на смену ему спешат два новых “молодца”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<?php
// Old school
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/bitrix/log-intervolga.txt");
// Old school
CEvent::Send(
"NEW_USER",
"s1",
array(
"EMAIL" => "info@intervolga.ru",
"USER_ID" => 42
)
);
// D7
use BitrixMainMailEvent;
Event::send(array(
"EVENT_NAME" => "NEW_USER",
"LID" => "s1",
"C_FIELDS" => array(
"EMAIL" => "info@intervolga.ru",
"USER_ID" => 42
),
));
Работа с GET- и POST-параметрами страницы
$_GET , $_POST , $_REQUEST
?>
Чтобы избавиться от глобальных переменных в коде (суперглобальных в том числе) в D7 изобрели класс BitrixMainHttpRequest . Забирать get- и post-переменные теперь можно через него.
// Old school
$name = $_POST["name"];
$email = htmlspecialchars($_GET["email"]);
// D7
use BitrixMainApplication;
$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 метода: для создания и для получения кук. Теперь всё стало гораздо глубже: задавать куки нужно через класс “ответа сервера” – BitrixMainHttpResponse , получать их нужно через класс “запроса к серверу” – BitrixMainHttpRequest .
// Old school
global $APPLICATION;
$APPLICATION->set_cookie("TEST", 42, false, "/", "example.com");
// Cookie будет доступна только на следующем хите!
echo $APPLICATION->get_cookie("TEST");
// D7
use BitrixMainApplication;
use BitrixMainWebCookie;
$cookie = new Cookie("TEST", 42);
$cookie->setDomain("example.com");
Application::getInstance()->getContext()->getResponse()->addCookie($cookie);
// Cookie будет доступна только на следующем хите!
echo Application::getInstance()->getContext()->getRequest()->getCookie("TEST");
Также работа с куками может вестись силами класса BitrixMainWebHttpClient , но это совсем другая история .
Важное замечание: запись куки, добавленной через D7, произойдет только при подключении эпилога (там вызывается метод BitrixMainHttpResponse::flush() )
Работа со ссылками
CMain::GetCurPageParam , DeleteParam
Для работы со ссылками в ядре D7 есть отдельный класс: BitrixMainWebUri . Правда, работа с ним не так “компактна”, как с его предшественником. Но это лишь следствие того, что в этом классе соблюдается принцип “1 метод – 1 ответственность”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<?php
// Old school
global $APPLICATION;
$redirect = $APPLICATION->GetCurPageParam("foo=bar", array("baz"));
// D7
use BitrixMainApplication;
use BitrixMainWebUri;
Их реально много. Их просто нужно “знать в лицо”, так как это будет основной инструмент на многие годы, как когда-то был CIBlockElement::GetList сотоварищи. В таблице в конце статьи я приведу основные ORM-классы, на которые стоит обратить внимание уже сегодня.
Запросы к БД
CDatabase::Query
Хоть это и не рекомендуется, но возможность поработать с БД прямыми запросами в продукте остается. Теперь доступ получается не через глобальный объект $DB класса CDatabase , а через BitrixMainDBConnection . “Добираться” до подключения нужно через BitrixMainApplication:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?php
// Old school
global $DB;
$record = $DB->Query("select 1+1;")->Fetch();
AddMessage2Log($record);
// D7
use BitrixMainApplication;
use BitrixMainDiagDebug;
Хозяйке на заметку : больше про ORM и работу с БД в D7 можно почерпнуть из другой нашей статьи .
Итоговая таблица аналогов старых методов и классов в новом ядре D7 (с примерами вызова)
Складывается интересная ситуация. Компания 1С-Битрикс активно рекламирует новое ядро D7, на каждой конференции все чаще слышны фразы “компонент/модуль полностью переписан на новом ядре, классах и т.п.”, старый код все чаще отмечается как @deprecated . Но при всем при этом никакой документации нет. Документация посвящена только старому ядру и если нужно познакомиться с D7 – то нужно держать руку на пульсе событий: читать исходники, форумы , блоги , общаться с техподдержкой, изучать официальные видеокурсы( Разработка на D7.Введение и D7. Разработка собственного модуля ). С одной стороны, это может повысить “порог вхождения” в “клуб программистов D7” и сделать их еще более бородатыми, с другой – может отпугнуть новичков.
Будем надеяться, что исчерпывающая документация по новому ядру все-таки появится и мы (программисты, пользователи и разработчики 1С-Битрикс: Управление сайтом) пойдем в светлое будущее, где уже маячат PHP 7, EcmaScript 6 и другие радости web-технологий.