brenoroosevelt/php-specifications

Implementation of Specification Pattern for PHP

dev-main 2021-10-15 13:50 UTC

This package is auto-updated.

Last update: 2024-11-15 20:30:59 UTC


README

Implementation of Specification Pattern in PHP for general purpose.

Requirements

  • PHP >= 7.1

Install

composer require brenoroosevelt/php-specifications

Definition

Specifications are classes that implements the interface Specification:

<?php
declare(strict_types=1);

namespace BrenoRoosevelt\Specification;

interface Specification
{
    public function isSatisfiedBy($candidate): bool;
}

Constraints

The functions below evaluate a candidate using the following specifications:

Operators

Chaining Specifications

Specifications can be chained using the following function:

Chained specifications will be evaluated with the corresponding operator.

Transverse Specifications for iterables

Often used with collections, these especial specifications iterate candidates and evaluate their elements.

Selectors

These special specifications extract candidate values and then evaluate the specification.

Creating Specifications

<?php
class RecentUser implements Specification
{
    private $daysAgo;
    
    public function __construct(int $daysAgo = 15) {
        $this->daysAgo = $daysAgo;
    }
    
    public function isSatisfiedBy($candidate): bool
    {
        $daysAgo = 
            (new DateTimeImmutable())->modify(sprintf("-%s days", $this->daysAgo));
        
        return 
            $candidate instanceof User && 
            $candidate->createdAt() >= $daysAgo;
    }
}
<?php
$user = new User(/** ... */);

(new RecentUser(30))->isSatisfiedBy($user); // (bool)
rule(RecentUser::class, 30)->isSatisfiedBy($user); // (bool)
anyOf()->rule(RecentUser::class)->method('getCategory', in(['premium']))->isSatisfiedBy($user); // (bool)

Inline Specifications

<?php

rule(fn($candidate) => $candidate->isActive());