DAO Search Filter Syntax
DataAccessObject::select(), update(), and delete() accept a
$search array where each entry is column => value. By default the
operator is =, but the column key can carry an &OPERATOR suffix to
choose a different one. This page is the canonical reference for the
supported suffixes.
Convention: Always assign the condition array to a local
$searchvariable before passing it to the DAO. This makes call sites consistent and easier to read.
Default — Equality
$search = [
'status' => 'active', // status = 'active'
'id' => 42, // id = 42
];
$rows = $this->select('users', $search);
null becomes IS NULL:
$search = [
'parent_id' => null, // parent_id IS NULL
];
Negation And NULL Checks
$search = [
'status&!=' => 'deleted', // status <> 'deleted'
'parent_id&IS' => null, // parent_id IS NULL
'parent_id&IS NOT' => null, // parent_id IS NOT NULL
];
Comparison
| Suffix | SQL |
|---|---|
&> |
> |
&>= |
>= |
&< |
< |
&<= |
<= |
$search = [
'price&>=' => 100,
'created_at&<' => '2026-01-01',
];
Set Membership
$search = [
'status&IN' => ['active', 'draft'], // status IN (...)
'status&NOT IN' => ['deleted'], // status NOT IN (...)
];
Always check that the array is non-empty before passing it to the DAO — passing an empty array currently raises an error.
Pattern Matching
$search = [
'caption&LIKE' => '%Festi%',
'caption&ILIKE' => '%festi%', // PostgreSQL only
];
The wildcard characters (%, _) are not escaped — supply them
yourself and quote any user input separately if needed.
Subqueries
Raw SQL strings are not allowed in plugin or business code. Build
subqueries with the Query builder or wrap a fragment in
Expression, then pass the resulting object as the search value.
use core\dao\Query;
$query = new Query($this->db);
$query->column('1')
->from('orders')
->where(['orders.user_id' => new Expression('users.id')]);
$search = [
'&EXISTS' => $query,
];
For multiple EXISTS clauses on the same query, prefix the key with
any unique label so the array keys remain distinct
(e.g. 'one&EXISTS', 'two&EXISTS'). See the README section on
EXISTS and NOT EXISTS conditions
for more variants, including Query and Expression usage.
Arithmetic Updates
The + and - suffixes (no &) are used in the values array of
update() to apply an incremental change instead of a literal
assignment:
$search = ['id' => $userID];
$values = [
'login_count+' => 1,
'balance-' => 100,
];
$this->update('users', $values, $search);
OR Conditions
Wrap an array of sub-searches under the sql_or key:
$search = [
'status' => 'active',
'sql_or' => [
['type' => 'admin'],
['type' => 'editor', 'verified' => true],
],
];
This produces status = 'active' AND ((type = 'admin') OR (type =
'editor' AND verified = TRUE)).
Order, Limit, Offset
These are separate arguments — they are not keys in the $search
array.
$rows = $this->select(
'contents',
$search,
['cdate DESC'], // order by
20, // limit
40 // offset
);