Minimal implementation of criteria pattern for Laravel.
Criteria is an implementation of \Baethon\LaravelCriteria\CriteriaInterface
which is responsible for only one thing - modify Laravels query in a specified way.
This allows to decouple and re-use query modifiers.
Criteria are very similar to Eloquent scopes. The main difference is that they can be applied to different models across the application.
composer require baethon/laravel-criteria
- PHP >= 7.1
This library has no dependencies to Laravel itself. It should work with all versions of Laravel.
First, you need to create an implementation of CriteriaInterface
:
<?php
use Baethon\LaravelCriteria\CriteriaInterface;
class CompareCriteria implements CriteriaInterface
{
private $field;
private $value;
public function __construct(string $field, string $value)
{
$this->field = $field;
$this->value = $value;
}
public function apply($query)
{
$query->where($this->field, $this->value);
}
}
Now, you can apply it to the query:
$query = User::query();
(new CompareCriteria('name', 'Jon'))->apply($query);
$jon = $query->first();
To simplify things it's possible to use AppliesCriteria
trait in a model.
use Baethon\LaravelCriteria\Traits\AppliesCriteria;
class User extends Model
{
// model body stripped for better readability
use AppliesCriteria;
}
$jon = User::query()
->apply(new CompareCriteria('name', 'Jon'))
->first();
The package provides collections which allow applying multiple criteria at once.
To apply group of criteria use \Baethon\LaravelCriteria\Collections\CriteriaCollection
:
$jonSnow = User::query()
->apply(CriteriaCollection::create([
new CompareCriteria('name', 'Jon'),
new CompareCriteria('lastname', 'Snow'),
]))
->first();
// same result, without CriteriaCollection
$jonSnow = User::query()
->apply(new CompareCriteria('name', 'Jon'))
->apply(new CompareCriteria('lastname', 'Snow'))
->first();
If you need to be sure that all criteria will be fulfilled you can use CriteriaCollection::allOf()
:
User::query()
->apply(CriteriaCollection::allOf([
new CompareCriteria('name', 'Jon'),
new CompareCriteria('lastname', 'Snow'),
]));
// same as
User::query()
->where(function ($query) {
$query->apply(new CompareCriteria('name', 'Jon'))
->apply(new CompareCriteria('lastname', 'Snow'));
});
Also, you can group criteria using logical OR
join:
User::query()
->apply(CriteriaCollection::oneOf([
new CompareCriteria('name', 'Jon'),
new CompareCriteria('lastname', 'Snow'),
]));
// same as
User::query()
->where(function ($query) {
$query->where('name', 'Jon')
->orWhere('lastname', 'Snow');
});
Run tests with:
./vendor/bin/phpunit
Please see CHANGELOG for more information what has changed recently.
The MIT License (MIT). Please see License File for more information.