Красивая пагинация на битриксе / bitrix pagination

Сделал свою пагинацию на битриксе. Получилось вот так.
Минусы:
— Код некачественный. Если есть идеи по оптимизации, пишите в комментариях, поправлю.
— Игнорирует пагинацию в «обратном порядке». Не увидел смысла в ней, поэтому отказался.

Тут можно изменять только один параметр:
$countPagesDisplay — это количество отображаемых страничек снизу (помимо первой, последней, стрелок и «…»).

Выглядит вот так:

[code lang=»php»]
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

if(!$arResult["NavShowAlways"])
{
if ($arResult["NavRecordCount"] == 0 || ($arResult["NavPageCount"] == 1 && $arResult["NavShowAll"] == false))
return;
}

// begin zadavaemie parametri

$countPagesDisplay = 3; // kolichestvo otobrajaemih stranic v paginacii

// end zadavaemie parametri

function addLeftBorder($lb) {
if ($lb > 1) {
$lb = $lb — 1;
}
return $lb;
}

function addRightBorder($rb,$max) {
if ($rb < $max) {
$rb = $rb + 1;
}
return $rb;
}

$i = 1;
$left_border = $arResult["NavPageNomer"];
$right_border = $arResult["NavPageNomer"];
$max = $arResult["NavPageCount"];

while($i < $countPagesDisplay) {
if($i % 2 == 0) {
$lb = $left_border;
$left_border = addLeftBorder($left_border);
if ($left_border == $lb) {
$rb = $right_border;
$right_border = addRightBorder($right_border, $max);
if ($right_border == $rb) {
$i = $countPagesDisplay;
}
}
} else {
$rb = $right_border;
$right_border = addRightBorder($right_border, $max);
if ($right_border == $rb) {
$lb = $left_border;
$left_border = addLeftBorder($left_border);
if ($left_border == $lb) {
$i = $countPagesDisplay;
}
}
}
$i++;
}
$arResult["nStartPage"] = $left_border;
$arResult["nEndPage"] = $right_border;

//echo "<pre>"; print_r($arResult);echo "</pre>";

$strNavQueryString = ($arResult["NavQueryString"] != "" ? $arResult["NavQueryString"]."&amp;" : "");
$strNavQueryStringFull = ($arResult["NavQueryString"] != "" ? "?".$arResult["NavQueryString"] : "");

?>
<div class="paginator">

<font class="text">

<?if ($arResult["NavPageNomer"] > 1):?>

<?if($arResult["bSavePage"]):?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["NavPageNomer"]-1)?>">&larr;</a>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=1">1</a>
<?else:?>
<?if ($arResult["NavPageNomer"] > 2):?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["NavPageNomer"]-1)?>">&larr;</a>
<?else:?>
<a href="<?=$arResult["sUrlPath"]?><?=$strNavQueryStringFull?>">&larr;</a>
<?endif?>
<?if ($arResult["nStartPage"] != 1):?>
<a href="<?=$arResult["sUrlPath"]?><?=$strNavQueryStringFull?>">1</a>
<?endif?>
<?endif?>

<?else:?>
&larr;&nbsp;
<?endif?>

<?if ($arResult["nStartPage"] > 2):?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["nStartPage"]-1)?>">…</a>
<?endif?>

<?while($arResult["nStartPage"] <= $arResult["nEndPage"]):?>

<?if ($arResult["nStartPage"] == $arResult["NavPageNomer"]):?>
<span><?=$arResult["nStartPage"]?></span>
<?elseif($arResult["nStartPage"] == 1 && $arResult["bSavePage"] == false):?>
<a href="<?=$arResult["sUrlPath"]?><?=$strNavQueryStringFull?>"><?=$arResult["nStartPage"]?></a>
<?else:?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=$arResult["nStartPage"]?>"><?=$arResult["nStartPage"]?></a>
<?endif?>
<?$arResult["nStartPage"]++?>
<?endwhile?>

<?if ($arResult["nEndPage"] < ($arResult["NavPageCount"] — 1)):?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["nEndPage"]+1)?>">…</a>
<?endif?>

<?if($arResult["NavPageNomer"] < $arResult["NavPageCount"]):?>
<?if($arResult["nEndPage"] < $arResult["NavPageCount"]):?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=$arResult["NavPageCount"]?>"><?=$arResult["NavPageCount"]?></a>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["NavPageNomer"]+1)?>">&rarr;</a>
<?else:?>
<a href="<?=$arResult["sUrlPath"]?>?<?=$strNavQueryString?>PAGEN_<?=$arResult["NavNum"]?>=<?=($arResult["NavPageNomer"]+1)?>">&rarr;</a>
<?endif?>
<?else:?>
&nbsp;&rarr;
<?endif?>

</div>
[/code]

Делаем теги и ссылки к ним в статьях битрикса

Можно решить эту задачу так. Для этого в конец компонента bitrix:news (скопировав его) следует вставить функцию:

[code lang=»php»]
<?
function addLinkForTag($tagname) {
$taglink = str_replace(‘ ‘,’+’,$tagname); // Пробелы должны заменяться плюсами
return ‘<a href="/search/?tags=’.$taglink.’">’.$tagname.'</a>’; // Добавляем ссылку. Внимание, у вас ссылка может быть не "/search/", а какая-либо другая!
}
?>
[/code]

И для тех же статей (при условии, что все стандартно) в компоненте bitrix:news.list можно написать что-либо подобное:

[code lang=»php»]
<?foreach($arItem["FIELDS"] as $code=>$value):?> // Это уже было — стандартный перебор свойств каждой новости
<small>
<?
if (GetMessage("IBLOCK_FIELD_".$code) == ‘Теги’) { // Желательно написать как-нибудь по другому, но на данный момент идей как правильно — нет 🙂
if(CModule::IncludeModule("search")) { // Необходимо подключить модуль поиска. Без него работать не будет
$tags_array = tags_prepare($value, "s1"); // Распиливаем теги в массив
echo GetMessage("IBLOCK_FIELD_".$code).’: ‘; // Выводим название "Теги"
$tags_array = array_map("addLinkForTag",$tags_array); // Применяем функцию для создания ссылок для элементов массивов
$result_tags = implode(", ", $tags_array); // Соединяем все обратно в одну строку
echo $result_tags; // Выводим результат
}
} else { // Если у нас не Тег, то просто выводим как обычно "ключ" : "значение" (эта строка была по умолчанию)
echo GetMessage("IBLOCK_FIELD_".$code).’: ‘.$value;
}
?>
</small>
<br />
<?endforeach;?>
[/code]

Затем создаем страницу в битриксе и вставляем в нее компонент поиска bitrix:search.page. Собственно, ссылка на него и будет ссылкой, на которую надо поменять мой «/search/».

Обработка отправления почты в bitrix

Возникла задача — отправлять письмо о заказе, кроме клиента, на два разных ящика. Притом, ящики должны были чередоваться (в той организации два конкурирующих менеджера). Сразу возник алгоритм, что при отправке письма проверять, четный или нечетный ID заказа, и в зависимости от этого, отправлять письмо на тот, или иной ящик.
Больше всего времени пришлось затратить на поиск документации, к какому событию привязывается отправление почты. В оф. документации поиск ничего не дал — но, оказалось, что плохо искал, т.к. там эта информация была.

Для написания пригодилось знать следующее:

Событие http://dev.1c-bitrix.ru/api_help/main/events/onbeforeeventadd.php вызывается в момент добавление почтового события в таблицу b_event. Как правило, задача обработчика данного события — изменить или добавить какое-либо значение, передаваемое в макросы почтового шаблона.

Порядок выполнения страницы (в данном случае не слишком пригодилось, но однозначно полезная информация).

Почтовая система

Итак, сам код. Его надо разместить в /bitrix/php_interface/init.php.

[code lang=»php»]
<?
AddEventHandler("main", "OnBeforeEventAdd", array("MailCheredator", "OnBeforeEventAddHandler"));

class MailCheredator {
function OnBeforeEventAddHandler(&$event, &$lid, &$arFields) {
$arFields["SALE_EMAIL"] = "sale_mail@example.ru";
$arFields["BCC"] = "";
if (intval($arFields["ORDER_ID"]) % 2 == 1) {
$arFields["EMAIL"] = $arFields["EMAIL"]. ",email1@example.ru";
} else {
$arFields["EMAIL"] = $arFields["EMAIL"]. ",email2@example.ru";
}
}
}
?>
[/code]
Здесь,
SALE_EMAIL — в моем случае, адрес, с которого отправляется письмо (у вас может быть другой!).
BCC — сюда отправляются копии письма, которые не должен видеть тот, кому отправляется письмо (можно было email1 и email2 сюда записать).
EMAIL — адрес, куда отправится письмо. Можно перечислять через запятую.

Просмотр всех свойств элемента инфоблока

Пригодится для просмотра в API битрикса всех данных об элементах инфоблока. А потом найденное можно будет изменить. Подробности можно прочитать тут: http://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php

[code lang=»php»]
<?
$arFilter = Array(
"IBLOCK_ID"=>IntVal(2), //id инфоблока
"ACTIVE"=>"Y", // только активные
"SECTION_ID"=>38, // id раздела в инфоблоке
"INCLUDE_SUBSECTIONS"=>"Y" // чтобы включались подразделы
);
$res = CIBlockElement::GetList(Array("SORT"=>"ASC", "PROPERTY_PRIORITY"=>"ASC"), $arFilter);
while($ob = $res->GetNextElement())
{
$arFields = $ob->GetFields();
echo $arFields["NAME"]."<br />";
print_r($arFields);
$arProps = $ob->GetProperties();
print_r($arProps);
echo "<br /><br />";
}
?>
[/code]