PHPackages                             nejcc/laravel-querylayer - 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. [API Development](/categories/api)
4. /
5. nejcc/laravel-querylayer

ActiveLibrary[API Development](/categories/api)

nejcc/laravel-querylayer
========================

v1.0.0(1y ago)21MITPHPPHP ^8.3CI failing

Since May 5Pushed 1y ago1 watchersCompare

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

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

Laravel QueryLayer
==================

[](#laravel-querylayer)

[![Latest Version on Packagist](https://camo.githubusercontent.com/b32c44c89093c0ef36623f9e7984e478e646787fa9fc11dcfa222d7bde0067aa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e656a63632f6c61726176656c2d71756572796c617965722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nejcc/laravel-querylayer)[![Total Downloads](https://camo.githubusercontent.com/233adc13fa725e0950570e0bc783591303b4d9b14417c753104694c05a62fa98/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e656a63632f6c61726176656c2d71756572796c617965722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nejcc/laravel-querylayer)[![GitHub Actions](https://github.com/nejcc/laravel-querylayer/actions/workflows/main.yml/badge.svg)](https://github.com/nejcc/laravel-querylayer/actions)[![License](https://camo.githubusercontent.com/48a501be43703d635e5b675fac95369bec3ad7ff1578789f50b8b240c2c20bf0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6e656a63632f6c61726176656c2d71756572796c617965722e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

A powerful and flexible repository pattern implementation for Laravel applications. This package provides a clean and maintainable way to handle database operations in your Laravel projects, with built-in singleton pattern support for efficient repository management.

Features
--------

[](#features)

- 🚀 Quick repository creation for any Eloquent model
- 🔄 Full CRUD operations out of the box
- 📦 Type-safe with PHP 8.0+ features and generics support
- 🎯 Query builder access for complex queries
- 📱 Pagination support
- 🛠️ Extensible base repository for custom implementations
- 💡 IDE-friendly with comprehensive PHPDoc annotations
- 🔒 Singleton pattern implementation for efficient resource usage
- 🗑️ Soft delete support for models using SoftDeletes
- 🔄 Database transaction support for reliable operations
- 🔗 Eager loading support for optimized relationship queries
- 🧹 Automatic query scope reset for cleaner code

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

[](#requirements)

- PHP 8.0 or higher
- Laravel 8.0 or higher

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

[](#installation)

You can install the package via composer:

```
composer require nejcc/laravel-querylayer
```

The package will automatically register its service provider.

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

[](#quick-start)

### Using the Facade

[](#using-the-facade)

The simplest way to create a repository for any model:

```
use Nejcc\LaravelQuerylayer\Facades\LaravelQuerylayer;
use App\Models\User;

// Get a repository instance for the User model
// The same instance will be returned for subsequent calls with the same model
$userRepository = LaravelQuerylayer::repository(User::class);

// Basic operations
$users = $userRepository->where(['is_active' => true])->paginate(15);
$user = $userRepository->find(1);
$activeUsers = $userRepository->where(['is_active' => true])->get();

// Pagination
$paginatedUsers = $userRepository->paginate();

// Create and update
$newUser = $userRepository->create([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

$userRepository->update(1, ['name' => 'Jane Doe']);

// Delete
$userRepository->delete(1);

// Eager loading relationships
$userWithPosts = $userRepository->with('posts')->find(1);

// Soft deletes - if your model uses SoftDeletes
$trashedUser = $userRepository->withTrashed()->find(5);
$onlyTrashedUsers = $userRepository->onlyTrashed()->paginate(10);
$userRepository->restore(1);
$userRepository->forceDelete(1);

// Transactions
$userRepository->transaction(function () use ($userRepository) {
    // Execute multiple operations in a transaction
    $user = $userRepository->create(['name' => 'Transaction User']);
    $userRepository->update($user->id, ['name' => 'Updated User']);
    return $user;
});

// Or use the convenient methods
$user = $userRepository->createOrFail(['name' => 'Safe Create']);
$success = $userRepository->updateOrFail(1, ['name' => 'Safe Update']);
```

### Creating Custom Repositories

[](#creating-custom-repositories)

For more complex scenarios, extend the `BaseRepository`:

```
use Nejcc\LaravelQuerylayer\Repositories\BaseRepository;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

class UserRepository extends BaseRepository
{
    protected function model(): string
    {
        return User::class;
    }

    /**
     * Get active admin users with pagination
     */
    public function getActiveAdminsPaginated(?int $perPage = null): LengthAwarePaginator
    {
        return $this->getActiveAdminsQuery()->paginate($perPage);
    }

    /**
     * Get query builder for active admin users
     */
    public function getActiveAdminsQuery(): Builder
    {
        return $this->query()
            ->where('is_active', true)
            ->where('role', 'admin');
    }
}
```

Available Methods
-----------------

[](#available-methods)

The repository provides a comprehensive set of methods for database operations:

MethodDescription`all()`Get all records (use with caution for large datasets)`get()`Get records for the current query`paginate(?int $perPage = null)`Get paginated results`find(intstring $id)``findBy(string $column, mixed $value)`Find a record by column value`where(array $conditions)`Add where conditions to the query`create(array $data)`Create a new record`update(intstring $id, array $data)``delete(intstring $id)``query()`Get the query builder instance`db()`Get the raw DB query builder instance`with(string|array $relations)`Eager load relationships`withTrashed()`Include soft deleted records`onlyTrashed()`Get only soft deleted records`restore(int|string $id)`Restore a soft deleted record`forceDelete(int|string $id)`Permanently delete a record`transaction(callable $callback)`Execute operations in a transaction`createOrFail(array $data)`Create a record in a transaction`updateOrFail(int|string $id, array $data)`Update a record in a transaction`reset()`Reset query scopes and eager loadingMethod Chaining
---------------

[](#method-chaining)

The repository supports fluent method chaining for building complex queries:

```
// Chain methods for a single query
$adminUsers = $userRepository
    ->with('posts')
    ->where(['role' => 'admin'])
    ->paginate(15);  // Pagination instead of all() for large datasets

// For limited dataset, you can use get()
$recentPosts = $postRepository
    ->query()
    ->orderBy('created_at', 'desc')
    ->limit(5)
    ->get();

// Query scopes are automatically reset after execution
// So this query will NOT include any trashed records
$activeUsers = $userRepository->where(['is_active' => true])->get();

// You can also manually reset query scopes
$userRepository
    ->withTrashed()
    ->with('posts')
    ->reset() // Reset all query scopes
    ->where(['is_admin' => true])
    ->get(); // Will NOT include trashed records or eager load posts
```

Singleton Pattern
-----------------

[](#singleton-pattern)

The package implements the singleton pattern for repository instances. This means:

- Each model class gets a single repository instance
- Subsequent calls to `LaravelQuerylayer::repository()` with the same model return the same instance
- This helps reduce memory usage and improves performance
- Perfect for dependency injection and service container usage

Soft Deletes
------------

[](#soft-deletes)

If your model uses Laravel's `SoftDeletes` trait, the repository automatically supports:

- Regular queries will exclude soft deleted records
- Use `withTrashed()` to include soft deleted records
- Use `onlyTrashed()` to get only soft deleted records
- Restore soft deleted records with `restore(id)`
- Permanently delete with `forceDelete(id)`

Transactions
------------

[](#transactions)

For data integrity, the repository provides transaction support:

- Wrap multiple operations in `transaction(function() { ... })`
- Use `createOrFail()` to ensure a record is created or transaction fails
- Use `updateOrFail()` to ensure an update succeeds or transaction fails

Eager Loading
-------------

[](#eager-loading)

Optimize database queries by eager loading relationships:

- Use `with('relation')` to load a single relation
- Use `with(['relation1', 'relation2'])` to load multiple relations
- Chain with other methods: `with('posts')->where(['active' => true])->get()`

Direct Database Access with db()
--------------------------------

[](#direct-database-access-with-db)

In addition to the Eloquent query builder accessible via `query()`, the repository provides raw database access through the `db()` method:

```
// Get raw database query builder for direct table operations
$usersTable = $userRepository->db();

// Perform complex SQL operations
$activeUsersByRole = $userRepository->db()
    ->select('role', $userRepository->db()->raw('COUNT(*) as count'))
    ->where('is_active', true)
    ->groupBy('role')
    ->orderBy('count', 'desc')
    ->get();

// Complex joins and aggregates
$userStats = $userRepository->db()
    ->select(
        'users.id',
        'users.name',
        $userRepository->db()->raw('COUNT(posts.id) as total_posts'),
        $userRepository->db()->raw('SUM(CASE WHEN posts.is_published = 1 THEN 1 ELSE 0 END) as published_posts')
    )
    ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
    ->groupBy('users.id', 'users.name')
    ->having('total_posts', '>', 0)
    ->orderBy('total_posts', 'desc')
    ->get();

// Useful for complex search functionality
$query = $userRepository->db();
if ($request->has('search')) {
    $query->where('name', 'like', "%{$request->search}%");
}
if ($request->has('role')) {
    $query->where('role', $request->role);
}
$results = $query->orderBy('name')->get();

// Direct database updates or bulk operations
$affected = $userRepository->db()
    ->whereIn('id', $userIds)
    ->update(['is_active' => false]);
```

The `db()` method provides:

- Direct access to Laravel's Query Builder for raw SQL operations
- Perfect for complex joins, aggregations, and statistical queries
- Useful for bulk operations that would be inefficient with Eloquent
- Access to advanced SQL features not available in Eloquent

When to use `db()` vs `query()`:

- Use `query()` when you need model features like relationships, accessors/mutators, and model events
- Use `db()` when you need raw performance, complex joins, or SQL-specific functionality
- Choose `db()` for statistical queries and reporting where you don't need full model instances

You can find more examples of using the `db()` method in the demo repositories:

- UserRepository - examples of grouping and counting
- PostRepository - examples of joins and complex filtering
- CommentRepository - examples of aggregation and bulk operations

Testing
-------

[](#testing)

The package includes a comprehensive test suite. Run the tests with:

```
composer test
```

Code Style
----------

[](#code-style)

This package follows the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding standard. Format your code using Laravel Pint:

```
# Format all files
composer format

# Check formatting without making changes
composer format-test
```

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)

- [Nejcc](https://github.com/nejcc)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

Model Interface
---------------

[](#model-interface)

You can also use the repository functionality directly on your models by implementing the `ModelInterface` and using the `HasRepository` trait:

```
use Nejcc\LaravelQuerylayer\Contracts\ModelInterface;
use Nejcc\LaravelQuerylayer\Traits\HasRepository;

class User extends Model implements ModelInterface
{
    use HasRepository;

    protected static function getRepositoryClass(): string
    {
        return UserRepository::class;
    }
}
```

Now you can use repository methods directly on your model:

```
// Create a new user
$user = User::createRecord([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// Find a user
$user = User::findById(1);
$user = User::findByColumn('email', 'john@example.com');

// Get all users
$users = User::getAll();

// Get paginated users
$users = User::getPaginated(10);

// Get users with conditions
$users = User::getWhere(['role' => 'admin']);

// Update a user
User::updateRecord(1, ['name' => 'Jane Doe']);

// Delete a user
User::deleteRecord(1);

// Get the query builder
$query = User::getQuery();

// Get the repository instance
$repository = User::getRepository();
```

This approach gives you the flexibility to use repository methods either through the repository class or directly on your models.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance49

Moderate activity, may be stable

Popularity4

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

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

378d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4e4629de002c40aef796e5b320091892f0b7b35b62497260c52cef3eb721eed1?d=identicon)[Nejcc](/maintainers/Nejcc)

---

Tags

nejcclaravel-querylayer

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/nejcc-laravel-querylayer/health.svg)

```
[![Health](https://phpackages.com/badges/nejcc-laravel-querylayer/health.svg)](https://phpackages.com/packages/nejcc-laravel-querylayer)
```

###  Alternatives

[mollie/laravel-mollie

Mollie API client wrapper for Laravel &amp; Mollie Connect provider for Laravel Socialite

3624.1M28](/packages/mollie-laravel-mollie)[mll-lab/laravel-graphiql

Easily integrate GraphiQL into your Laravel project

683.2M9](/packages/mll-lab-laravel-graphiql)[spatie/laravel-route-discovery

Auto register routes using PHP attributes

23645.0k2](/packages/spatie-laravel-route-discovery)[esign/laravel-conversions-api

A laravel wrapper package around the Facebook Conversions API

69145.4k](/packages/esign-laravel-conversions-api)[didww/didww-api-3-php-sdk

PHP SDK for DIDWW API 3

1218.2k](/packages/didww-didww-api-3-php-sdk)[surface/laravel-webfinger

A Laravel package to create an ActivityPub webfinger.

113.8k](/packages/surface-laravel-webfinger)

PHPackages © 2026

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