MODX. &where, примеры записей условий для выборки (примеры предикатов)
Отредактировано: 06 Февраля 2024
В случае, если надо конкретизировать условия выборки записей, используются предикаты — выражения которые в качестве результата возвращают TRUE, FALSE или UNKNOWN. В случае использования CMF MODX количество вариаций записи предикатов возрастает, из-за большого количества языков, которые понимает данная система.
Различия записей в языках:
SQL: WHERE width = 15
MODX: &where=`width = 15`
JSON в тегах MODX: &where = `{ "width":15 }` (данный тип записи в тегах MODX может срабатывать но заносить ошибку в лог)
xPDO: $query->where(array('width' => 15));
JSON в fenom: 'where' => '{"width":15}'
fenom: 'where' => [ 'width' => 15]
Ссылка на официальную документацию
Множественный выбор с условиями
MODX: &where=`width = 15 OR width = 25`
xPDO: $query->where(array
(
array( 'width' => 15), array('OR:width:=' => 25)));
JSON: { "0": { "width :=":"15","AND:height:=":"10" },"OR:width :=":"25" }
fenom: 'where' => [ 'width' => 15, 'OR:width:=' => 25 ]
Доступные операторы
Символ | Пример xPDO | Пример MODX | |
Равно | 'width' => 15 | `width = 15` | |
= | 'width:=' => 15 | ||
Равно (безопасное сравнение значения NULL) | <=> | ||
Не равно | != | 'width:!=' => 15 | `width != 15` |
<> | |||
Меньше | > | 'width:>' => 15 | `width > 15` |
Больше | < | 'width:<' => 15 | `width < 15` |
Больше или равно | >= | 'width:>=' => 15 | `width >= 15` |
Меньше или равно | <= | 'width:<=' => 15 | `width <= 15` |
Содержит | LIKE |
'width:LIKE' => '%15%' Переменная в Fenom: 'width:LIKE' => '%'~$.get.tag~'%' |
`width LIKE %15%` |
Не содержит | NOT LIKE | 'width:NOT LIKE' => '%15%' | `width NOT LIKE %15%` |
В массиве | IN | 'width:IN' => array(15,16,17,20) | |
Не в массиве | NOT IN | 'width:NOT IN' => array(15,16,17,20) | |
NOT | `width NOT 15 ` | ||
Если Null | IS | 'width:IS' => null | `width IS null` |
IS NULL | `width IS NULL ` | ||
Если Not Null | IS NOT NULL | `width IS NOT NULL` | |
Между | BETWEEN | ||
Включает | EXISTS | ||
Не включает | NOT EXISTS | ||
Соединяется | COALESCE | ||
Интервал | INTERVAL | ||
Наибольшее | GREATEST | ||
Наименьшее | LEAST | ||
Совпадает | MATCH | ||
Максимум | MAX | ||
Минимум | MIN | ||
В среднем | AVG | ||
Или | OR |
array( 'width' => 15), array('OR:width:=' => 10) |
|
И | AND |
array( 'width' => 15), array('AND:height:=' => 10) |
|
Регулярное выражение | REGEXP | `pagetitle REGEXP "MODX"` |
Трафаретные символы
При составлении предикатов (условий выборки) можно использовать трафаретные символы:
- символ подчеркивания (_) — означает любой единичный символ в проверяемом значении;
- символ процента (%) — означает последовательность любых символов в проверяемом значении. Количество символов в такой последовательности не ограничено (от 0 и более).
Образец | Описание |
---|---|
'abc%' | Любые строки, которые начинаются с букв «abc» |
'abc_' | Строки длиной строго 4 символа, причем первыми символами строки должны быть «abc» |
'%z' | Любая последовательность символов, которая обязательно заканчивается символом «z» |
'%word%' | Любая последовательность символов, содержащая слово «word» в любой позиции строки |
'% % %' | Текст, содержащий не менее 2-х пробелов, например, "World Wide Web" |
Трафаретные символы открывают большой простор для творчества при создании предикатов:
# Где class не заканчивается на o, но не на go
WHERE class NOT LIKE '%go' AND class LIKE '%o' ;
С трафаретными символами может возникнуть проблема в случае если искомая строка будет содержать аналогичные символы, например, если надо отыскать все значения, содержащие символ «_», то шаблон ‘%_%’ приведет к тому, что будут возвращены все записи из таблицы. В этом случае поможет указание экранирующего символа в ESCAPE или экранирующий символ \.
# указываем что символ # является экранирующим
'%#_%' ESCAPE '#'
# назначить можно любой символ, в этом примере |
LIKE '25|%' ESCAPE '|'
# некоторые версии SQL в качестве экранирующего могут принимать обратный слеш (\),
# по примеру популярных языков программирования
'%\_%'
'25\%'
Теги MODX
[[pdoResources?
&where = `published=1,deleted=0,createdby=12`
...
]]
Для сложных конструкций можно использовать чанк, сниппет или плейсхолдер вместо строки:
[[pdoResources?
&where=`[[CalculatedWhere]]`
...
]]
пример такого сниппета:
$where = array(
'published' => 1,
'deleted' => 0,
'createdby' => $modx->user->get('id'),
);
return $modx->toJSON($where);
Json
Обратите внимание, что при использовании JSON записи одновременно с шаблонизатором Fenom, после фигурных скобок надо проставлять пробелы. Иначе запись может вызвать ошибку в логах, несмотря на то что код будет обработан правильно.
[[pdoResources?
&where = `{ "published":1,"deleted":0,"createdby":12 }`
...
]]
Использование плейсхолдеров
Плейсхолдеры должны формироваться до вызова ресурсов. К примеру сниппет SetWhere формирующий плейсхолдер:
$jsonString = $modx->toJSON($input);
$modx->setPlaceholder('CalculatedWhere', $jsonString);
Вызов сниппетов
[[SetWhere?
&input=`month=January,year=2015`
]]
[[pdoResources?
&where=`[[+CalculatedWhere]]`
...
]]
Несколько вызовов на странице можно сформировать добавив дополнительный параметр. Формирование плейсхолдера:
$placeholderName = $scriptProperties['ph']
// ...
$modx->setPlaceholder($placeholderName, $value);
Вызов на странице:
[[SetWhere?
$month=`January`
&year=`2015
&ph=`January`
]]
[[getResources?
&where=`[[+January]]`
...
]]
...
[[SetWhere?
$month=`February`
&year=`2015
&ph=`February`
]]
[[getResources?
&where=`[[+February]]`
...
]]
Примеры
Получение всех ресурсов, опубликованных в течение определенного месяца того или иного года
[[getResources?
&where=`[[CalculatedWhere? &month=`January` &year=`2015`]]`
...
]]
Сниппет CalculatedWhere
$month = $scriptProperties['month'];
$year = $scriptProperties['year'];
$a_date = $month . ' ' . $year;
$min = strtotime($a_date);
$time = date("Y-m-t 23:59", $min);
$max = strtotime($time);
$where = array(
'publishedon:>=' => $min,
'publishedon:<=' => $max,
);
return $modx->toJSON($where);
// будет сформирована JSON строка вида
// {"publishedon:>=":1420092000,"publishedon:<=":1422770340}
Данные какого-либо плейсхолдера входят в массив
[[pdoResources?
&where = `[[+id]] IN (1,2,3,4,5)`
...
]]
php конструкция, формирующая запрос where
// опубликованные ресурсы, не являющиеся каталогом
$where = array( 'published' => 1, 'isfolder' => 0, );
// формирование were из GET данных
$filter = array();
if($_GET['tags']) {
$filter[] = 'tags='.$_GET['tags'];
}
if($filter) {
$where = $modx->toJSON(array($filter));
} else {
$where = '';
}
$params = array(
...
'where' => $where
);
where и оператор like в php
$arr = array (5,15,10,20);
$params = array(
...
'where' => [
'field:LIKE' => '%'.$arr.'%',
'field2:LIKE' => $arr.'%',
'field3:LIKE' => '%'.$arr
],
...
);
$out = $modx->runSnippet('pdoPage', $params);
Возможные ошибки
- Если после составления условия where в логах возникает ошибка «Error parsing condition with key 0», то вероятно неправильно составлены критерии выборки. Например, отсутствует хотя бы 1 рабочий параметр: «pagetitle REGEXP "MODX"» выдаст ошибку, в то время как «isfolder = 0 and pagetitle REGEXP "MODX"» выведет искомый результат.