Условия выборки
1 2 3 4 5 6 7 8 |
"!" - не равно "< " - меньше "<=" - меньше либо равно ">" - больше ">=" - больше либо равно ">< " - между "!>< " - не между false - без значения |
Маски фильтров
Примеры фильтров
Фильтрация по пользовательским свойствам типа «Дата»
При поиске по не встроенным полям (НЕ «начало активности», НЕ «конец активности») обязательно конвертировать дату в формат хранения YYYY-MM-DD HH:MI:SS (DateTime::format(‘Y-m-d H:i:s’)), например выбор записей не старше 31 дня:
1 2 3 |
$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 дня:
1 2 |
$now = new DateTime(); $arFilter = array(">DATE_CREATE" => $now->modify('-31 day')->format('d.m.Y H:i:s')); |
Выбор новостей за день или за месяц
Если у новости ее датой является «начало активности», и нет продолжительности по времени, то есть «конец активности» несет смысл только снятия ее с публикации, то выбор новостей за день или месяц происходит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$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; </date_active_from> |
Выбор событий с интервалом
Допустим, событие (акция) имеет продолжительность, которую указываем в полях «начало активности» и «конец активности», без учета времени, только дата.
«Конец активности» в данном случае служит для указания конца интервала времени, а не снятия с публикации (хотя такое тоже возможно).
Тогда выбор текущего события выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$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’] — массив номеров инфоблоков
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
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 вставить:
1 |
$dayActivites = $this->isDaysActiveCond($this->dateBegin); |
Модифицировать $query:
1 |
$query = "SELECT EXTRACT(DAY FROM `ACTIVE_FROM`) AS `day`, `PREVIEW_PICTURE` as `pic`, `NAME` as `name`, `ACTIVE_TO` as `act_to`, {$dayActivites} ..." |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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).