Skip to content

Criteria

phil/listings

A criterion is a name the application defines — lowercase ASCII segments of at most 64 bytes — and a value of one of three types:

TypeBuilt byHoldsMeets a wanted criterion of the same name and type when
ChoiceCriterion::choice($name, $choices)1 to 32 distinct values of up to 64 ASCII letters, digits, ., _, : or -, in the order giventhey share at least one value
RangeCriterion::range($name, $min, $max)two integers, both ends included, $min not above $maxthey share at least one integer
FlagCriterion::flag($name, $flag)yes or nothey are equal

A choice's values are keys, not labels: the application translates them, and the same key means the same thing in every language. A range holds whole numbers: a salary band in whole units, a number of players, an age bracket. The fields a type does not use are empty: a choice has no ends, a range no choices.

use Phil\Listings\Criteria;
use Phil\Listings\Criterion;

$listing = Criteria::of([
    Criterion::choice('day', ['sat', 'sun']),
    Criterion::range('players', 3, 5),
    Criterion::flag('beginners', true),
]);

$search = Criteria::of([Criterion::choice('day', ['sun']), Criterion::range('players', 4, 8)]);

$listing->meets($search);   // true: Sunday is shared, and 4 or 5 players fit both

Criteria::of() keeps at most 32 criteria, one per name. A listing's criteria meet a search's when every criterion the search wants meets the listing's criterion of the same name: a listing that does not state a criterion does not meet a search that wants it, and a search that wants nothing meets every listing.

meets() is the rule, not the search: an application with many listings filters them in its store or its search engine first, then applies meets() to what it reads, or indexes the same rule. Its cost is bounded by the 32 criteria and 32 values of each side.