Как вывести ближайшие дни рождения пользователей - Битрикс
В данном примере рассмотрим написание компонента, который будет выводить ближайшие дни рождения пользователей на сайте. Изначально эта функция доступна с модулем корп. портала, мы напишем свой компонент для любой редакции 1С Битрикс: Управление сайтом.
Была задача: показывать дни рождения пользователей за ближайшие 10 дней. Окончательное решение выглядит так:
Первой идеей, которая пришла в голову была: получить пользователей по заданному фильтру, так как указано в документации
$rsUsers = CUser::GetList(($by="personal_country"), ($order="desc"), $filter); // выбираем пользователей
В массиве $filter мы можем задать поля для сортировки, среди которых есть:
PERSONAL_BIRTHDAY_1 - день рождения "с"
PERSONAL_BIRTHDAY_2 - день рождения "по"
Исходя из этих полей мы сможем к текущий дате прибавить 10 дней и вывести всех пользователей, которые попадают под это условие, но тут столкнулись с проблемой: эти поля отвечают за дату рождения вместе с годом рождения, мы же запрашиваем диапазон дат в текущем году. Соответсвенно данный метод нам не подошел.
Вторым вариантом было перебирать каждый год с выбранным диапазоном дат. Данный способ совсем не "экономичный", особенно если компонент не использует кеширование.
В комментариях был найден новый вариант использования, более "экономный":
$arFilter = array(
"PERSONAL_BIRTHDAY_DATE" => date('m-d'), // именно так: месяц-день
"ACTIVE" => 'Y',
);
Так мы получим пользователей, у которых день рождения в заданный день. Остается перебрать дни. Десять проходов (на каждый день) куда экономичнее, чем перебор каждого года.
Использовать можно как и в виде компонента, так и использовать включаемую область с php кодом.
Вконце статьи можно скачать архив с данным компонентом. В данном примере я приведу код компонента, параметров и шаблона вывода.
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arComponentParameters = array(
"PARAMETERS" => array( //массив параметров для компонента
"TITLE" => array( //Заголовок блока в котором будут выводиться наши данные
"PARENT" => "BASE",
"NAME" => GetMessage("TITLE"),
"TYPE" => "STRING",
"DEFAULT" => "Ближайшие дни рождения",
"REFRESH" => "N",
"COLS" => "40"
),
"DAYS_AFTER" => array( //Сколько дней просчитывать от текущей даты
"PARENT" => "BASE",
"NAME" => GetMessage("DAYS_AFTER"),
"TYPE" => "STRING",
"DEFAULT" => "10",
"REFRESH" => "N",
"COLS" => "15"
),
"FORMAT" => array( //формат вывода даты
"PARENT" => "BASE",
"NAME" => GetMessage("FORMAT"),
"TYPE" => "STRING",
"DEFAULT" => "j F",
"REFRESH" => "N",
"COLS" => "15"
),
)
);
?>
Параметр FORMAT принимает строчки в формате php даты и в формате даты Битрикса, подробнее про форматы дат в битрикс можно узнать тут.
Теперь код самого компонента:
Сначала получаем текущую дату и считаем дату окончания
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$daysAfter = $arParams["DAYS_AFTER"]; //за сколько дней показывать дни рождения
$nowDate = date($DB->DateFormatToPHP(CSite::GetDateFormat("SHORT")), time());//получаем текущую дату
$tmpDate = ConvertDateTime($nowDate, "MM-DD", "ru"); //текущая дата в нужном нам формате m-d
2. Теперь в цикле будем получать новую дату для получения пользователей
for ($i=0; $i <= $daysAfter ; $i++) {
$tmpDate = MakeTimeStamp($tmpDate, "MM-DD"); //переводим формат даты
$arrAdd = array(
"DD" => $i,
"MM" => 0,
"YYYY" => 0,
"HH" => 0,
"MI" => 0,
"SS" => 0,
);
$tmpDate = AddToTimeStamp($arrAdd, $tmpDate);
$tmpDate = date("m-d", $tmpDate); //теперь в tmpDate текущая дата +$i дней
3. Остается только получить пользователей у которых день рождения в указанный день
$filter = Array
(
"PERSONAL_BIRTHDAY_DATE"=> $tmpDate
);
$rsUsers = CUser::GetList(($by="timestamp_x"), ($order="desc"), $filter); // выбираем пользователей
4. Так как возможны несколько дней в которые возможны дни рождения сложим пользователей в массив с ключем в виде даты
while ($arUser = $rsUsers->GetNext()){ //проверяем результаты
$dateFormat = FormatDate($arParams["FORMAT"], MakeTimeStamp($arUser["PERSONAL_BIRTHDAY"])); // Создаем дату в формате заданном в параметрах
$arResult[$dateFormat][$arUser["ID"]]=$arUser; //делаем полученую дату ключем массива и в этот массив записываем пользователей по их ID
}
}//конец цикла
$this->IncludeComponentTemplate(); // выводим шаблон
На выходе мы получаем такой массив:
[24 Апреля] => Array
(
[4] => Array
(
[ID] => 4
[~ID] => 4
[PERSONAL_BIRTHDAY] => 24.04.1998
...
)
)
[28 Апреля] => Array
(
[2] => Array
(
[ID] => 2
[~ID] => 2
[PERSONAL_BIRTHDAY] => 28.04.1993
[~PERSONAL_BIRTHDAY] => 28.04.1993
...
)
)
Осталось написать шаблон вывода у нас он имеет такой вид:
<div class="b-white col-xs-12 mb10">
<div class="row">
<div class="yellow col-xs-12">
<?=$arParams["TITLE"]?>
</div>
<div class="col-xs-12 dr">
<div class="row">
<?foreach ($arResult as $formatedDate => $currentDate):?>
<p><?=$formatedDate?></p>
<?foreach ($currentDate as $userID => $user):?>
<p>
<a href="#"><?=$user["NAME"]?> <?=$user["LAST_NAME"]?></a>
</p>
<?endforeach;?>
<?endforeach;?>
</div>
</div>
</div>
</div>