| Package Data | |
|---|---|
| Maintainer Username: | chalcedonyt | 
| Maintainer Contact: | chalcedonyt@gmail.com (Tim Teoh) | 
| Package Create Date: | 2015-09-01 | 
| Package Last Update: | 2018-08-07 | 
| Home Page: | |
| Language: | PHP | 
| License: | MIT | 
| Last Refreshed: | 2025-10-28 03:04:32 | 
| Package Statistics | |
|---|---|
| Total Downloads: | 8,640 | 
| Monthly Downloads: | 0 | 
| Daily Downloads: | 0 | 
| Total Stars: | 12 | 
| Total Watchers: | 2 | 
| Total Forks: | 6 | 
| Total Open Issues: | 1 | 
An adaptation of the Specification Pattern as done by https://github.com/domnikl/DesignPatternsPHP, adding an artisan command to quickly create specifications.
Via Composer (please change your minimum-stability to "dev")
$ composer require chalcedonyt/laravel-specification
Then run composer update. Once composer is finished, add the service provider to the providers array in app/config/app.php:
Chalcedonyt\Specification\Providers\SpecificationServiceProvider::class
An artisan command will be added to quickly create specifications.
php artisan make:specification [NameOfSpecification]
Adding a --parameters flag will prompts for parameters to be inserted into the constructor when generated:
Enter the class or variable name for parameter 0 (Examples: \App\User or $value) [Blank to stop entering parameters] [(no_param)]:
 > \App\User
 Enter the class or variable name for parameter 1 (Examples: \App\User or $value) [Blank to stop entering parameters] [(no_param)]:
 > $my_value
Results in
class NewSpecification extends AbstractSpecification
{
    /**
    * @var  \App\User
    */
    protected $user;
    /**
    * @var  
    */
    protected $myValue;
    /**
    *
    *  @param  \App\User $user
    *  @param   $myValue
    *
    */
    public function __construct(\App\User $user, $my_value)
    {
        $this->user = $user;
        $this->myValue = $my_value;
    }
    /**
    * Tests an object and returns a boolean value
    *
    * @var  mixed
    */
    public function isSatisfiedBy($candidate)
    {
        //return a boolean value
    }
}
class AgeOfPersonSpecification extends \Chalcedonyt\Specification\AbstractSpecification
{
    protected $minAge;
    protected $maxAge;
    /**
    * Set properties here for a parameterized specification.
    *
    */
    public function __construct($min_age, $max_age)
    {
        $this->minAge = $min_age;
        $this->maxAge = $max_age;
    }
    /**
    * Tests an object and returns a boolean value
    *
    * @var Array $candidate
    */
    public function isSatisfiedBy($candidate)
    {
        return $this->minAge <= $candidate['age'] && $this->maxAge >= $candidate['age'];
    }
}
class MalePersonSpecification  extends \Chalcedonyt\Specification\AbstractSpecification
{
    const GENDER_MALE = 1;
    const GENDER_FEMALE = 2;
    /**
    * Tests an object and returns a boolean value
    *
    * @var Array candidate
    */
    public function isSatisfiedBy($candidate)
    {
        return $candidate['gender'] == self::GENDER_MALE;
    }
}
$adult_spec = new AgeOfPersonSpecification(21, 80);
$teenager_spec = new AgeOfPersonSpecification(13, 19);
$puberty_spec = new AgeOfPersonSpecification(15, 19);
$male_spec = new MalePersonSpecification;
$female_spec = new NotSpec($male_spec);
$young_teenage_female = ['age' => 13, 'gender' => MalePersonSpecification::GENDER_FEMALE ];
$teenage_female = ['age' => 15, 'gender' => MalePersonSpecification::GENDER_FEMALE ];
$adult_female = ['age' => 22, 'gender' => MalePersonSpecification::GENDER_FEMALE ];
$nested_female_spec =  $puberty_spec->andSpec( $teenager_spec->andSpec( $female_spec ) );
$this->assertEquals( $nested_female_spec->isSatisfiedBy( $teenage_female ), true );
$this->assertEquals( $nested_female_spec->isSatisfiedBy( $young_teenage_female ), false );
$any_young_female_spec = $female_spec->andSpec( $teenager_spec->orSpec( $puberty_spec ));
$this->assertEquals( $nested_female_spec->isSatisfiedBy( $teenage_female ), true );
$this->assertEquals( $nested_female_spec->isSatisfiedBy( $adult_female ), false );
You may also retrieve unfulfilled specifications via the remainderUnsatisfiedBy property
$any_age_spec = new AgeOfPersonSpecification(1, 80);
$male_spec = new MalePersonSpecification;
$female_spec = new NotSpec($male_spec);
$male = ['age' => 16, 'gender' => MalePersonSpecification::GENDER_MALE ];
$any_young_female_spec = new AndSpec( $female_spec, $any_age_spec );
$this->assertEquals( $any_young_female_spec->isSatisfiedBy( $male ), false );
//returns the $female_spec
$unfulfilled_spec =  $any_young_female_spec->remainderUnsatisfiedBy( $male );
$inverse_female_spec = new NotSpec( $unfulfilled_spec );
$this->assertEquals( $inverse_female_spec->isSatisfiedBy( $male ), true );
php artisan make:specification MyDir\\MySpec
isSatisfiedBy method from the abstract and interface. This allows type hinting on the $candidate.--parameters flagremainderUnsatisfiedBy functionsThe MIT License (MIT). Please see License File for more information.