├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── composer.json ├── config └── repository.php └── src ├── Console ├── Commands │ ├── InstallPackageCommand.php │ ├── MakeRepositoryCommand.php │ └── MakeRepositoryProviderCommand.php └── Stubs │ ├── RepositoryInterface.stub │ ├── RepositoryServiceProvider.stub │ └── repository.stub ├── Facades └── RepositoryFacade.php ├── Providers └── RepositoryServiceProvider.php ├── Repositories ├── BaseRepository.php └── IBaseEloquentRepositoryInterface.php ├── Repository.php └── Traits ├── GetStubs.php ├── HelpersMethods.php └── Validation.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://idpay.ir/laravelir'] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | node_modules/ 3 | npm-debug.log 4 | yarn-error.log 5 | composer.lock 6 | *.meta.* 7 | _ide_* 8 | .phpunit.result.cache 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - [![Starts](https://img.shields.io/github/stars/miladimos/laravel-repository?style=flat&logo=github)](https://github.com/miladimos/laravel-repository/forks) 2 | - [![Forks](https://img.shields.io/github/forks/miladimos/laravel-repository?style=flat&logo=github)](https://github.com/miladimos/laravel-repository/stargazers) 3 | 4 | ### in your project 5 | 6 | `composer require miladimos/laravel-repository` 7 | 8 | ### for install package 9 | 10 | `php artisan repository:install` 11 | 12 | ### for create new repository 13 | 14 | `php artisan make:repository {ModelName}` 15 | 16 | ### Example: 17 | 18 | `php artisan make:repository Tag` 19 | 20 | this create a TagRepository and TagEloquentRepositoryInterface 21 | 22 | next you must add Repository to RepositoryServiceProvider in repositories property like: 23 | 24 | ```php 25 | protected $repositories = [ 26 | [ 27 | TagEloquentRepositoryInterface::class, 28 | TagRepository::class, 29 | ], 30 | ]; 31 | ``` 32 | 33 | next in your controller add this: 34 | 35 | ```php 36 | private $tagRepo; 37 | public function __construct(TagEloquentRepositoryInterface $tagRepo) 38 | { 39 | $this->tagRepo = $tagRepo; 40 | } 41 | 42 | ``` 43 | 44 | add custom methods in TagEloquentRepositoryInterface and implement them. 45 | 46 | you must have a provider with below content and register it: 47 | 48 | ```php 49 | repositories as $repository) { 71 | $this->app->bind($repository[0], $repository[1]); 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | or create it automatically by below command: 78 | 79 | ```php 80 | php artisan make:repository:provider 81 | ``` 82 | 83 | and add to app.php providers: 84 | 85 | ```php 86 | App\Providers\RepositoryServiceProvider::class, 87 | ``` 88 | 89 | #### Methods: 90 | 91 | ```php 92 | $model->all($columns = ['*']); 93 | 94 | $model->create(array $data); 95 | 96 | $model->update(array $data, $id, $attribute = "id"); 97 | 98 | $model->find($id); 99 | 100 | $model->findOrFail($id); 101 | 102 | $model->findWhere(string $field, $condition, $columns); 103 | 104 | $model->first(); 105 | 106 | $model->last(); 107 | 108 | $model->firstOrCreate(); 109 | 110 | $model->whereIn($attribute, array $values); 111 | 112 | $model->max($column); 113 | 114 | $model->min($column); 115 | 116 | $model->avg($column); 117 | 118 | $model->delete($id); 119 | 120 | $model->truncate(); 121 | 122 | $model->count($columns = ['*']); 123 | 124 | $model->paginate($columns = ['*'], $perPage = 8); 125 | 126 | $model->simplePaginate($limit = null, $columns = ['*']); 127 | 128 | $model->search(array $query, $columns = ["*"]); 129 | 130 | $model->pluck($value, $key = null); 131 | 132 | $model->with($relations); 133 | 134 | $model->toSql(); 135 | 136 | 137 | ``` 138 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "miladimos/laravel-repository", 3 | "description": "a powerful and simple to use package for repository pattern", 4 | "homepage": "https://github.com/miladimos/laravel-repository", 5 | "type": "library", 6 | "version": "v0.8.9", 7 | "keywords": [ 8 | "laravel", 9 | "laravel-package", 10 | "laravel-repository", 11 | "laravel support", 12 | "laravel packages", 13 | "repository pattern", 14 | "design pattern", 15 | "repository" 16 | ], 17 | "authors": [ 18 | { 19 | "name": "miladimos", 20 | "email": "miladimos@outlook.com", 21 | "role": "maintainer", 22 | "homepage": "https://github.com/miladimos" 23 | } 24 | ], 25 | "autoload": { 26 | "psr-4": { 27 | "Miladimos\\Repository\\": "src/" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "Miladimos\\Repository\\Tests\\": "tests" 33 | } 34 | }, 35 | "extra": { 36 | "laravel": { 37 | "providers": [ 38 | "Miladimos\\Repository\\Providers\\RepositoryServiceProvider" 39 | ], 40 | "aliases": { 41 | "Repository": "Miladimos\\Repository\\Facades\\RepositoryFacade" 42 | } 43 | } 44 | }, 45 | "require": { 46 | "php": ">=7.4|^8.0" 47 | }, 48 | "scripts": { 49 | "post-package-update": [ 50 | "php artisan vendor:publish --provider=Miladimos\\Repository\\Providers\\RepositoryServiceProvider --tag=repository-stubs --force", 51 | "php artisan vendor:publish --provider=Miladimos\\Repository\\Providers\\RepositoryServiceProvider --tag=repository-config --force" 52 | ] 53 | }, 54 | "license": "MIT" 55 | } 56 | -------------------------------------------------------------------------------- /config/repository.php: -------------------------------------------------------------------------------- 1 | getNamespace() 8 | */ 9 | 'application_namespace' => 'App', 10 | 11 | /** 12 | * Path that contains Models 13 | * 14 | * application_namespace + \ + models_namespace ==> App\Models 15 | */ 16 | 'models_namespace' => 'Models', 17 | 18 | /** 19 | * Path that contains Repositories 20 | * 21 | * application_namespace + repositories_namespace ==> App\Repositories 22 | * 23 | */ 24 | 'repositories_namespace' => 'Repositories', 25 | 26 | /** 27 | * Path that contains Repository Interfaces 28 | * 29 | * application_namespace + repositories_namespace ==> App\Repositories\Interfaces; 30 | */ 31 | 'interfaces_namespace' => 'Interfaces', 32 | 33 | /** 34 | * Suffix for Created Repositories 35 | * 36 | * ex: $modelNameRepository 37 | * 38 | */ 39 | 'repositories_suffix' => 'Repository', 40 | 41 | /** 42 | * Suffix for Created Repositories 43 | * 44 | * ex: $modelNameInterface 45 | * 46 | */ 47 | 'interfaces_suffix' => 'Interface', 48 | 49 | 'caching' => [ 50 | 'enabled' => false, 51 | ], 52 | ]; 53 | -------------------------------------------------------------------------------- /src/Console/Commands/InstallPackageCommand.php: -------------------------------------------------------------------------------- 1 | info("laravel-repository package installing started..."); 20 | 21 | //config 22 | if (File::exists(config_path('repository.php'))) { 23 | $confirmConfig = $this->confirm("repository.php already exist. you must overwrite it! Are you ok?"); 24 | if ($confirmConfig) { 25 | $this->publishConfig(); 26 | $this->info("config publish/overwrite finished"); 27 | } else { 28 | $this->error("you must publish or overwrite config file"); 29 | die; 30 | } 31 | } else { 32 | $this->publishConfig(); 33 | $this->info("config published"); 34 | } 35 | 36 | // stub files 37 | if (File::isDirectory(resource_path('vendor/miladimos/repository/stubs'))) { 38 | $confirmConfig = $this->confirm("stubs files already exist. you must overwrite it! Are you ok?"); 39 | if ($confirmConfig) { 40 | $this->publishStubs(); 41 | $this->info("stubs publish/overwrite finished"); 42 | } else { 43 | $this->error("you must publish and overwrite stubs file"); 44 | die; 45 | } 46 | } 47 | $this->publishStubs(); 48 | $this->info("stub files published!"); 49 | 50 | 51 | $this->info("repository package installed successfully! please star me on github!"); 52 | $this->info("https://github.com/miladimos/laravel-repository"); 53 | 54 | return 0; 55 | } 56 | 57 | private function publishConfig() 58 | { 59 | $this->call('vendor:publish', [ 60 | '--provider' => "Miladimos\Repository\Providers\RepositoryServiceProvider", 61 | '--tag' => "repository-config", 62 | '--force' => true, 63 | ]); 64 | } 65 | 66 | private function publishStubs() 67 | { 68 | $this->call('vendor:publish', [ 69 | '--provider' => "Miladimos\Repository\Providers\RepositoryServiceProvider", 70 | '--tag' => "repository-stubs", 71 | '--force' => true, 72 | ]); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Console/Commands/MakeRepositoryCommand.php: -------------------------------------------------------------------------------- 1 | modelName = trim(Str::studly($this->argument('model'))); 30 | 31 | $this->warn("Repository {$this->modelName} is creating ..."); 32 | 33 | try { 34 | 35 | if ((new self)->ensureRepositoryDoesntAlreadytExist($this->modelName)) { 36 | $msg = ' ""' . (new self)->getRepositoryPath($this->modelName) . '""' . " already exist. you must overwrite it! Are you ok?"; 37 | 38 | $confirm = $this->confirm($msg); 39 | if ($confirm) { 40 | if (Repository::make($this->modelName)) { 41 | $this->info("{$this->modelName}Repository.php overwrite finished"); 42 | die; 43 | } else { 44 | $this->error('Error in overwriting Repository!'); 45 | die; 46 | } 47 | } else { 48 | $this->modelName = $this->ask("Enter the Repository another file name? "); 49 | } 50 | } 51 | 52 | if (Repository::make($this->modelName)) { 53 | $this->info("Repository file: {$this->modelName} is created successfully."); 54 | die; 55 | } else { 56 | $this->error('Error in creating Repository!'); 57 | die; 58 | } 59 | } catch (\Exception $exception) { 60 | $this->error($exception); 61 | die; 62 | } 63 | 64 | return 0; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Console/Commands/MakeRepositoryProviderCommand.php: -------------------------------------------------------------------------------- 1 | name = trim(Str::studly($this->argument('name'))); 28 | 29 | $this->warn("Serivce Provider {$this->name} is creating..."); 30 | 31 | try { 32 | 33 | if (Repository::createProvider($this->name)) { 34 | $this->info("Service Provider: {$this->name} is created successfully."); 35 | } else { 36 | $msg = ' ""' . $this->name . '""' . " already exist. do you want create another?"; 37 | $confirm = $this->confirm($msg); 38 | if ($confirm) { 39 | $this->name = $this->ask("Enter the Provider name? "); 40 | if (Repository::createProvider($this->name)) { 41 | $this->info("Service Provider file: {$this->name} is created successfully."); 42 | } else { 43 | $this->error("error"); 44 | die; 45 | } 46 | } else { 47 | $this->warn("You must have a Provider for Repositories. create it"); 48 | die; 49 | } 50 | } 51 | } catch (\Exception $exception) { 52 | $this->error($exception); 53 | die; 54 | } 55 | 56 | return 0; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Console/Stubs/RepositoryInterface.stub: -------------------------------------------------------------------------------- 1 | repositories as $repository) { 23 | $this->app->bind($repository[0], $repository[1]); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Console/Stubs/repository.stub: -------------------------------------------------------------------------------- 1 | mergeConfigFrom(__DIR__ . "/../../config/repository.php", 'repository'); 16 | 17 | $this->registerFacades(); 18 | } 19 | 20 | public function boot() 21 | { 22 | if ($this->app->runningInConsole()) { 23 | 24 | $this->registerPublishes(); 25 | 26 | $this->registerCommands(); 27 | } 28 | } 29 | 30 | private function registerFacades() 31 | { 32 | $this->app->bind('repository', function ($app) { 33 | return new Repository(); 34 | }); 35 | } 36 | 37 | private function registerPublishes() 38 | { 39 | $this->publishes([ 40 | __DIR__ . '/../../config/repository.php' => config_path('repository.php') 41 | ], 'repository-config'); 42 | 43 | $this->publishes([ 44 | __DIR__ . '/../Console/Stubs' => resource_path('vendor/miladimos/repository/stubs'), 45 | ], 'repository-stubs'); 46 | } 47 | 48 | public function registerCommands() 49 | { 50 | $this->commands([ 51 | InstallPackageCommand::class, 52 | MakeRepositoryCommand::class, 53 | MakeRepositoryProviderCommand::class, 54 | ]); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Repositories/BaseRepository.php: -------------------------------------------------------------------------------- 1 | app = app(); 19 | 20 | $this->makeModel(); 21 | } 22 | 23 | abstract public function model(); 24 | 25 | final public function makeModel() 26 | { 27 | return $this->setModel($this->model()); 28 | } 29 | 30 | final public function setModel(Model $model) 31 | { 32 | $this->newInstanceModel = $this->app->make($model); 33 | 34 | if (!$this->newInstanceModel instanceof Model) 35 | throw new Exception("Class {$this->newInstanceModel} must be an instance of Illuminate\\Database\\Eloquent\\Model"); 36 | 37 | return $this->model = $this->newInstanceModel; 38 | } 39 | 40 | public function getModel(): Model 41 | { 42 | return $this->model; 43 | } 44 | 45 | public function all($columns = ['*']): object 46 | { 47 | return $this->model->all($columns); 48 | } 49 | 50 | public function create(array $data) 51 | { 52 | return $this->model->create($data); 53 | } 54 | 55 | public function update(array $data, $id, $attribute = "id") 56 | { 57 | $keys = ['_token', '_method', 'XDEBUG_SESSION_START']; 58 | foreach ($keys as $key) { 59 | if (array_key_exists($key, $data)) { 60 | unset($data[$key]); 61 | } 62 | } 63 | 64 | $updated = $this->model 65 | ->where($attribute, '=', $id) 66 | ->update($data); 67 | 68 | if (!$updated) { 69 | throw new Exception( 70 | "Update model {$this->model()} was unsuccessful" 71 | ); 72 | } 73 | 74 | return $updated; 75 | } 76 | 77 | public function find($id): object 78 | { 79 | return $this->model->find($id); 80 | } 81 | 82 | public function findOrFail($id): ?object 83 | { 84 | return $this->model->findOrFail($id); 85 | } 86 | 87 | public function findWhere(string $field, $condition, $columns) 88 | { 89 | return $this->model->where($field, $condition, $columns); 90 | } 91 | 92 | public function first(): object 93 | { 94 | return $this->model->first(); 95 | } 96 | 97 | public function last(): object 98 | { 99 | return $this->model->latest()->first(); 100 | } 101 | 102 | public function next($id): object 103 | { 104 | return $this->model->where('id', '>', $id)->orderBy('id')->first(); 105 | } 106 | 107 | public function before($id): object 108 | { 109 | return $this->model->where('id', '<', $id)->orderBy('id', 'desc')->first(); 110 | } 111 | 112 | public function firstOrCreate($attributes, $values) 113 | { 114 | return $this->model->firstOrCreate($attributes, $values); 115 | } 116 | 117 | public function whereIn($attribute, array $values) 118 | { 119 | return $this->model->whereIn($attribute, $values)->get(); 120 | } 121 | 122 | public function max($column) 123 | { 124 | return $this->model->max($column); 125 | } 126 | 127 | public function min($column) 128 | { 129 | return $this->model->min($column); 130 | } 131 | 132 | public function avg($column) 133 | { 134 | return $this->model->avg($column); 135 | } 136 | 137 | public function delete($id) 138 | { 139 | $status = $this->model->destroy($id); 140 | if (!$status and !is_array($id) and !empty($id)) { 141 | throw new Exception( 142 | "Unable to delete {$this->model()} with id: {$id}" 143 | ); 144 | } 145 | return $status; 146 | } 147 | 148 | public function truncate() 149 | { 150 | return $this->model->truncate(); 151 | } 152 | 153 | public function count($columns = ['*']): int 154 | { 155 | return $this->model->count($columns); 156 | } 157 | 158 | public function paginate($columns = ['*'], $perPage = 8) 159 | { 160 | return $this->model->paginate($perPage, $columns); 161 | } 162 | 163 | public function simplePaginate($limit = null, $columns = ['*']) 164 | { 165 | return $this->model->simplePaginate($limit, $columns); 166 | } 167 | 168 | public function search(array $query, $columns = ["*"]) 169 | { 170 | return $this->model->search($columns); 171 | } 172 | 173 | public function pluck($value, $key = null) 174 | { 175 | $lists = $this->model->pluck($value, $key); 176 | 177 | if (is_array($lists)) { 178 | return $lists; 179 | } 180 | 181 | return $lists->all(); 182 | } 183 | 184 | public function with($relations) 185 | { 186 | return $this->model->with($relations); 187 | } 188 | 189 | public function toSql() 190 | { 191 | return $this->model->toSql(); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/Repositories/IBaseEloquentRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | getRepositoryDefaultDirectory())) 69 | mkdir($path, 0777, true); 70 | 71 | self::createRepository($modelName); 72 | self::createInterface($modelName); 73 | 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Traits/GetStubs.php: -------------------------------------------------------------------------------- 1 | getRepositorySuffix($model) . '.php'); 14 | } 15 | 16 | protected function getRepositoryDefaultDirectory() 17 | { 18 | $repositoryNamespace = config('repository.repositories_namespace') ?? 'Repositories'; 19 | return app_path($repositoryNamespace); 20 | } 21 | 22 | protected static function getRepositoryDefaultNamespace($full = true) 23 | { 24 | $appNamespace = config('repository.base_app_namespace') ?? 'App'; 25 | $repositoryNamespace = config('repository.repositories_namespace') ?? 'Repositories'; 26 | if ($full) 27 | return $appNamespace . '\\' . $repositoryNamespace . ';'; 28 | 29 | return $appNamespace . '\\' . $repositoryNamespace; 30 | } 31 | 32 | protected static function getRepositorySuffix($model) 33 | { 34 | $repotisorySuffix = config('repositories.repositories_suffix') ?? 'Repository'; 35 | return $model . $repotisorySuffix; 36 | } 37 | 38 | protected static function getRepositoryInterfaceSuffix($model) 39 | { 40 | $interfaceSuffix = config('repositories.interfaces_suffix') ?? 'Interface'; 41 | return $model . $interfaceSuffix; 42 | } 43 | 44 | protected static function getModelClassName($model) 45 | { 46 | return trim(Str::studly($model)); 47 | } 48 | 49 | protected static function getModelNamespace($model) 50 | { 51 | $appNamespace = config('repository.base_app_namespace') ?? 'App'; 52 | $modelNamespace = config('repository.models_namespace') ?? 'Models'; 53 | 54 | return $appNamespace . '\\' . $modelNamespace . '\\' . $model . ';'; 55 | } 56 | 57 | protected static function getModelPath($model) 58 | { 59 | $modelNamespace = config('repository.models_namespace') ?? 'Models'; 60 | 61 | return app_path($modelNamespace . '//' . $model); 62 | } 63 | 64 | protected static function getInterfaceNamespace($model) 65 | { 66 | $appNamespace = config('repository.base_app_namespace') ?? 'App'; 67 | $repositoryNamespace = config('repository.repository_namespace') ?? 'Repositories'; 68 | 69 | return $appNamespace . '\\' . $repositoryNamespace . '\\' . $model; 70 | } 71 | 72 | protected static function getRepositoryInterfaceNamespace($model) 73 | { 74 | $appNamespace = config('repository.base_app_namespace') ?? 'App'; 75 | $repositoryNamespace = config('repository.repository_namespace') ?? 'Repositories'; 76 | 77 | return $appNamespace . '\\' . $repositoryNamespace . '\\' . $model . '\\' . $model; 78 | } 79 | 80 | protected static function getRepositoryNamespace($model) 81 | { 82 | $appNamespace = config('repository.base_app_namespace') ?? 'App'; 83 | $repositoryNamespace = config('repository.repository_namespace') ?? 'Repositories'; 84 | 85 | return $appNamespace . '\\' . $repositoryNamespace . '\\' . $model; 86 | } 87 | 88 | protected static function getRepositoryServiceProviderPath($providerName) 89 | { 90 | $ds = DIRECTORY_SEPARATOR; 91 | return app_path("Providers{$ds}{$providerName}.php"); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Traits/Validation.php: -------------------------------------------------------------------------------- 1 | getRepositoryPath($model))) { 10 | return true; 11 | } 12 | 13 | return false; 14 | } 15 | 16 | public static function ensureRepositoryServiceProviderDoesntAlreadytExist($providerName) 17 | { 18 | if (file_exists(self::getRepositoryServiceProviderPath($providerName))) { 19 | return false; 20 | } 21 | 22 | return true; 23 | } 24 | } 25 | --------------------------------------------------------------------------------