PHPackages                             sfneal/datum - 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. [Database &amp; ORM](/categories/database)
4. /
5. sfneal/datum

ActiveLibrary[Database &amp; ORM](/categories/database)

sfneal/datum
============

Construct reusable &amp; cacheable Eloquent queries with custom filters

2.0.2(2y ago)166.3k↑800%[3 PRs](https://github.com/sfneal/datum/pulls)5MITPHPPHP ^8.0CI passing

Since Feb 3Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/sfneal/datum)[ Packagist](https://packagist.org/packages/sfneal/datum)[ Docs](https://github.com/sfneal/datum)[ RSS](/packages/sfneal-datum/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (11)Versions (36)Used By (5)

Datum
=====

[](#datum)

[![Packagist PHP support](https://camo.githubusercontent.com/20948dabb19e577ad379efa6c30a8aad7283ff3ed707efab0d59ef443be2ddf7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f73666e65616c2f646174756d)](https://packagist.org/packages/sfneal/datum)[![Latest Version on Packagist](https://camo.githubusercontent.com/554fd964df4726546247d881b2385210ad464f3fc74b116bd51ca6730d3cf12f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73666e65616c2f646174756d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sfneal/datum)[![Build Status](https://camo.githubusercontent.com/d61ac15203db4cbc418f6036dc3ac897556569bd6bc1c2b4660378414cefd23d/68747470733a2f2f7472617669732d63692e636f6d2f73666e65616c2f646174756d2e7376673f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://travis-ci.com/sfneal/datum)[![StyleCI](https://camo.githubusercontent.com/b59d0658acd4dea5c177e3a492c664178d398e910ebdaf141c76078e8a633142/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3333353638343037322f736869656c643f6272616e63683d6d6173746572)](https://github.styleci.io/repos/335684072?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/b08e39468e96ec5707dc31907c498b8614d10d2ba56e8fc788a198f68d3cf2f6/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73666e65616c2f646174756d2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/sfneal/datum/?branch=master)[![Total Downloads](https://camo.githubusercontent.com/e19a64521f156ae5ff64421cfd393cf78d4b853bd4426e13d291f116fbbd0fe9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73666e65616c2f646174756d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sfneal/datum)

Construct reusable &amp; cacheable Eloquent queries with custom filters.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require sfneal/datum
```

Usage
-----

[](#usage)

### Basic Query

[](#basic-query)

The Query abstract class requires a `builder()` &amp; `execute()` method must be implemented. The `builder()` method retrieves a Builder instance for constructing the query (useful for adding or removing scopes). The `execute()` method is where the remainder of the query params can be added. Expected return type is a Builder but this can be overwritten to be a Collection, array, string, etc. In this case we're using the HasKeyParam to accept a `$modelKey` param in the Query's \_\_construct method.

```
use Illuminate\Database\Eloquent\Builder;
use Sfneal\Queries\Query;
use Sfneal\Queries\Traits\HasKeyParam;

class PeopleQuery extends Query
{
    use HasKeyParam;

    /**
     * Retrieve a Query builder.
     *
     * @return Builder
     */
    protected function builder(): Builder
    {
        return People::query();
    }

    /**
     * Execute a DB query.
     *
     * @return Builder
     */
    public function execute(): Builder
    {
        return $this->builder()
            ->where('person_id', '=', $this->modelKey);
    }
}

// Example use
$model = (new PeopleQuery($id))->execute()->get()
```

### Advanced Query (with filters)

[](#advanced-query-with-filters)

The FilterableQuery abstract class extends the previously mentioned Query abstract class while providing additional functionality by using Filters. The `execute` method that is required by the abstract Query is pre-defined but a `builder` method must still be implemented. Additionally, FilterableQuery requires a `queryFilters()` method be implemented that returns an array of Filter classes that can be used to add predefined filters to a query.

Before creating a FilterableQuery extension, the Filters that Query will use should be created.

```
use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\Filter;

class NameLastFilter implements Filter
{
    /**
     * Apply a given search value to the builder instance.
     *
     * @param Builder $query
     * @param mixed $value
     * @return Builder $query
     */
    public function apply(Builder $query, $value): Builder
    {
        $query->whereIn('name_last', (array) $value);

        return $query;
    }
}

class CityFilter implements Filter
{
    /**
     * Apply a given search value to the builder instance.
     *
     * @param Builder $query
     * @param mixed $value
     * @return Builder $query
     */
    public function apply(Builder $query, $value): Builder
    {
        $query->whereIn('city', (array) $value);

        return $query;
    }
}
```

Now that we've created our Filters, a FilterableQuery extension can be created that uses them.

```
use CityFilter;
use NameLastFilter;
use Sfneal\Queries\FilterableQuery;

class PeopleFilterableQuery extends FilterableQuery
{
    /**
     * Retrieve a Query builder.
     *
     * @return Builder
     */
    protected function builder(): Builder
    {
        return People::query();
    }

    /**
     * Retrieve an array of model attribute keys & corresponding Filter class values.
     *
     * @return array
     */
    protected function queryFilters(): array
    {
        return [
            'city' => CityFilter::class,
            'name_last' => NameLastFilter::class,
        ];
    }
}
```

With the FilterableQuery finally created, we can pass filter params to it and receive results.

```
$filters = [
    'name_last' => 'Brady'
    'city' => 'Brookline',
];

$results = (new PeopleQueryWithFilters($filters))->execute()->get();
```

Since we built the Filter implementations to mutate filter $values to arrays, we can pass an array of valid filters to retrieve more results.

```
$filters = [
    'name_last' => [
        'Neal',
        'Brady',
    ],
    'city' => [
        'Brookline',
        'Boston',
    ],
];

$results = (new PeopleQueryWithFilters($filters))->execute()->get();
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Stephen Neal](https://github.com/sfneal)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

PHP Package Boilerplate
-----------------------

[](#php-package-boilerplate)

This package was generated using the [PHP Package Boilerplate](https://laravelpackageboilerplate.com).

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance53

Moderate activity, may be stable

Popularity27

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 98.4% 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

Every ~38 days

Recently: every ~244 days

Total

32

Last Release

733d ago

Major Versions

0.12.0 → 1.0.02021-02-15

1.6.0 → 2.0.02024-04-01

PHP version history (3 changes)0.1.0PHP &gt;=7.3

1.6.0PHP ^7.3|^8.0

2.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/ec5fdf3b9d2183ae9c777e4aed46fd5cfd9aa4789cd05c669e5907de0b8c865c?d=identicon)[sfneal](/maintainers/sfneal)

---

Top Contributors

[![sfneal](https://avatars.githubusercontent.com/u/23200215?v=4)](https://github.com/sfneal "sfneal (254 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")

---

Tags

filtersqueriesDatumsfneal

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sfneal-datum/health.svg)

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

###  Alternatives

[essa/api-tool-kit

set of tools to build an api with laravel

52680.5k](/packages/essa-api-tool-kit)[cerbero/query-filters

Filter Laravel Eloquent models based on query parameters.

85282.6k](/packages/cerbero-query-filters)[jerome/filterable

Streamline dynamic Eloquent query filtering with seamless API request integration and advanced caching strategies.

19226.1k](/packages/jerome-filterable)[czim/laravel-filter

Filter for Laravel Eloquent queries, with support for modular filter building

8973.0k3](/packages/czim-laravel-filter)[aldemeery/sieve

A simple, clean and elegant way to filter Eloquent models.

1396.3k](/packages/aldemeery-sieve)[squareboat/sql-doctor

Quickly debugging the amount of database queries per request in Laravel.

571.4k](/packages/squareboat-sql-doctor)

PHPackages © 2026

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