PHP code example of cariuk / laravel-repository-pattern
1. Go to this page and download the library: Download cariuk/laravel-repository-pattern library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
cariuk / laravel-repository-pattern example snippets
namespace App\Repositories;
use App\Models\User;
use RepositoryPatternLaravel\Repository;
class UserRepository extends Repository
{
protected $fillable = [];
public function __construct()
{
$this->model = User::class;
}
}
namespace App\Repositories;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use RepositoryPatternLaravel\Repository;
class UserRepository extends Repository
{
// Fillable fields for create/update operations
protected $fillable = ['name', 'email', 'password'];
// Enable pagination (default: true)
protected $paginationable = true;
// Items per page (default: 10)
protected $paginatePerPage = 15;
// Allow sorting (default: true)
protected $sortable = true;
// Allowed fields for sorting
protected $sortAllowedFields = ['id', 'name', 'email', 'created_at'];
// Default sort field
protected $defaultSortField = 'created_at';
// Default sort direction (default: false)
protected $defaultSortDescending = true;
// Enable eager loading (default: false)
protected $relationable = true;
// Allowed relationships to load
protected $relationAllowed = ['posts', 'profile', 'roles'];
public function __construct()
{
$this->model = User::class;
}
/**
* Apply custom filters to the query
*/
protected function applyFilter(Request $request, Builder &$builder): void
{
// Search by name or email
if ($request->filled('search')) {
$builder->where(function($query) use ($request) {
$query->where('name', 'like', '%' . $request->search . '%')
->orWhere('email', 'like', '%' . $request->search . '%');
});
}
// Filter by status
if ($request->filled('status')) {
$builder->where('status', $request->status);
}
// Filter by role
if ($request->filled('role')) {
$builder->whereHas('roles', function($query) use ($request) {
$query->where('name', $request->role);
});
}
// Date range filter
if ($request->filled('from_date')) {
$builder->where('created_at', '>=', $request->from_date);
}
if ($request->filled('to_date')) {
$builder->where('created_at', '<=', $request->to_date);
}
}
}
namespace App\Http\Controllers;
use App\Http\Requests\UserStoreRequest;
use App\Http\Requests\UserUpdateRequest;
use App\Repositories\UserRepository;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function __construct(
protected UserRepository $repository
) {}
/**
* Display a listing of users
*/
public function index(Request $request)
{
$users = $this->repository->getList($request);
return response()->json($users);
}
/**
* Display a specific user
*/
public function show(Request $request, int $id)
{
$user = $this->repository->getDetail($request, $id);
return response()->json($user);
}
/**
* Create a new user
*/
public function store(UserStoreRequest $request)
{
$user = $this->repository->create($request);
return response()->json($user, 201);
}
/**
* Update an existing user
*/
public function update(UserUpdateRequest $request, int $id)
{
$user = $this->repository->update($request, $id);
return response()->json($user);
}
/**
* Delete a user
*/
public function destroy(Request $request, int $id)
{
$this->repository->delete($request, $id);
return response()->json(['message' => 'User deleted successfully']);
}
}
// Get paginated/collection list
$users = $repository->getList($request);
// Get single record by ID
$user = $repository->getDetail($request, $id);
// Get single record with custom query modifier
$user = $repository->getDetail($request, $id, function(Builder &$builder) {
$builder->where('status', 'active');
});
// Create a new record
$user = $repository->create($request);
// Create with array data
$user = $repository->create([
'name' => 'John Doe',
'email' => '[email protected]',
]);
// Update existing record
$user = $repository->update($request, $id);
// Update with custom query modifier
$user = $repository->update($request, $id, function(Builder &$builder) {
$builder->where('company_id', auth()->user()->company_id);
});
// Delete a record
$repository->delete($request, $id);
// Delete with custom query modifier
$repository->delete($request, $id, function(Builder &$builder) {
$builder->where('created_by', auth()->id());
});
// Get trashed records
$trashedUsers = $repository->getTrashList($request);
// Force delete permanently
$repository->forceDelete($request, $id);
// Restore soft-deleted record
$user = $repository->restore($request, $id);
class UserRepository extends Repository
{
/**
* Called after a record is created
*/
protected function onCreated(FormRequest|array $request, Model $object): void
{
// Send welcome email
Mail::to($object->email)->send(new WelcomeEmail($object));
// Log activity
activity()
->performedOn($object)
->log('User created');
}
/**
* Called after a record is updated
*/
protected function onUpdated(FormRequest $request, Model $object): void
{
// Invalidate cache
Cache::forget("user.{$object->id}");
}
/**
* Called after create or update
*/
protected function onSaved(FormRequest|array $request, Model $object): void
{
// Sync relationships
if (is_object($request) && $request->has('roles')) {
$object->roles()->sync($request->roles);
}
}
/**
* Called after a record is deleted
*/
protected function onDeleted(Request $request, Model $object): void
{
// Clean up related files
Storage::delete($object->avatar);
}
/**
* Called after a record is force deleted (soft delete only)
*/
protected function onForceDeleted(Request $request, Model $object): void
{
// Permanent cleanup
$object->posts()->forceDelete();
}
/**
* Called after a record is restored (soft delete only)
*/
protected function onRestored(Request $request, Model $object): void
{
// Restore related data
$object->posts()->restore();
}
}
class UserRepository extends Repository
{
/**
* Modify data before saving
*/
public function getDataSave(array $data, $action): array
{
// Hash password if present
if (isset($data['password'])) {
$data['password'] = bcrypt($data['password']);
}
// Add metadata
if ($action === 'create') {
$data['created_by'] = auth()->id();
}
if ($action === 'update') {
$data['updated_by'] = auth()->id();
}
return $data;
}
/**
* Different fillable fields for different operations
*/
protected function getFillable($method = null)
{
if ($method === 'create') {
return ['name', 'email', 'password', 'role_id'];
}
if ($method === 'update') {
// Don't allow changing email on update
return ['name', 'role_id'];
}
return $this->fillable;
}
}
// In your controller or service
public function getUsersByCompany(Request $request, int $companyId, int $userId)
{
return $this->repository->getDetail($request, $userId, function(Builder &$builder) use ($companyId) {
$builder->where('company_id', $companyId)
->where('status', 'active');
});
}
// Skip default filters
public function getAdminUser(Request $request, int $id)
{
return $this->repository->getDetail(
$request,
$id,
skipDefaultFilter: true // Skip applyFilter method
);
}
class PostRepository extends Repository
{
protected $relationable = true;
protected $relationAllowed = ['author', 'comments', 'tags'];
public function __construct()
{
$this->model = Post::class;
}
/**
* Load nested relationships
*/
protected function applyFilter(Request $request, Builder &$builder): void
{
// This will be combined with ?with=author,comments
// to load relationships efficiently
}
}
// Usage in controller
GET /posts?with=author,comments.user,tags
class UserRepository extends Repository
{
protected $paginationable = true;
protected $optionalPagination = true; // Allow disabling pagination
// ...
}
// Request without pagination
GET /users?paginate=false
// Good
class UserRepository extends Repository { }
class PostRepository extends Repository { }
// Avoid
class UserPostRepository extends Repository { }
// Good
public function store(UserStoreRequest $request)
{
return $this->repository->create($request);
}
// Avoid validating in repository
class UserService
{
public function __construct(
protected UserRepository $userRepository,
protected RoleRepository $roleRepository,
protected NotificationService $notificationService
) {}
public function createUserWithRole(array $data)
{
DB::beginTransaction();
try {
$user = $this->userRepository->create($data);
$role = $this->roleRepository->getDetail(request(), $data['role_id']);
$user->roles()->attach($role);
$this->notificationService->sendWelcomeEmail($user);
DB::commit();
return $user;
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}
}
// Good
public function getUserPosts(int $userId): Collection
{
return $this->repository->getDetail(request(), $userId)->posts;
}
// Avoid
public function getUserPosts($userId)
{
return $this->repository->getDetail(request(), $userId)->posts;
}
class UserRepository extends Repository
{
public function getDetail(Request $request, $id, \Closure $modifier = null, $skipDefaultFilter = false): Model
{
return Cache::remember("user.{$id}", 3600, function() use ($request, $id, $modifier, $skipDefaultFilter) {
return parent::getDetail($request, $id, $modifier, $skipDefaultFilter);
});
}
protected function onUpdated(FormRequest $request, Model $object): void
{
Cache::forget("user.{$object->id}");
}
}
use Tests\TestCase;
use App\Repositories\UserRepository;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
class UserRepositoryTest extends TestCase
{
use RefreshDatabase;
protected UserRepository $repository;
protected function setUp(): void
{
parent::setUp();
$this->repository = new UserRepository();
}
public function test_can_create_user()
{
$data = [
'name' => 'John Doe',
'email' => '[email protected]',
'password' => 'password123',
];
$user = $this->repository->create($data);
$this->assertInstanceOf(User::class, $user);
$this->assertEquals('John Doe', $user->name);
$this->assertDatabaseHas('users', ['email' => '[email protected]']);
}
public function test_can_get_paginated_list()
{
User::factory()->count(25)->create();
$request = request();
$result = $this->repository->getList($request);
$this->assertInstanceOf(\Illuminate\Pagination\LengthAwarePaginator::class, $result);
$this->assertEquals(10, $result->perPage());
$this->assertEquals(25, $result->total());
}
public function test_can_filter_users()
{
User::factory()->create(['name' => 'John Doe', 'status' => 'active']);
User::factory()->create(['name' => 'Jane Doe', 'status' => 'inactive']);
$request = request()->merge(['status' => 'active']);
$result = $this->repository->getList($request);
$this->assertEquals(1, $result->total());
$this->assertEquals('active', $result->first()->status);
}
}
// Instead of calling repositories inside hooks
protected function onCreated(FormRequest $request, Model $object): void
{
// Avoid - may cause deadlock
$this->roleRepository->create(['user_id' => $object->id]);
}
// Use events or jobs
protected function onCreated(FormRequest $request, Model $object): void
{
// Better - dispatched after transaction commits
CreateDefaultRole::dispatch($object);
}
// Use chunking instead
$this->repository->getBuilder()
->chunk(1000, function($users) {
foreach ($users as $user) {
// Process user
}
});
bash
php artisan make:repository UserRepository User
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.