A single filter: a set of path => condition pairs, ALL of which must match (an implicit AND) for test to pass. Each condition is either a plain value (equality) or a ['$operator' => value] pair (FilterOperator).
Methods20
Empty the underlying content, keeping the object itself.
function clear()$bag->clear(); // count($bag) === 0 afterwards
\Countable::count
function count(): intCreate a Filter or FilterGroup from an array or string.
static function From(array|string $data, ArrayAccess|array $vars = []): MMO\core\interfaces\iFilterSupported string format:
`({path} {operator} {value}) {groupOperator} (...)`
- {path}: valid json identifier on which the operator is applied. @ex `man/name`
- {operator}: valid FilterOperator (starting with `$` or `<=`,`>=`,`!`,`=`)
- {value}: valid json value.
- if {value} is inside curly brackets and starts with #, it is converted to a reference
to a path in the data. (example: {#xxx/yyy} represents the value at data[xxx][yyy])
- if {value} is inside curly brackets and starts with $, it is a value given in the vars
(example {$xxx} is replaced by $vars['xxx'])
- {groupOperator}: `!` (not), `&` (and), `|` (or)| $data | array | string | |
| $vars = [] | ArrayAccess | array | variables to inject in the string data (does not work if $data is an array) to use a variable, write it {$xxx} where xxx is a key in $vars |
| returns | iFilter | |
look for all firstname = lastname or firstname = $vars['name']
- (firstname = {#lastname}) | (firstname = {$name})Filter::From(['name' => 'Marc', 'age' => ['$gte' => 18]]); // a FilterFilter::From(['$or' => [['name' => 'Marc'], ['name' => 'Bob']]]); // a FilterGroupFilter::From(['age' => ['$gte' => 18, '$lt' => 65]]); // an AND FilterGroup: one condition per operatorFilter::From(['name' => 'Marc', '$or' => [['age' => 18], ['age' => 30]]]); // name AND (age OR age)Filter::From('(name = "Marc") & (age >= 18)');Filter::From('name = {$who}', ['who' => 'Marc']);
function getContent(): array| returns | array | raw path => (scalar|FilterValue) content |
\IteratorAggregate::getIterator
function getIterator(): Traversablefunction has(string $path): bool| $path | string | |
| returns | bool | true if this filter has a condition on $path |
Whether $value is a condition (['$gte' => 18], ['>=' => 18, '<' => 65]) rather than a value to compare with: each of its keys is an operator, or starts with $ like one.
static function IsCondition(array $value): boolfunction isEmpty()| returns | | true if the underlying content has no elements |
$bag->isEmpty(); // true right after clear(), false as soon as an item is set
\JsonSerializable::jsonSerialize -- the raw content is returned as-is (not recursively converted), so json_encode() relies on any nested iArray values being JsonSerializable themselves.
function jsonSerialize(): mixedjson_encode($bag); // e.g. '{"x":1,"0":2}'
function keys(): array| returns | array | the list of keys currently set |
$bag->keys(); // e.g. ['x', 0]
Load every entry of a plain array into the content, through offsetSet (so any offsetSet() override defined by the class using this trait, e.g. for validation or type coercion, is honored for every entry).
function loadArray(array $data): static$bag->loadArray(['x' => 1, 'y' => 2]); // equivalent to $bag['x'] = 1; $bag['y'] = 2;
\ArrayAccess::offsetExists
function offsetExists(mixed $key): bool\ArrayAccess::offsetGet
function offsetGet(mixed $key): mixed\ArrayAccess::offsetSet -- a ['$operator' => value] array is recognized and converted into a FilterValue automatically (so $filter['age'] = ['$gte' => 18] behaves the same as building it via From).
function offsetSet(mixed $offset, mixed $value): void| $offset | mixed | |
| $value | mixed | |
| returns | void | |
| throws | | for an unknown operator (['$gtee' => 18]), or several of them: a Filter holds one condition per path (From makes one Filter of each). The value of a NATIVE_OPERATORS is kept as it is. |
\ArrayAccess::offsetUnset -- on a list (sequential integer keys, as produced by $bag[] = ...), the element is spliced out (closing the gap and reindexing), matching \unset() semantics on a plain PHP list; on an associative array, the key is simply removed.
function offsetUnset(mixed $key): voidunset($bag[0]); // on a list: every following index shifts down by one, like array_splice()
function test(ArrayAccess|array $data, ?MMO\core\schemas\Schema $schema = null): bool| $data | ArrayAccess | array | the record to test |
| $schema = null | null | Schema | if given, each condition's value is coerced through the matching property's schema before comparing (e.g. so a string '18' compares correctly against an integer age); a value whose schema is not known (owner/username, when owner is typed with an interface: Schema::walkSchemaFor), or a bool one, is compared as it is |
| returns | bool | true if EVERY path/condition in this filter matches (implicit AND) |
(new Filter(['age' => ['$gte' => 18]]))->test(['age' => 30]); // true
function toArray(): array| returns | array | MongoDB-style filter array, e.g. ['name' => 'Marc', 'age' => ['$gte' => 18]] |
function toClosure(ArrayAccess|array $data, ?MMO\core\schemas\Schema $schema = null): Closurefunction __construct(array $data = [])function __toString(): string| returns | string | e.g. '(name = "Marc" & age $gte 18)' |