star/specification

Specification system to allow applying specification to a data source.

0.2.0 2024-01-11 19:01 UTC

This package is auto-updated.

Last update: 2024-11-11 20:41:44 UTC


README

Build Status

Specification system for php. Provides adapter for some libraries.

Installation

Using Composer: composer require star/php-specification

Usage

With basic php array

fetchAll()

Fetch all items matching the specification

$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
$items = $result->fetchAll(EqualsTo::fromBoolean('alias', 'active', true));
echo $items->count(); // 2
echo $items->getValue(0, 'name')->toInteger(); // Jane
echo $items->getValue(1, 'name')->toInteger(); // Jack

fetchOne()

Fetch single item matching the specification

Note: If the specification would result with more than one row, a NotUniqueResult exception will be thrown.

$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
$row = $result->fetchOne(EqualsTo::booleanValue('alias', 'active', false));
echo $row->count(); // 1
echo $row->getValue('name')->toInteger(); // Joe

exists()

Fetch whether an item matches the specification

$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
echo $result->exists(EqualsTo::stringValue('alias', 'name', 'Joe')); // true
echo $result->exists(EqualsTo::stringValue('alias', 'name', 'Not found')); // false

Supported specifications

EqualsTo

Whether the property's value is matching exactly the provided value (===).

Example:

EqualsTo::stringValue('alias', 'name', 'Joe');

Note: Both values will be converted to a string in order to assert the equality.

Between

Whether the property's numeric or date value is included between the left and right values.

Example:

Between::integers('alias', 'age', 18, 40);
Between::dates('alias', 'published_at', new \DateTime('1900-01-01'), new \DateTime('2000-01-01 12:34:56'));

Note: The format Y-m-d H:i:s is the only supported format used for comparison.

Contains

Whether the provided value is found at any position of the item's property (start, end, middle).

Example:

Contains::string('alias', 'name', 'Joe');

EndsWith

Whether the provided value is found at the end of the item's property.

Example:

EndsWith::string('alias', 'name', 'Joe');

Greater

Whether the property's numeric or date value is greater than the provided value.

Example:

Greater::thanInteger('alias', 'age', 18);
Greater::thanDate('alias', 'born_at', new \DateTime('2000-01-01'));

GreaterEquals

Whether the property's numeric or date value is greater or equal than the provided value.

Example:

GreaterEquals::thanInteger('alias', 'age', 18);
GreaterEquals::thanDate('alias', 'born_at', new \DateTime('2000-01-01'));

InArray

Whether the property's value is contained in the range of provided values.

Example:

InArray::ofIntegers('alias', 'age', 18, 20, 34); // would return items with age 18, 20 or 34.

IsEmpty

Whether the property's value is an empty value.

Example:

new IsEmpty('alias', 'name');

Note: Zero, boolean false are considered empty.

IsNot

Inverse the provided specification.

Example:

new IsNot(Lower::thanInteger('alias', 'age', 18)); // would return items with age >= 19.

IsNull

Whether the property's value is a null value.

Example:

new IsNull('alias', 'age');

Note: Zero, boolean false and empty string are not considered null.

Lower

Whether the property's numeric or date value is less than the provided value.

Example:

Lower::thanInteger('alias', 'age', 18);
Lower::thanDate('alias', 'age', new \DateTime('2000-01-01'));

LowerEquals

Whether the property's numeric or date value is less or equal than the provided value.

Example:

LowerEquals::thanInteger('alias', 'age', 18);
LowerEquals::thanDate('alias', 'age', new \DateTime('2000-01-01'));

StartsWith

Whether the provided value is found at the beginning of the item's property.

Example:

StartsWith::string('alias', 'name', 'Joe');

Composites (And / Or)

Using AndX and OrX you are able to configure a more complex specification to your need.

Example:

// equivalent to "name = 'Joe' AND active = true"
new AndX(
    EqualsTo::stringValue('alias', 'name', 'Joe'),
    EqualsTo::booleanValue('alias', 'active', true),
);

// equivalent to "name = 'Joe' OR active = true"
new OrX(
    EqualsTo::stringValue('alias', 'name', 'Joe'),
    EqualsTo::booleanValue('alias', 'active', true),
);

Ordering by properties

We can also order our specifications with 1 or more properties.

Example:

new AndX(
    OrderBy::desc('alias', 'is_active'),
    OrderBy::asc('alias', 'age'),
    OrderBy::desc('alias', 'name'),
);
new OrX(
    OrderBy::desc('alias', 'is_active'),
    OrderBy::asc('alias', 'age'),
    OrderBy::desc('alias', 'name'),
);

Supported frameworks