Основные константы, функции и способы вывода в шаблонах Битрикс D7 и не только
Rus
Eng
Основные константы, функции и способы вывода в шаблонах Битрикс D7 и не только
Решаю сложные технические задачи для Bitrix и 1С: от аудита чужого кода до разработки сайтов и настройки сложных интеграций с гарантией результата
Рекомендую

Хостинг для сайта

Если выбираете хостинг под проект — советую Timeweb. Современная инфраструктура, широкий выбор тарифов от стартовых до VPS под нагрузку, отзывчивая техподдержка, которая отвечает по существу, а не отписками. Я сам держу на нём часть своих проектов и рекомендую клиентам.

Перейти Партнёрская ссылка. Для вас цена не меняется.

Навигация по разделам:

Вывод скриптов, стилей и метатегов Битрикс в header

$APPLICATION->ShowTitle() //Вывод заголовка страницы

//Вывод мета-тегов
$APPLICATION->ShowMeta("robots", false, false);	
$APPLICATION->ShowMeta("keywords", false, false);
$APPLICATION->ShowMeta("description", false, false);

$APPLICATION->ShowLink("canonical", null, false); //Канонический урл
$APPLICATION->ShowLink('prev', 'prev'); //rel="prev"
$APPLICATION->ShowLink('next', 'next'); //rel="next"

$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/main.css'); //Вывод отдельного css файла
$APPLICATION->AddHeadString('<link href="'.SITE_TEMPLATE_PATH.'"/css/common.min.css" type="text/css" rel="preload" />',true);

$APPLICATION->ShowCSS(true, false); //Вывод css стилей сайта

$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/jquery.min.js'); //Вывод одиночного скрипта

$APPLICATION->ShowHeadScripts();//Вывод объединенных скриптов

$APPLICATION->ShowHeadStrings();//Вывод как скриптов так и стилей добавленных через команду $APPLICATION->AddHeadString

$APPLICATION->ShowHead(); //Вывод всех служебных скриптов и стилей
$APPLICATION->ShowPanel(); //Вывод панели администратора

$APPLICATION->SetPageProperty('canonical', ($APPLICATION->IsHTTPS() ? 'https://' : 'http://') . 'domain.ru' . $APPLICATION->GetCurPage()); //Устанавливаем каноническую ссылку

if ($arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_TITLE']) {
	$APPLICATION->SetTitle($arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_TITLE']); //Устанавливаем заголовок страницы
	$APPLICATION->SetPageProperty('title', $arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_TITLE']); //Устанавливаем title страницы
}

if ($arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_DESCRIPTION']) {
	$APPLICATION->SetPageProperty("description", $arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_DESCRIPTION']); //Устанавливаем мета описание
}

if ($arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_KEYWORDS']) {
	$APPLICATION->SetPageProperty("keywords", $arResult['SECTION']['IPROPERTY_VALUES']['SECTION_META_KEYWORDS']); //Устанавливаем мета keywords
}

//D7
use Bitrix\Main\Page\Asset;

Asset::getInstance()->addJs(SITE_TEMPLATE_PATH . "/js/jquery.js"); //Добавление одиночного скрипта

Asset::getInstance()->addCss(SITE_TEMPLATE_PATH . "/css/main.css"); //Добавление одиночного стиля
Asset::getInstance()->addString('<link href="'.SITE_TEMPLATE_PATH.'"/css/common.min.css";  type="text/css" rel="preload" />');

Asset::getInstance()->addString("<link href='http://fonts.googleapis.com/css?family=PT+Sans:400&subset=cyrillic' rel='stylesheet' type='text/css'>"); //Добавление одинокой строчки в шапку

При установке свойств страницы часто бывает необходимо получить в header значение свойства в переменную. Стандартное подключение header.php в шаблоне не позволяет это сделать, поскольку инициализация сессии, свойств, подключения к БД происходят уже после. На выручку приходит отличный хак. Вместо

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");

Используйте такой вариант подключения:

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
$APPLICATION->SetPageProperty("mainImage", "background.jpg");
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_after.php");

Подключение скриптов в шаблоне компонета

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

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

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

// Старый вариант
CModule::IncludeModule("iblock");

// D7
use Bitrix\Main\Loader;

Loader::includeModule("iblock");

Есть возможность напрямую вызывать класс компонента

CBitrixComponent::includeComponentClass("tichiy:sale.order.ajax")

Работа с настройками модулей

//Старый вариант
COption::SetOptionString("main", "some_option", "option_value");
$temp = COption::GetOptionInt("main", "some_option");
COption::RemoveOption("main", "some_option", "s1");

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

Option::set("main", "some_option", "option_value");
$temp = Option::get("main", "some_option");
Option::delete("main", array(
    "name" => "some_option",
    "site_id" => "s1"
    )
);

Локализация

// Старый вариант
IncludeTemplateLangFile(__FILE__);
echo GetMessage("TEMPLATE_STRING");

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

Loc::loadMessages(__FILE__);
echo Loc::getMessage("TEMPLATE_STRING");

Кеширование

//Старый вариант
$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
$cache = Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache($cacheTime, $cacheId, $cacheDir))
{
    $result = $cache->getVars();
}
elseif ($cache->startDataCache())
{
    $result = array();
    // ...
    if ($isInvalid)
    {
        $cache->abortDataCache();
    }
    // ...
    $cache->endDataCache($result);
}

События

// 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");

Работа с файлами

// 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/"
);

Обработка ошибок

//Старый вариант
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();
}

Отладка

//Старый вариант
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"]."/log24342.txt");

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

//D7
// Запись отладочной информации в файл
Bitrix\Main\Diag\Debug::writeToFile(array('ID' => $id, 'fields'=>$fields ),"","/logs/logname.log");
Bitrix\Main\Diag\Debug::dumpToFile(array('ID' => $id, 'fields'=>$fields ),"","/logs/logname.log");

// Время исполнения скрипта
// В начале исследуемого участка кода, добавляем: 
Bitrix\Main\Diag\Debug::startTimeLabel('test 1');
// в конец: 
Bitrix\Main\Diag\Debug::endTimeLabel('test 1'); 
// И для вывода используем: 
Bitrix\Main\Diag\Debug::getTimeLabels(); 

// Получение текущей метки времени
Bitrix\Main\Diag\Helper::getCurrentMicrotime(); 

// Получение стека вызова функций
Bitrix\Main\Diag\Helper::getBackTrace($limit = 0, $options = null);

Настройки логирования ошибок в новом ядре в файле .settings.php

'exception_handling' => array (
  'value' => array (
      'debug' => false, //Включаем\выключаем отладку
      'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_STRICT & ~E_WARNING, //В ключе задаются типы ошибок, которые система отлавливает (не игнорирует)
      'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_COMPILE_WARNING, //В ключе задаются типы ошибок, при которых система выбрасывает исключение.
      'ignore_silence' => true,
      'assertion_throws_exception' => true,
      'assertion_error_type' => 256,
      'log' => array (
          'settings' => array (
				'file' => "bitrix/logs/Errors_" . date("Y_m_d") . ".log",
				'log_size' => 1000000, // ~ лимит размера файла 1Mb
          ),
      ),
  ),
  'readonly' => true,
),

Для отладки агентов можно воспользоваться константой BX_AGENTS_LOG_FUNCTION

define('BX_AGENTS_LOG_FUNCTION', 'TestAgents');

function TestAgents($agent, $operation, $result=false, $return=false){
    clearstatcache();
    $handle = fopen($_SERVER["DOCUMENT_ROOT"]."/agents.txt", "a");
    static $log = array();
    $time = date('Y-m-d-H:i:s');
    if($operation=='start'){
        $log[$agent['ID']] = microtime(true);      
        fwrite($handle, $_SERVER["REQUEST_TIME_FLOAT"].'-'.$time.'-'.$agent['ID'].'-start: '.$agent['NAME'].' ['.$agent['MODULE_ID'].'], '.$agent['AGENT_INTERVAL']."\n");
    }elseif($operation=='finish'){
        fwrite($handle, $_SERVER["REQUEST_TIME_FLOAT"].'-'.$time.'-'.$agent['ID'].'-finish ('.number_format(microtime(true) - $log[$agent['ID']], 4, '.', ' ').'s): '.$agent['NAME'].' ['.$agent['MODULE_ID'].'], '.$agent['AGENT_INTERVAL']."\n");
    }

    fclose($handle);
}

Отправка почты

//Старый вариант
CEvent::Send(
    "NEW_USER",
    "s1",
    array(
        "EMAIL" => "info@site.ru",
        "USER_ID" => 42
    )
);

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

Работа с GET- и POST

//Старый вариант
$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

//Старый вариант
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");

//Установка cookie через ajax с подключением только prologue_before
$application = Application::getInstance();
$context = $application->getContext();

$cookie = new Cookie("TEST", 12, time() + 60*60*24*60);
$cookie->setDomain($context->getServer()->getHttpHost());
$cookie->setHttpOnly(false);

$context->getResponse()->addCookie($cookie);
$context->getResponse()->flush("");
//Старый вариант
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();

Работа с БД

//Старый вариант
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);

Подключение включаемых областей

//Подключение в режиме php
$APPLICATION->IncludeFile(SITE_DIR."include/flash.php", Array(), Array("MODE"=>"php", "NAME"=>'Доставка и оплата')); 

//Подключение в режиме html
$APPLICATION->IncludeFile(SITE_DIR."include/flash.php", Array(), Array("MODE"=>"html", "NAME"=>'Доставка и оплата')); 

Подключение веб-мессенджера

$APPLICATION->IncludeComponent("bitrix:im.messenger", "", Array(), null, array("HIDE_ICONS" => "N"));

Работа с инфоблоками

//Вывод названия, описания и картинки инфоблока
$cntIBLOCK_List = 19; //ID инфоблока

$name=CIBlock::GetArrayByID($cntIBLOCK_List, "NAME"); //Название инфоблока
$description=CIBlock::GetArrayByID($cntIBLOCK_List, "DESCRIPTION"); //Описание инфоблока
$picture=CFile::GetPath(CIBlock::GetArrayByID($cntIBLOCK_List, "PICTURE")); //Изображение инфоблока

CIBlockSection::GetCount(array("IBLOCK_TYPE" => "INFO_AFW", 'IBLOCK_ID' => 18,'SECTION_ID' => $arResult["VARIABLES"]["SECTION_ID"]))//Получаем кол-во подразделов раздела

Константы

SITE_TEMPLATE_PATH //Путь к активному шаблону от корня сайта

SITE_ID //Идентификатор активного сайта

SITE_DIR //Папка сайта

LANGUAGE_ID //Текущий язык

Сессия

//Вывод идентификатора сессии в форме
echo bitrix_sessid_post();

//Получение идентификатора сессии в javascript
BX.bitrix_sessid()

Проверки

//Проверка на административную часть
if (defined('ADMIN_SECTION') && (ADMIN_SECTION === true))
  return false;

Типовые файлы

Генерация ошибки 404

Bitrix\Iblock\Component\Tools::process404(
	'Не найден', //Сообщение
	true, // Нужно ли определять 404-ю константу
	true, // Устанавливать ли статус
	true, // Показывать ли 404-ю страницу
	false // Ссылка на отличную от стандартной 404-ю
);

Передача данных из template.php или component_epilog.php в скрипт

Код в component_epilog.php

BX.message({
	FREE_BUTTON: '<? echo $button; ?>'
});

Код в script.js

BX.message('FREE_BUTTON')

Подключение файлов ядра Битрикс:

//Подключаем шапку
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
//Подключаем футер
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_after.php');
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php");
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_admin.php");

Передача $arResult в component_epilog

В конец файла tamplate.php добавляем

// добавляем к кэшируемому результату $arResult
if(property_exists($component, 'arResultCacheKeys')) {
    if(!is_array($component->arResultCacheKeys)) {
        $component->arResultCacheKeys = array();
    }
    $sVarName = 'arResult';
    $component->arResultCacheKeys[] = $sVarName;
    $component->arResult[$sVarName] = $$sVarName;
}

В начало файла component_epilog.php добавляем.

// заменяем $arResult эпилога значением, сохраненным в шаблоне
if(isset($arResult['arResult'])) {
    $arResult =& $arResult['arResult'];
    // подключаем языковой файл
    global $MESS;
    include_once(GetLangFileName(dirname(__FILE__).'/lang/', '/template.php'));
} else {
    return;
}

Передача данных из result_modifier.php в component_epilog

В конец файла result_modifier.php добавляем:

$this->__component->arResult["SIMILAR_PRODUCTS"] = $SECTIONS['SECTIONS'];
$this->__component->SetResultCacheKeys(array("SIMILAR_PRODUCTS"));

В component_epilog ключ получаем просто: $arResult['SIMILAR_PRODUCTS']

Добавляем ЧПУ в getlist

Иногда необходимо через getList() элемент каталога вместе с правильной ссылкой на элемент. На помощь приходит встроенная функция SetUrlTemplates.

$rs = CIBlockElement::GetList (
	Array(&quot;RAND&quot; =&gt; &quot;ASC&quot;),
	Array(&quot;IBLOCK_ID&quot; =&gt; 15,&quot;IBLOCK_TYPE&quot; =&gt; &#39;catalog&#39;),
	false,
	Array (&quot;nTopCount&quot; =&gt; 4)
);
$rs-&gt;SetUrlTemplates(&quot;/shop/#SECTION_CODE#/#ELEMENT_CODE#/&quot;);//Здесь записываем ЧПУ шаблон
while ($row = $rs-&gt;GetNext())
{
	//Вывод данных
}

Получить bxajaxid для ajax запросов

bxajaxid генерируется динамически, а потому в каждом компоненте его нужно получать отдельно

//Получаем bxajaxid для компонента\шаблона
$bxajaxid = CAjax::GetComponentID('bitrix:system.auth .form', 'personal');

//Получаем bxajaxid в компоненте на php < 7
$bxajaxid = CAjax::GetComponentID($component->__name, $component->__template->__name);

//Получаем bxajaxid в компоненте на php > 7
$bxajaxid = CAjax::GetComponentID($component->__name, $component->__template->__name, $component->arParams['AJAX_OPTION_ADDITIONAL']);

//Если вы получаете ошибку "Too few arguments to function CAjax::GetComponentID()", то попробуйте следующий вариант
CAjax::GetComponentID($component->__name, $component->__template->__name, '');

Передача полей из result_modifier в component_epilog

Добавляем в result_modifier.php

$item = \Bitrix\Iblock\ElementTable::getList(array(
    "select" => array("ID", "PREVIEW_TEXT", "DETAIL_TEXT", "PREVIEW_PICTURE", "DETAIL_PICTURE"),
    "filter" => array("IBLOCK_ID" => Stroy\Data\Config::getCatalogIB(), "ID" => $arResult['ID']),
    "order"  => array("ID" => "ASC")
))->fetch();

$cp = $this->__component;

if (is_object($cp)){
    $cp->arResult['CUSTOM'] = $item;
    $cp->SetResultCacheKeys(array('CUSTOM'));

}

В component_epilog.php эти данные можно получить в переменной

$arResult['CUSTOM']

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

Работа с системой битрикс

Репозиторий “Потрясающий битрикс”

Полезные инструменты для тех, кто в одной лодке с Bitrix

 

На основе материалов:

Александр Тихий
Автор статьи

Александр Тихий

Fullstack-разработчик · 1С-Битрикс

Разрабатываю и развиваю интернет-магазины и корпоративные порталы на 1С-Битрикс. Интеграции с 1С, highload-нагрузки, безопасность по 152-ФЗ.


Комментарии

Комментариев еще нет, Вы можете стать первым кто его оставит

Оставьте комментарий

На сайте используется система премодерирования комментариев, поэтому ваше сообщение будет опубликовано лишь после одобрения модератором

Вы отвечаете на комментарий пользователя

Отправить

ОБРАТНАЯ СВЯЗЬ

Напишите мне

Напишите мне, чтобы обсудить задачу. Работаю удаленно, официально (самозанятый), стоимость часа — 1800 ₽, в день могу уделять проекту 3–4 часа. Отвечаю быстро, консультация бесплатная.

Во время отправки произошла ошибка, пожалуйста попробуйте еще раз через некоторое время
Сообщение отправлено успешно

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

Россия, г. Москва

Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта