PHPackages                             kanel/specification2 - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. kanel/specification2

ActiveLibrary

kanel/specification2
====================

An implementation of the Specification design pattern

1.0.0(8y ago)016MITPHPPHP &gt;=7.0.0

Since Jul 13Pushed 8y agoCompare

[ Source](https://github.com/elkaadka/Specification2)[ Packagist](https://packagist.org/packages/kanel/specification2)[ RSS](/packages/kanel-specification2/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

[![build](https://camo.githubusercontent.com/1a7d565465695d1427d867a594ec9e23e6171a95574524a3ff0d21cb4612ed27/68747470733a2f2f7472617669732d63692e6f72672f656c6b6161646b612f53706563696669636174696f6e322e7376673f6272616e63683d6d6173746572)](https://camo.githubusercontent.com/1a7d565465695d1427d867a594ec9e23e6171a95574524a3ff0d21cb4612ed27/68747470733a2f2f7472617669732d63692e6f72672f656c6b6161646b612f53706563696669636174696f6e322e7376673f6272616e63683d6d6173746572)

Specification design pattern
============================

[](#specification-design-pattern)

This is my implementation of the "Specification" design pattern. It differs from the original one since i find it simpler and more straight forward.

It also allows the composition of multiple Specifications that takes in different types of parameters

The Goal of this pattern is to have separate classes of logic in order to do condition composition without rewriting and maintaining the conditions at different places.

Here is a detailed "how to" for thi package :

Creating a Specification
------------------------

[](#creating-a-specification)

Create a class that implements the SpecificationInterface and that holds your logic :

Here is basic example of a list of specifications that checks differents things about products and customers

A class the checks if a product is available :

```
    class IsProductAvaialble implement SpecificationInterface
    {
        protected $product;
        protected $neededQuantity;

        public function __construc(Product $product, $neededQuantity = 1)
        {
            $this->product = $product;
            $this->neededQuantity = $neededQuantity;
        }

        public function isValid(): bool
        {
            //here your code logic that uses the data set in the construct and returns a boolean
        }
    }
```

A class the checks if a product can be shipped to the customer :

```
    class IsProductShipableForCustomer implement SpecificationInterface
    {
        protected $product;
        protected $customer;

        public function __construc(Product $product, Customer $customer)
        {
            $this->product = $product;
            $this->customer = $customer;
        }

        public function isValid(): bool
        {
            //doing the logic to check if the product is avaialble in the customer's country
        }
    }
```

A class the checks if a product is special (a special product is supposed to be (magically?) always in stock)

```
    class IsASpecialProduct implement SpecificationInterface
    {
        protected $product;

        public function __construc(Product $product)
        {
            $this->product = $product;
        }

        public function isValid(): bool
        {
            //doing the logic to check if the product is special
        }
    }
```

A class that checks if a customer is not blacklisted

```
    class IsCustomerBlackListed implement SpecificationInterface
    {
        protected $customer;

        public function __construc(Customer $customer)
        {
            $this->customer = $customer;
        }

        public function isValid(): bool
        {
            //doing the logic to checks if the customer is banned
        }
    }
```

All the available operators :
-----------------------------

[](#all-the-available-operators-)

### 2.1 - isSatisfiedBy

[](#21---issatisfiedby)

One of the tree entry points of the specification pattern.
It Has to be used before any operator.
**If used after an operator it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())->isSatisfiedBy(new IsProductAvaialble($product));

     if ($specification->isValid()) {
        ...
     }
```

### 2.2 - isSatisfiedByAll

[](#22---issatisfiedbyall)

the second possible entry point of the specification pattern.
Checks if all the Specifications sent are Valid ones (equivalent to chaining and operators)
It Has to be used before any operator.
**If used after an operator it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())->isSatisfiedByAll(
        new IsProductAvaialble($product),
        new IsProductShipableForCustome($product, $customer)
    );

    if ($specification->isValid()) {
        ...
    }
```

### 2.3 - isSatisfiedByAny

[](#23---issatisfiedbyany)

the third and last possible starting point of the specification pattern.
Checks if one of the Specifications sent is a Valid one (equivalent to chaining or operators)
It Has to be used before any operator.
**If used after an operator it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())->isSatisfiedByAny(
        new IsProductAvaialble($product),
        new IsASpecialProduct($product)
    );

    if ($specification->isValid()) {
        ...
    }
```

### 2.4 - and Operator

[](#24---and-operator)

adds an '&amp;&amp;' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductAvaialble($product))
        ->and(new IsProductShipableForCustomer($product, $customer))
        ...
    ;

    if ($specification->isValid()) {
       ...
    }
```

### 2.5 - andNot Operator

[](#25---andnot-operator)

adds an '&amp;&amp; !' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductAvaialble($product))
        ->and(new IsProductShipableForCustomer($product, $customer))
        ->andNot(new IsCustomerBlackListed($customer)
        ...
    ;

    if ($specification->isValid()) {
       ...
    }
```

### 2.6 - or Operator

[](#26---or-operator)

adds an '||' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->or(new IsASpecialProduc($product))
       ...
    ;

    if ($specification->isValid()) {
       ...
    }
```

### 2.7 - orNot Operator

[](#27---ornot-operator)

adds an '|| !' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->orNot(new IsASpecialProduc($product))
    ;

    if ($specification->isValid()) {
       ...
    }
```

### 2.7 - xor Operator

[](#27---xor-operator)

adds a 'xor' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->xor(new IsASpecialProduc($product))
    ;

    if ($specification->isValid()) {
       ...
    }
```

### 2.7 - xorNot Operator

[](#27---xornot-operator)

adds a 'xor !' condition to the previously set specifications
**It can not be used first or else it will throw a WrongUsageException**

Example :

```
    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->xorNot(new IsASpecialProduc($product))
    ;

    if ($specification->isValid()) {
       ...
    }
```

3- Composition
--------------

[](#3--composition)

The specifications can be composed :

Example:

```
    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductShipableForCustomer($product, $customer))
        ->and(
            (new Specification())
                ->isSatisfiedBy(new IsProductAvaialble($product))
                ->or(new IsASpecialProduct($product))
        )
    ;

    if ($specification->isValid()) {
       ...
    }
```

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

3228d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3215e882ee8ae39a8b904d0958420f68bf23b2cf0e22175d5a61513f98e6ef64?d=identicon)[elkaadka](/maintainers/elkaadka)

---

Top Contributors

[![elkaadka](https://avatars.githubusercontent.com/u/24205608?v=4)](https://github.com/elkaadka "elkaadka (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kanel-specification2/health.svg)

```
[![Health](https://phpackages.com/badges/kanel-specification2/health.svg)](https://phpackages.com/packages/kanel-specification2)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
