Gohari Repository Pattern Laravel package documentation · v1.1.0
Laravel · Repository · Service Layer · DTO

Clean repository and service generation for Laravel.

Generate repositories, contracts, services, DTOs, bindings, publishable stubs, and configuration with one package. This page contains the complete documentation in English and Persian.

Created by Mohamadreza Gohari, a member of Gandom Software Group.

English Documentation

`gohari/repository-pattern` helps Laravel applications keep data access predictable by generating repositories, interfaces, optional service layers, DTOs, and service-provider bindings.

This package was created by Mohamadreza Gohari from Gandom Software Group.

Repository generator Create repository classes and contracts from Artisan.
Service layer generator Generate services, service interfaces, DTOs, and config together.
Publishable stubs Customize generator templates in your own application.
Clean tooling PHPUnit, Larastan/PHPStan, and Pint scripts are included.

Installation

Install the package with Composer:

composer require gohari/repository-pattern

Laravel package discovery registers the provider automatically:

Gohari\RepositoryPattern\RepositoryPatternServiceProvider::class

If package discovery is disabled, register it manually in config/app.php:

'providers' => [
    Gohari\RepositoryPattern\RepositoryPatternServiceProvider::class,
],

Publish configuration and stubs when you want to customize defaults:

php artisan vendor:publish --tag=repository-pattern-config
php artisan vendor:publish --tag=repository-pattern-stubs

Published stubs are stored in resources/stubs/vendor/repository-pattern.

Command Usage

php artisan repository:make {name} --model={model}
Option Description
name Repository name. User and UserRepository both generate UserRepository.
--model Model class name or FQCN. Defaults to the repository name.
--path Repository output path. Defaults to config paths.repositories.
--interface-path Repository interface output path. Defaults to config paths.interfaces.
--force Overwrite existing generated files.
--bind Register interface-to-implementation bindings in App\Providers\RepositoryServiceProvider.
--service Generate repository, repository interface, service, service interface, DTO, and config.
--service-path Service output path. Defaults to config paths.services.
--dto Generate only the DTO alongside the repository.
--dto-path DTO output path. Defaults to config paths.dtos.
--config Copy the package config file into the application.

Examples

php artisan repository:make User --model=User
php artisan repository:make UserRepository --model=User
php artisan repository:make Product --model="App\Models\Product"
php artisan repository:make Admin/User --model=User
php artisan repository:make User --model=User --service
php artisan repository:make User --model=User --service --bind
php artisan repository:make Product --model=Product --path=app/Domain/Repositories
php artisan repository:make Product --model=Product --force

Generated Repository

A basic command creates the repository and its contract:

php artisan repository:make User --model=User
app/Repositories/UserRepository.php
app/Repositories/Contracts/UserRepositoryInterface.php

Repository output

<?php

namespace App\Repositories;

use App\Models\User;
use App\Repositories\Contracts\UserRepositoryInterface;
use Gohari\RepositoryPattern\BaseRepository;

class UserRepository extends BaseRepository implements UserRepositoryInterface
{
    public function __construct(User $user)
    {
        parent::__construct($user);
    }
}

Contract output

<?php

namespace App\Repositories\Contracts;

use Gohari\RepositoryPattern\BaseRepositoryInterface;

interface UserRepositoryInterface extends BaseRepositoryInterface
{
    //
}

Base Repository Methods

$repository->query();
$repository->getAll();
$repository->paginate(15);
$repository->findById($id);
$repository->findOrFail($id);
$repository->firstWhere('email', 'user@example.com');
$repository->findBy('email', 'user@example.com');
$repository->exists($id);
$repository->count();
$repository->create($data);
$repository->updateOrCreate(['email' => $email], $data);
$repository->update($id, $data);
$repository->delete($id);
$repository->deleteMany([$firstId, $secondId]);
$repository->search('email', 'user@example.com', '=');
$repository->searchByColumn('name', 'john');
$repository->with(['roles', 'profile'])->paginate();
$repository->withRelations(['roles', 'profile'])->get();
$repository->sortBy('created_at', 'desc')->get();
$repository->withTrashed()->getAll();
$repository->onlyTrashed()->count();
$repository->restore($id);
$repository->forceDelete($id);

Legacy aliases are still available: insertData, updateItem, and deleteData.

Service Layer, DTO, and Binding

Generate all layers together:

php artisan repository:make User --model=User --service --bind
app/Repositories/UserRepository.php
app/Repositories/Contracts/UserRepositoryInterface.php
app/Services/UserService.php
app/Services/UserServiceInterface.php
app/DTOs/UserData.php
config/repository-pattern.php

The generated service supports relationships, sorting, DTO-based create/update, restore, and force delete:

$users->paginate(['roles'], 'created_at', 'desc', 20);
$users->find($id, ['profile']);
$users->create(UserData::fromArray($data));
$users->restore($id);
$users->forceDelete($id);

When binding is enabled, the command creates or updates app/Providers/RepositoryServiceProvider.php:

public function register(): void
{
    $this->app->bind(
        \App\Repositories\Contracts\UserRepositoryInterface::class,
        \App\Repositories\UserRepository::class
    );

    $this->app->bind(
        \App\Services\UserServiceInterface::class,
        \App\Services\UserService::class
    );
}

The provider is registered in bootstrap/providers.php for modern Laravel apps, or in config/app.php when that file is available.

Configuration

Publish the config file:

php artisan vendor:publish --tag=repository-pattern-config
<?php

return [
    'paths' => [
        'repositories' => app_path('Repositories'),
        'interfaces' => app_path('Repositories/Contracts'),
        'services' => app_path('Services'),
        'dtos' => app_path('DTOs'),
        'stubs' => resource_path('stubs/vendor/repository-pattern'),
    ],

    'namespaces' => [
        'repositories' => 'App\\Repositories',
        'interfaces' => 'App\\Repositories\\Contracts',
        'services' => 'App\\Services',
        'dtos' => 'App\\DTOs',
    ],

    'auto_bind' => true,
    'generate_service' => false,
    'generate_model_if_missing' => true,
];

Publish and edit stubs when you need custom class templates:

php artisan vendor:publish --tag=repository-pattern-stubs
If a published stub exists, it overrides the internal package stub with the same filename.

Testing, Analysis, Formatting, and Security

Install dependencies and run the quality checks:

composer install
composer test
composer analyse
composer format:test

Format code with Pint:

composer format

Security vulnerabilities should not be reported in public issues. See SECURITY.md for the reporting address and supported versions.

The package is released under the MIT License.

مستندات فارسی

پکیج gohari/repository-pattern برای پروژه‌های Laravel ساخته شده تا ساخت Repository، Contract، Service Layer، DTO، binding و config قابل انتشار را سریع‌تر و تمیزتر کند.

سازنده این پکیج محمدرضا گوهری از تیم Gandom Software Group است.

تولید Repository با یک دستور Artisan کلاس Repository و Interface آن را بسازید.
تولید Service Layer Service، ServiceInterface، DTO و config را کنار Repository بسازید.
Stub قابل انتشار قالب فایل‌های تولیدی را داخل پروژه خودتان شخصی‌سازی کنید.
ابزارهای کیفیت کد PHPUnit، Larastan/PHPStan و Pint برای توسعه پکیج آماده‌اند.

نصب

پکیج را با Composer نصب کنید:

composer require gohari/repository-pattern

Laravel به صورت خودکار Service Provider پکیج را پیدا و ثبت می‌کند:

Gohari\RepositoryPattern\RepositoryPatternServiceProvider::class

اگر package discovery غیرفعال است، provider را دستی داخل config/app.php ثبت کنید:

'providers' => [
    Gohari\RepositoryPattern\RepositoryPatternServiceProvider::class,
],

برای شخصی‌سازی config و stubها، آن‌ها را publish کنید:

php artisan vendor:publish --tag=repository-pattern-config
php artisan vendor:publish --tag=repository-pattern-stubs

Stubهای publish شده در مسیر resources/stubs/vendor/repository-pattern قرار می‌گیرند.

دستورها

php artisan repository:make {name} --model={model}
گزینه توضیح
name نام Repository. هر دو مقدار User و UserRepository خروجی UserRepository می‌سازند.
--model نام مدل یا FQCN مدل. اگر وارد نشود از نام Repository استفاده می‌شود.
--path مسیر خروجی Repository. پیش‌فرض از config بخش paths.repositories خوانده می‌شود.
--interface-path مسیر خروجی Interface. پیش‌فرض app/Repositories/Contracts است.
--force فایل‌های موجود را overwrite می‌کند.
--bind Binding بین Interface و Implementation را داخل App\Providers\RepositoryServiceProvider ثبت می‌کند.
--service Repository، Interface، Service، ServiceInterface، DTO و config را با هم تولید می‌کند.
--service-path مسیر خروجی Service. پیش‌فرض از config بخش paths.services خوانده می‌شود.
--dto فقط DTO را کنار Repository تولید می‌کند.
--dto-path مسیر خروجی DTO. پیش‌فرض از config بخش paths.dtos خوانده می‌شود.
--config فایل config پکیج را داخل پروژه کپی می‌کند.

مثال‌ها

php artisan repository:make User --model=User
php artisan repository:make UserRepository --model=User
php artisan repository:make Product --model="App\Models\Product"
php artisan repository:make Admin/User --model=User
php artisan repository:make User --model=User --service
php artisan repository:make User --model=User --service --bind
php artisan repository:make Product --model=Product --path=app/Domain/Repositories
php artisan repository:make Product --model=Product --force

Repository تولید شده

این دستور:

php artisan repository:make User --model=User

این فایل‌ها را می‌سازد:

app/Repositories/UserRepository.php
app/Repositories/Contracts/UserRepositoryInterface.php

خروجی Repository

<?php

namespace App\Repositories;

use App\Models\User;
use App\Repositories\Contracts\UserRepositoryInterface;
use Gohari\RepositoryPattern\BaseRepository;

class UserRepository extends BaseRepository implements UserRepositoryInterface
{
    public function __construct(User $user)
    {
        parent::__construct($user);
    }
}

خروجی Interface

<?php

namespace App\Repositories\Contracts;

use Gohari\RepositoryPattern\BaseRepositoryInterface;

interface UserRepositoryInterface extends BaseRepositoryInterface
{
    //
}

متدهای BaseRepository

$repository->query();
$repository->getAll();
$repository->paginate(15);
$repository->findById($id);
$repository->findOrFail($id);
$repository->firstWhere('email', 'user@example.com');
$repository->findBy('email', 'user@example.com');
$repository->exists($id);
$repository->count();
$repository->create($data);
$repository->updateOrCreate(['email' => $email], $data);
$repository->update($id, $data);
$repository->delete($id);
$repository->deleteMany([$firstId, $secondId]);
$repository->search('email', 'user@example.com', '=');
$repository->searchByColumn('name', 'john');
$repository->with(['roles', 'profile'])->paginate();
$repository->withRelations(['roles', 'profile'])->get();
$repository->sortBy('created_at', 'desc')->get();
$repository->withTrashed()->getAll();
$repository->onlyTrashed()->count();
$repository->restore($id);
$repository->forceDelete($id);

Aliasهای قدیمی insertData، updateItem و deleteData همچنان پشتیبانی می‌شوند.

Service Layer، DTO و Binding

برای تولید همه لایه‌ها با هم:

php artisan repository:make User --model=User --service --bind
app/Repositories/UserRepository.php
app/Repositories/Contracts/UserRepositoryInterface.php
app/Services/UserService.php
app/Services/UserServiceInterface.php
app/DTOs/UserData.php
config/repository-pattern.php

Service تولید شده pagination همراه relationship و sorting، عملیات create/update با DTO یا array، و soft delete را پوشش می‌دهد:

$users->paginate(['roles'], 'created_at', 'desc', 20);
$users->find($id, ['profile']);
$users->create(UserData::fromArray($data));
$users->restore($id);
$users->forceDelete($id);

وقتی binding فعال باشد، فایل app/Providers/RepositoryServiceProvider.php ساخته یا به‌روزرسانی می‌شود:

public function register(): void
{
    $this->app->bind(
        \App\Repositories\Contracts\UserRepositoryInterface::class,
        \App\Repositories\UserRepository::class
    );

    $this->app->bind(
        \App\Services\UserServiceInterface::class,
        \App\Services\UserService::class
    );
}

این provider در Laravelهای جدید داخل bootstrap/providers.php ثبت می‌شود و در پروژه‌های قدیمی‌تر در config/app.php.

تنظیمات و Stubها

برای انتشار config:

php artisan vendor:publish --tag=repository-pattern-config
<?php

return [
    'paths' => [
        'repositories' => app_path('Repositories'),
        'interfaces' => app_path('Repositories/Contracts'),
        'services' => app_path('Services'),
        'dtos' => app_path('DTOs'),
        'stubs' => resource_path('stubs/vendor/repository-pattern'),
    ],

    'namespaces' => [
        'repositories' => 'App\\Repositories',
        'interfaces' => 'App\\Repositories\\Contracts',
        'services' => 'App\\Services',
        'dtos' => 'App\\DTOs',
    ],

    'auto_bind' => true,
    'generate_service' => false,
    'generate_model_if_missing' => true,
];

برای انتشار stubها:

php artisan vendor:publish --tag=repository-pattern-stubs
اگر stub منتشر شده با همان نام وجود داشته باشد، command به جای stub داخلی پکیج از همان فایل استفاده می‌کند.

تست، تحلیل ایستا، فرمت و امنیت

برای توسعه پکیج:

composer install
composer test
composer analyse
composer format:test

برای فرمت کردن کد با Pint:

composer format

آسیب‌پذیری‌های امنیتی را در issue عمومی GitHub ثبت نکنید. روش گزارش در فایل SECURITY.md نوشته شده است.

این پکیج با لایسنس MIT منتشر شده است.