laravel-repository maintained by mrtolouei
Laravel Repository
A clean and flexible base repository package for Laravel that simplifies data access, enforces the Repository Pattern, and keeps your application code organized, testable, and maintainable.
This package provides a reusable BaseRepository implementation with common Eloquent operations and a powerful filtering system.
Table of Contents
- Features
- Requirements
- Installation
- Basic Usage
- Available Methods
- Filtering System
- Query Builder & Chainable Methods
- Persisting Queries
- CRUD Operations
- Advanced Usage
- Testing
- Contributing
- License
Features
- Clean BaseRepository implementation
- Built‑in query builder helpers
- Dynamic filtering system with multiple operators
- Support for nested and OR conditions
- Relation filtering using dot notation
- Fluent query chaining
- Works with Laravel 9+
- Fully testable and extendable
Requirements
- PHP >= 8.0
- Laravel / Illuminate components >= 9.0
Installation
composer require mrtolouei/laravel-repository
No configuration or service provider registration is required.
Basic Usage
Create a repository for your model by extending the BaseRepository.
Example Model
App\Models\User
Create Repository
namespace App\Repositories;
use App\Models\User;
use Repository\Repositories\BaseRepository;
class UserRepository extends BaseRepository
{
public function __construct(User $model)
{
parent::__construct($model);
}
protected array $allowedFilters = [
'email',
'name',
'age',
'created_at',
];
}
Available Methods
The BaseRepository provides many commonly used data access methods.
Create
$user = $repository->create([
'email' => 'john@example.com',
'name' => 'John'
]);
Find
$user = $repository->find($id);
$user = $repository->findOrFail($id);
Update
$repository->update($id, [
'name' => 'Updated Name'
]);
Delete
$repository->delete($id);
Restore (Soft Deletes)
$repository->restore($id);
Insert Multiple
$repository->insert([
['email' => 'a@example.com'],
['email' => 'b@example.com']
]);
Where
$repository->where('age', '>', 18)->all();
OR Where
$repository
->where('age', 18)
->orWhere('age', 25)
->all();
Where In
$repository->whereIn('id', [1,2,3])->all();
Where Not In
$repository->whereNotIn('id', [4,5])->all();
Order
$repository->orderBy('created_at', 'desc')->all();
Limit
$repository->limit(10)->all();
Pagination
$repository->paginate(15);
Aggregate Functions
$repository->count();
$repository->sum('amount');
$repository->avg('rating');
Existence Check
$repository->where('email', 'john@example.com')->exists();
Filtering System
The package includes a powerful filtering trait that allows structured filtering from arrays (useful for APIs).
Only fields listed in $allowedFilters can be filtered.
Example
$repository->filter([
'age' => ['gte' => 18],
'email' => ['like' => 'gmail']
])->all();
Supported Operators
| Keyword | SQL Equivalent |
|---|---|
| eq | = |
| neq | != |
| gt | > |
| gte | >= |
| lt | < |
| lte | <= |
| like | LIKE |
| in | IN (...) |
Using Filters
Example usage in a controller:
public function index(Request $request)
{
$repo = new UserRepository(new User());
$users = $repo
->filter($request->query()) // apply filters
->orderBy('created_at', 'desc')
->paginate(15);
return response()->json($users);
}
Example filter input (from query parameters or request body):
{
"email": {
"like": "example.com"
},
"is_active": true,
"or": [
{
"age": {
"gte": 30
}
},
{
"roles.id": {
"in": [
1,
2,
3
]
}
}
]
}
Explanation
email.like:Finds users with email containing “example.com”is_active:Equals trueorgroup: Matches users aged 30+ or belonging to roles with IDs 1, 2, 3
Query Builder & Chainable Methods
All major query methods remain chainable:
| Method | Description | Example |
|---|---|---|
| query() | Get Builder instance | $userRepo->query()->where('active', true); |
| where(...) | Add where clause (supports array and closure) | $repo->where(['status' => 'active']); |
| with([...]) | Eager load relations | $repo->with(['posts', 'roles']); |
| orderBy() | Add order clause | $repo->orderBy('created_at', 'desc'); |
| limit() | Limit results | $repo->limit(10)->all(); |
Persisting Queries
Preserve query state across multiple operations:
$repo->persistQuery()
->where('is_active', true)
->orderBy('created_at', 'desc');
$firstActive = $repo->first();
$activeUsers = $repo->all();
Without calling persistQuery(), queries auto‑reset after each operation.
CRUD Operations
// Create
$newUser = $userRepo->create([
'name' => 'Ali',
'email' => 'ali@example.com',
]);
// Update
$updated = $userRepo->update($newUser->id, ['name' => 'Ali Tolouei']);
// Delete (soft)
$deletedCount = $userRepo->delete($newUser->id);
// Restore
$restoredCount = $userRepo->restore($newUser->id);
// Insert many
$userRepo->insert([
['name' => 'John', 'email' => 'john@example.com'],
['name' => 'Jane', 'email' => 'jane@example.com'],
]);
// First or create
$user = $userRepo->firstOrCreate(['email' => 'user@example.com'], ['name' => 'User']);
// Update or create
$user = $userRepo->updateOrCreate(['email' => 'user@example.com'], ['name' => 'Updated']);
Advanced Usage
Powerful nested filter combinations with chaining:
$users = $userRepo
->filter([
'is_active' => true,
'roles.id' => ['in' => [1, 5]],
'or' => [
['created_at' => ['gte' => '2024-01-01']],
['name' => ['like' => 'Ali']],
],
])
->with(['profile', 'posts'])
->orderBy('created_at', 'desc')
->paginate(10);
Testing
Run tests using PHPUnit:
vendor/bin/phpunit
Contributing
- Fork the repository
- Create a feature branch (
feature/awesome-feature) - Commit your changes (
git commit -m 'Add new feature') - Push to the branch (
git push origin feature/awesome-feature) - Open a Pull Request
License
This package is open-sourced software licensed under the MIT license.