PHPackages                             bytetcore/serpo - 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. bytetcore/serpo

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

bytetcore/serpo
===============

Laravel Repository Pattern - Elegant data layer abstraction with criteria-based filtering for Eloquent models.

1.0.1(2d ago)11↓100%Apache-2.0PHPPHP ^8.1CI passing

Since Apr 6Pushed 2d agoCompare

[ Source](https://github.com/ByteTCore/serpo)[ Packagist](https://packagist.org/packages/bytetcore/serpo)[ Docs](https://github.com/ByteTCore/serpo)[ RSS](/packages/bytetcore-serpo/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (6)Versions (3)Used By (0)

Serpo — Laravel Repository Pattern
==================================

[](#serpo--laravel-repository-pattern)

[![Latest Version on Packagist](https://camo.githubusercontent.com/5a6368cc01442be2629d5f277cb1acb601a28b518d1f3582bc5ecaf6139f1eeb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6279746574636f72652f736572706f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/bytetcore/serpo)[![License](https://camo.githubusercontent.com/05b0a7630922134581d5435d89fec32fe0c034ebcc7d15a7cc8566c79882e462/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6279746574636f72652f736572706f2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/c03596900f378f0d56c50bf70a746300306f5fe92e4ec7272aeaf2ca2589c79d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6279746574636f72652f736572706f2e7376673f7374796c653d666c61742d737175617265)](composer.json)[![Latest Stable Version](https://camo.githubusercontent.com/87847df57ccbafe214b9630e75fd61f69ef283c66697538467f72cbe34920990/687474703a2f2f706f7365722e707567782e6f72672f4279746554436f72652f736572706f2f76)](https://packagist.org/packages/ByteTCore/serpo)[![Total Downloads](https://camo.githubusercontent.com/bc97ac67a8b4c56693191849f15a1f0819b582823439ca0e135ddb2ff32a1abe/687474703a2f2f706f7365722e707567782e6f72672f4279746554436f72652f736572706f2f646f776e6c6f616473)](https://packagist.org/packages/ByteTCore/serpo)[![Latest Unstable Version](https://camo.githubusercontent.com/67574b99150ce3c5b3169cdc6592a10708dbbfff24e0c67d7eed7a9ef0a508a5/687474703a2f2f706f7365722e707567782e6f72672f4279746554436f72652f736572706f2f762f756e737461626c65)](https://packagist.org/packages/ByteTCore/serpo)

Elegant data layer abstraction for Laravel using the **Repository Pattern** with powerful **criteria-based filtering**. Keep your controllers clean and your data logic reusable.

Features
--------

[](#features)

- 🏗️ **Repository Pattern** — Abstract Eloquent models behind clean interfaces
- 🔍 **Criteria System** — Composable, reusable query filters (where, like, date, JSON, null, in)
- ⚡ **Zero Boilerplate** — Artisan generators for repositories, services, and criteria
- 🔗 **Fluent Chaining** — Chain any Eloquent Builder method directly on repositories
- 🔄 **Auto Query Reset** — Query state resets after execution, preventing stale queries
- 📦 **Laravel Auto-Discovery** — Install and go, no manual provider registration

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 9.0+

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

[](#installation)

```
composer require bytetcore/serpo
```

Publish the configuration:

```
php artisan vendor:publish --tag=serpo-config
```

Quick Start
-----------

[](#quick-start)

### 1. Generate a Repository

[](#1-generate-a-repository)

```
# Basic repository
php artisan make:repository UserRepository

# With a specific model
php artisan make:repository UserRepository --model=User

# With a corresponding service class
php artisan make:repository UserRepository --model=User --service
```

### 2. Generate a Service

[](#2-generate-a-service)

```
php artisan make:service UserService
```

### 3. Generate a Custom Criteria

[](#3-generate-a-custom-criteria)

```
php artisan make:criteria ActiveUserCriteria
```

Usage
-----

[](#usage)

### Basic Repository

[](#basic-repository)

```
namespace App\Repositories;

use App\Models\User;
use ByteTCore\Serpo\Repositories\BaseRepository;

class UserRepository extends BaseRepository
{
    public function __construct(User $model)
    {
        parent::__construct($model);
    }
}
```

### Query Methods

[](#query-methods)

```
$repo = app(UserRepository::class);

// Get all records
$users = $repo->all();

// Get with specific columns
$users = $repo->get(['id', 'name', 'email']);

// Get first record
$user = $repo->first();

// Get first or throw exception
$user = $repo->firstOrFail();

// Get latest record
$user = $repo->last();
$user = $repo->last('updated_at');
```

### Eloquent Builder Chaining

[](#eloquent-builder-chaining)

All Eloquent Builder methods are available directly on the repository:

```
$users = $repo->where('active', true)
    ->orderBy('name')
    ->limit(10)
    ->get();

$count = $repo->where('role', 'admin')->count();

$users = $repo->with('posts')->whereHas('posts')->get();
```

### Criteria-Based Filtering

[](#criteria-based-filtering)

Define reusable filter conditions in your repository:

```
use ByteTCore\Serpo\Criteria\WhereCriteria;
use ByteTCore\Serpo\Criteria\LikeCriteria;
use ByteTCore\Serpo\Criteria\DateCriteria;
use ByteTCore\Serpo\Constants\Filter;

class UserRepository extends BaseRepository
{
    protected array $conditions = [
        // Simple equality (default operator is '=')
        'status' => WhereCriteria::class,

        // Search across multiple columns
        'keyword' => [
            'class' => LikeCriteria::class,
            'columns' => 'name|email',
            'boolean' => Filter::OR,
            'pattern' => Filter::CONTAINS,
        ],

        // Comparison operators via params
        'min_age' => [
            'class' => WhereCriteria::class,
            'columns' => 'age',
            'operator' => Filter::GTE,
        ],

        // Date filtering
        'created_after' => [
            'class' => DateCriteria::class,
            'columns' => 'created_at',
            'operator' => Filter::GTE,
        ],
    ];

    public function __construct(User $model)
    {
        parent::__construct($model);
    }
}
```

Apply filters from request data:

```
// In your controller
$users = $repo->filters($request->only(['status', 'keyword', 'min_age']))->get();
```

### Available Criteria

[](#available-criteria)

CriteriaDescriptionParams`WhereCriteria``WHERE col op val``operator`: `=`, ``, `>`, `>=`, `=`, `=`, `=`, ` WhereCriteria::class, // Checks if 'status' matches input
'price_over' => [
    'class' => WhereCriteria::class,
    'columns' => 'price',
    'operator' => Filter::GTE // ->where('price', '>=', input)
]
```

#### Search &amp; Text (LikeCriteria)

[](#search--text-likecriteria)

Automatically supports SQL padding (%) so you don't have to inject % in strings.

```
'keyword' => [
    'class' => LikeCriteria::class,
    'columns' => 'title|content|author',
    'boolean' => Filter::OR, // ->where('title', 'like', '%val%') OR ->where('content', ...)
    'pattern' => Filter::CONTAINS, // Optional. Other options: STARTS_WITH, ENDS_WITH
]
```

#### Ranges (BetweenCriteria)

[](#ranges-betweencriteria)

Expects an array of precisely two values: `[$start, $end]`.

```
'price_range' => [
    'class' => BetweenCriteria::class,
    'columns' => 'price' // expects $request->price_range = [100, 500]
]
```

#### Working with Dates

[](#working-with-dates)

Filter via specific date, year, or month. Extremely useful for reporting dashboards.

```
'created_at' => DateCriteria::class, // Date match YYYY-MM-DD
'birth_year' => YearCriteria::class,
'birth_month' => MonthCriteria::class,
```

#### Sets &amp; Arrays

[](#sets--arrays)

Checks whether a column is among an array of inputs.

```
'tags' => InCriteria::class,    // Expects $request->tags = ['php', 'laravel']
'ignore' => NotInCriteria::class, // Exclude IDs
```

#### Nullity Checks

[](#nullity-checks)

Pass a truthy value (`true`, `1`) to trigger these.

```
'unverified' => NullCriteria::class,    // ->whereNull('email_verified_at')
'active_only' => NotNullCriteria::class // ->whereNotNull('email_verified_at')
```

#### JSON Columns

[](#json-columns)

Filter based on JSON arrays directly in the database.

```
'has_tag' => JsonContainsCriteria::class, // ->whereJsonContains('tags', input)
```

#### Dynamic Sorting (OrderByCriteria)

[](#dynamic-sorting-orderbycriteria)

Pass `Filter::ASC` or `Filter::DESC` to dynamically sort records dynamically instead of hardcoding `->orderBy()`.

```
'sort_date' => [
    'class' => OrderByCriteria::class,
    'columns' => 'created_at' // expects $request->sort_date = Filter::DESC
]
```

### Custom Criteria

[](#custom-criteria)

```
namespace App\Criteria;

use ByteTCore\Serpo\Criteria\BaseCriteria;
use Illuminate\Database\Eloquent\Builder;

class ActiveWithRecentPostsCriteria extends BaseCriteria
{
    public function apply(Builder $query): void
    {
        $query->where('active', true)
            ->whereHas('posts', fn (Builder $q) => $q->where('created_at', '>=', now()->subDays(30)));
    }
}
```

### Auto-Reset Behavior

[](#auto-reset-behavior)

By default, the query builder resets after each execution to prevent stale state:

```
$active = $repo->where('active', true)->get();   // query resets after get()
$all = $repo->all();                              // fresh query — returns all records
```

Disable auto-reset when you need to reuse the query:

```
$repo->withoutAutoReset()
    ->where('active', true);

$count = $repo->count();       // same filtered query
$users = $repo->get();         // same filtered query
```

Configuration
-------------

[](#configuration)

```
// config/serpo.php
return [
    'repository' => [
        'namespace' => env('SERPO_REPOSITORY_NAMESPACE', 'Repositories'),
    ],
    'service' => [
        'namespace' => env('SERPO_SERVICE_NAMESPACE', 'Services'),
    ],
    'criteria' => [
        'namespace' => env('SERPO_CRITERIA_NAMESPACE', 'Criteria'),
    ],
];
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for release history.

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

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

License
-------

[](#license)

Licensed under the [Apache License 2.0](LICENSE).

###  Health Score

40

—

FairBetter than 87% of packages

Maintenance99

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 60% 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 ~0 days

Total

2

Last Release

2d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3be00157eb3b2afdf3024f93dcbe423e0fc71180431eccf5e48fe73f4d71d40d?d=identicon)[dovutuan](/maintainers/dovutuan)

---

Top Contributors

[![dovutuan](https://avatars.githubusercontent.com/u/51498778?v=4)](https://github.com/dovutuan "dovutuan (3 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")

---

Tags

laraveleloquentfilterrepository patternquery builderrepositorycriteriadata layer

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/bytetcore-serpo/health.svg)

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

###  Alternatives

[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[mehdi-fathi/eloquent-filter

Eloquent Filter adds custom filters automatically to your Eloquent Models in Laravel.It's easy to use and fully dynamic, just with sending the Query Strings to it.

450191.6k1](/packages/mehdi-fathi-eloquent-filter)[torann/laravel-repository

Base repository implementation for Laravel

88497.8k2](/packages/torann-laravel-repository)[czim/laravel-repository

Repository for Laravel (inspired by and indebted to Bosnadev/Repositories)

54110.0k4](/packages/czim-laravel-repository)[czim/laravel-filter

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

8973.0k3](/packages/czim-laravel-filter)

PHPackages © 2026

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