Содержание
Выборка (фильтрация) в Битриксе
Условия выборки
"!" - не равно "<" - меньше "<=" - меньше либо равно ">" - больше ">=" - больше либо равно "><" - между "!><" - не между false - без значения
По дате
Фильтрация по пользовательским свойствам типа "Дата"
При поиске по не встроенным полям (НЕ «начало активности», НЕ «конец активности») обязательно конвертировать дату в формат хранения YYYY-MM-DD HH:MI:SS
(DateTime::format('Y-m-d H:i:s')
), например выбор записей не старше 31 дня:
- property-date-search.php
$dateNow = new DateTime('now', new DateTimeZone('UTC')); $dateNow->modify('-31 day'); $arFilter['>=PROPERTY_PAY_DATE'] = $dateNow->format('Y-m-d H:i:s');
Фильтрация по "началу" и "концу активности"
Наоборот, для полей «начало активности» и «конец активности» следует использовать формат DD.MM.YYYY HH:MI:SS
(DateTime::format('d.m.Y H:i:s')
).
Фильтрация по дате создания
Выбрать записи не старше 31 дня:
- date-create-filter.php
$now = new DateTime(); $arFilter = array(">DATE_CREATE" => $now->modify('-31 day')->format('d.m.Y H:i:s'));
Выбор новостей за день или за месяц
Если у новости ее датой является «начало активности», и нет продолжительности по времени, то есть «конец активности» несет смысл только снятия ее с публикации, то выбор новостей за день или месяц происходит так:
- calendar.php
<?php $BITRIX_DATETIME_FORMAT = 'd.m.Y H:i:s'; $activeYear = isset($_REQUEST['year']) ? (int)$_REQUEST['year'] : null; $activeMonth = isset($_REQUEST['month']) ? (int)$_REQUEST['month'] : null; $activeDay = isset($_REQUEST['day']) ? (int)$_REQUEST['day'] : null; $activeCompany = isset($_REQUEST['company']) ? (int)$_REQUEST['company'] : null; $arFilter = array("IBLOCK_ID"=>BlockId::_()->news); switch(true) { case isset($activeDay) && isset($activeMonth) && isset($activeYear): // новости за день $dateBegin = new DateTime(sprintf('%1$04d-%2$02d-%3$02d 00:00:00', $activeYear, $activeMonth, $activeDay), new DateTimeZone('UTC')); $dateEnd = clone $dateBegin; $dateEnd->modify('+1 day -1 second'); break; case isset($activeMonth) && isset($activeYear): // новости за месяц $dateBegin = new DateTime(sprintf('%1$04d-%2$02d-%3$02d 00:00:00', $activeYear, $activeMonth, $activeDay), new DateTimeZone('UTC')); $dateEnd = clone $dateBegin; $dateEnd->modify('+1 month -1 second'); break; default: } if (isset($dateBegin) && isset($dateEnd)) { $arFilter['><DATE_ACTIVE_FROM'] = array($dateBegin->format($BITRIX_DATETIME_FORMAT), $dateEnd->format($BITRIX_DATETIME_FORMAT)); } $GLOBALS['arFilter'] = $arFilter;
Выбор событий с интервалом
Допустим, событие (акция) имеет продолжительность, которую указываем в полях «начало активности» и «конец активности», без учета времени, только дата.
«Конец активности» в данном случае служит для указания конца интервала времени, а не снятия с публикации (хотя такое тоже возможно).
Тогда выбор текущего события выглядит так:
- event.php
$BITRIX_DATETIME_FORMAT = 'd.m.Y H:i:s'; $arFilter = array("IBLOCK_ID" => $this->arParams['IBLOCK_ID'], "ACTIVE"=>"Y"); $arSort = array("SORT" => "DESC"); $arSelect = array("IBLOCK_ID", "ID", "CODE", "NAME", "PREVIEW_TEXT", "PREVIEW_PICTURE", "ACTIVE_FROM", "ACTIVE_TO", "TAGS"); // для архива событий на определенную дату $dateBegin = new DateTime(sprintf('%1$04d-%2$02d-%3$02d 00:00:00', $_REQUEST['year'], $_REQUEST['month'], $_REQUEST['day']), new DateTimeZone('UTC')); // для актуальных событий $dateBegin = new DateTime(sprintf('%1$04d-%2$02d-%3$02d 00:00:00', date('Y'), date('m'), date('d')), new DateTimeZone('UTC')); $arDayFilter = $arFilter; $dateEnd = clone $dateBegin; $dateBegin->modify('+1 day -1 second'); $arDayFilter['<=DATE_ACTIVE_FROM'] = $dateBegin->format($BITRIX_DATETIME_FORMAT); $arDayFilter['>=DATE_ACTIVE_TO'] = $dateEnd->format($BITRIX_DATETIME_FORMAT); $itemsListDay = CIBlockElement::GetList($arSort, $arDayFilter, false, false, $arSelect);
Быстрый выбор новостей в календарь за месяц из нескольких инфоблоков
Высокая скорость обеспечивается прямым обращением к базе данных. В качестве даты новости - поле «Начало активности».
$this-\>arParams['IBLOCK_ID']
- массив номеров инфоблоков
- month_calendar.php
class BAEventsEngine { const MYSQL_DATETIME_FORMAT = 'Y-m-d H:i:s'; public function getDates($year, $month) { global $DB; $dates = array(); $monthDates = array(); $this->calcStartEndDate($year, $month); $query = "SELECT EXTRACT(DAY FROM `ACTIVE_FROM`) AS `day`, `PREVIEW_PICTURE` as `pic`, `NAME` as `name`, `ACTIVE_TO` as `act_to` FROM `b_iblock_element` WHERE IBLOCK_ID IN (".implode(', ', (array)$this->arParams['IBLOCK_ID']).") AND ACTIVE = 'Y' AND (ACTIVE_FROM BETWEEN '".$this->dateBegin->format(self::MYSQL_DATETIME_FORMAT)."' AND '".$this->dateEnd->format(self::MYSQL_DATETIME_FORMAT)."') ORDER BY SORT"; $CDatabaseRes = $DB->Query($query, false, ''); if ($CDatabaseRes->SelectedRowsCount() > 0) { while ($result = $CDatabaseRes->Fetch()) { $day =& $dates[$result['day']]; if(!isset($day)) $day = array(); if(!isset($day['pic'])) { $day['pic'] = $result['pic']; } if($result['act_to'] == null) { $monthDates[100][] = $result; } else { $monthDates[$result['day']][] = $result; } } unset($day); ksort($monthDates); } return array($dates, $monthDates); } private $dateBegin, $dateEnd; private function calcStartEndDate($year, $month) { $this->dateBegin = new DateTime(sprintf('%1$04d-%2$02d-%3$02d 00:00:00', $year, $month, 1), new DateTimeZone('UTC')); $this->dateEnd = clone($this->dateBegin); $this->dateEnd->modify("+1 month -1 second"); } }
Если события в таком календаре имеют продолжительность, возможно узнать, активно ли событие активность в данный день. Перед $query
вставить:
$dayActivites = $this->isDaysActiveCond($this->dateBegin);
Модифицировать $query
:
$query = "SELECT EXTRACT(DAY FROM `ACTIVE_FROM`) AS `day`, `PREVIEW_PICTURE` as `pic`, `NAME` as `name`, `ACTIVE_TO` as `act_to`, {$dayActivites} ..."
private function isDaysActiveCond($date) { $cond = array(); $numDaysInMonth = $date->format('t'); $year = $date->format('Y'); $month = $date->format('m'); for($i = 1; $i <= $numDaysInMonth; $i++) { $day = sprintf('%1$02d', $i); $cond[] = "(`ACTIVE_FROM` <= '{$year}-{$month}-{$day} 23:59:59' AND `ACTIVE_TO` >= '{$year}-{$month}-{$day} 00:00:00') AS `day_{$i}`"; } return implode(', ', $cond); }
Таким образом в выборку попадут поля day_1, day_2, ..., содержащие признак активности события в этот день (1).