├── .gitignore ├── README.md ├── composer.json ├── config └── repository.php ├── src ├── Console │ └── Commands │ │ ├── MakeAbstractRepositoryCommand.php │ │ ├── MakeRepositoryCommand.php │ │ └── RepositoryInstallCommand.php ├── Constants │ ├── AppConstants.php │ └── ErrorConstants.php ├── Contracts │ ├── FileContract.php │ └── RepositoryInterface.php ├── Eloquent │ └── AbstractRepository.php ├── Exceptions │ ├── BaseException.php │ └── RepositoryException.php ├── Helpers │ └── helpers.php ├── RepositoryServiceProvider.php ├── Services │ └── FileService.php ├── Support │ ├── Facades │ │ └── JetBoxFile.php │ └── Utility.php └── Traits │ ├── EnvironmentTrait.php │ └── Translatable.php └── stubs ├── abstract-repository.stub └── repository.stub /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | composer.lock 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Repository 2 | 3 | ![Laravel Repository - Social Image](https://banners.beyondco.de/Laravel%20Repository.png?theme=light&packageManager=composer+require&packageName=jetbox%2Flaravel-repository&pattern=architect&style=style_1&description=Laravel+Repository+Package&md=1&showWatermark=1&fontSize=100px&images=https%3A%2F%2Flaravel.com%2Fimg%2Flogomark.min.svg) 4 | 5 | Laravel Version Support 6 | 7 | - > `^5.5` `^6.0` `^7.0` `^8.0` `^9.0` `^10.0` `^11.0` 8 | 9 | Php Version Support 10 | 11 | - > `^7.0` `^8.0` 12 | 13 | [![Latest Stable Version](https://poser.pugx.org/jetbox/laravel-repository/v)](//packagist.org/packages/jetbox/laravel-repository) 14 | [![Total Downloads](https://poser.pugx.org/jetbox/laravel-repository/downloads)](//packagist.org/packages/jetbox/laravel-repository) 15 | [![Latest Unstable Version](https://poser.pugx.org/jetbox/laravel-repository/v/unstable)](//packagist.org/packages/jetbox/laravel-repository) 16 | [![License](https://poser.pugx.org/jetbox/laravel-repository/license)](//packagist.org/packages/jetbox/laravel-repository) 17 | 18 | [![Daily Downloads](https://poser.pugx.org/jetbox/laravel-repository/d/daily)](//packagist.org/packages/jetbox/laravel-repository) 19 | [![Monthly Downloads](https://poser.pugx.org/jetbox/laravel-repository/d/monthly)](//packagist.org/packages/jetbox/laravel-repository) 20 | [![Total Downloads](https://poser.pugx.org/jetbox/laravel-repository/downloads)](//packagist.org/packages/jetbox/laravel-repository) 21 | 22 | [![Issues](https://img.shields.io/github/issues/DavitMnacakanyan/laravel-repository)](https://github.com/DavitMnacakanyan/laravel-repository/issues) 23 | [![Stars](https://img.shields.io/github/stars/DavitMnacakanyan/laravel-repository)](https://github.com/DavitMnacakanyan/laravel-repository/stargazers) 24 | [![Forks](https://img.shields.io/github/forks/DavitMnacakanyan/laravel-repository)](https://github.com/DavitMnacakanyan/laravel-repository/network/members) 25 | 26 | ## Table of Contents 27 | 28 | - Installation 29 | - Composer 30 | - Command 31 | - Methods 32 | - Usage 33 | - Create a Repository 34 | - Use methods 35 | 36 | ## Installation 37 | 38 | ### Composer 39 | 40 | Execute the following command to get the latest version of the package: 41 | 42 | ```terminal 43 | composer require jetbox/laravel-repository 44 | ``` 45 | 46 | ### Repository Install 47 | 48 | ```terminal 49 | php artisan repository:install 50 | ``` 51 | 52 | ### Create Repository 53 | 54 | Create a new Eloquent model repository class 55 | 56 | ```terminal 57 | php artisan make:repository UserRepository 58 | ``` 59 | 60 | ## Methods 61 | 62 | ### JetBox\Repositories\Contracts\RepositoryInterface 63 | 64 | - get($columns = ['*'], $take = false, $pagination = false, $where = false); 65 | - all($columns = ['*']); 66 | - take($take, $columns = ['*']); 67 | - paginate($perPage = false, $columns = ['*']); 68 | - withPaginate($relations, $columns = ['*'], $paginate = 15); 69 | - simplePaginate($perPage = false, $columns = ['*']); 70 | - limit($take, $columns = ['*']); 71 | - find($id, $columns = ['*']); 72 | - findMany($ids, $columns = ['*']); 73 | - findOrFail($id, $columns = ['*']); 74 | - first($columns = ['*']); 75 | - firstOrFail($columns = ['*']); 76 | - where($column, $value = null, $columns = ['*']); 77 | - whereOrFail($column, $value = null, $columns = ['*']); 78 | - whereAll($column, $value = null, $columns = ['*']); 79 | - whereWithAll($column, $value = null, $relations, $columns = ['*']); 80 | - whereBetween($column, $value = [], $columns = ['*']); 81 | - with($relations, $columns = ['*']); 82 | - withCount($relations, $columns = ['*']); 83 | - pluck($column, $key = null); 84 | - create(array $attributes); 85 | - forceCreate(array $attributes); 86 | - update(array $attributes, $model, bool $tap = false, bool $forceFill = false); 87 | - updateForce(array $attributes, $model, bool $tap = false); 88 | - delete($model, bool $tap = false, bool $forceDelete = false); 89 | - forceDelete($model, bool $tap = false); 90 | - querySortable(string $orderByColumn, string $orderByDirection) 91 | 92 | ## Helpers 93 | 94 | - lLog(string $message, string $log = 'info', array $context = [], string $disk = null) 95 | - is_json(string $str, bool $returnData = false) 96 | - currentUser(): ?Authenticatable 97 | - numberFormatShort($n, int $precision = 2) 98 | 99 | ## EnvironmentTrait 100 | ```php 101 | use JetBox\Repositories\Traits\EnvironmentTrait 102 | ``` 103 | - changeEnvironmentVariable(string $key, $value): void 104 | - environmentVariableAllUpdate(array $data): void 105 | 106 | ## Translatable 107 | ```php 108 | use JetBox\Repositories\Traits\Translatable 109 | ``` 110 | - withTranslations(Builder $query, $locales = null, $fallback = true): void 111 | - getTranslated($attribute, $locale = null, $fallback = true) 112 | 113 | ## File Facade 114 | - JetBoxFile::save(string $path, object $file, string $fileName = null, array $options = []) 115 | - JetBoxFile::delete(Model $model, string $field, string $path) 116 | - JetBoxFile::numberFormatSizeUnits(int $sizeInBytes) 117 | 118 | ## Constants 119 | - AppConstants::permissions(): array 120 | - AppConstants::roles(): array 121 | - AppConstants::status(): array 122 | ```php 123 | namespace App\Constants; 124 | 125 | use JetBox\Repositories\Constants\AppConstants as BaseAppConstants; 126 | 127 | final class AppConstants extends BaseAppConstants 128 | { 129 | const ROLE_VISITOR = 'visitor'; 130 | const ROLE_EDITOR = 'editor'; 131 | 132 | const PERMISSION_VIEW_BLOG = 'view_blog'; 133 | } 134 | ``` 135 | 136 | ## Usage 137 | 138 | ### Create a Repository 139 | 140 | > #### Recommended This Shorter 141 | > Laravel `^5.7` `^6.0` `^7.0` `^8.0` 142 | > if your model is not linked to the repository auto, you can override the `$model` property of your repository 143 | 144 | ```php 145 | namespace App\Repositories; 146 | 147 | class UserRepository extends AbstractRepository 148 | { 149 | 150 | } 151 | ``` 152 | 153 | ### Or 154 | 155 | > Laravel `^5.2` `<=5.6` override the `$model` property 156 | 157 | ```php 158 | namespace App\Repositories; 159 | 160 | use App\Models\User; 161 | 162 | class UserRepository extends AbstractRepository 163 | { 164 | /** 165 | * @var string 166 | */ 167 | protected $model = User::class; 168 | 169 | /** 170 | * Global OrderBy Column 171 | * @var string 172 | */ 173 | public $orderByColumn = 'created_at'; 174 | 175 | /** 176 | * Global OrderBy Direction 177 | * @var string 178 | */ 179 | public $orderByDirection = 'desc'; 180 | } 181 | ``` 182 | 183 | ### Use methods 184 | 185 | ```php 186 | namespace App\Http\Controllers; 187 | 188 | use Illuminate\Contracts\Foundation\Application; 189 | use Illuminate\Contracts\View\Factory; 190 | use Illuminate\View\View; 191 | use App\Repositories\UserRepository as UserR; 192 | 193 | class UserController extends BaseController { 194 | 195 | /** 196 | * @var $users 197 | */ 198 | protected $users; 199 | 200 | /** 201 | * UserController constructor. 202 | * @param UserR $users 203 | */ 204 | public function __construct(UserR $users) 205 | { 206 | $this->users = $users; 207 | } 208 | 209 | /** 210 | * @return Application|Factory|View 211 | */ 212 | public function index() 213 | { 214 | $users = $this->users->all(); 215 | 216 | return view('users', compact('users')); 217 | } 218 | 219 | } 220 | ``` 221 | 222 | Find all results in Repository 223 | 224 | ```php 225 | $users = $this->users->all(); 226 | ``` 227 | 228 | Find by result by id 229 | 230 | ```php 231 | $user = $this->users->find($id); 232 | ``` 233 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jetbox/laravel-repository", 3 | "description": "Laravel Repository Package", 4 | "keywords": [ 5 | "laravel", 6 | "repository" 7 | ], 8 | "type": "library", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Davit Mnacakanyan", 13 | "email": "davitmnacakanyan055@gmail.com" 14 | } 15 | ], 16 | "require": { 17 | "php": "^7.0|^8.0", 18 | "laravel/framework": "^5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "JetBox\\Repositories\\": "src" 23 | }, 24 | "files": [ 25 | "src/Helpers/helpers.php" 26 | ] 27 | }, 28 | "extra": { 29 | "laravel": { 30 | "providers": [ 31 | "JetBox\\Repositories\\RepositoryServiceProvider" 32 | ], 33 | "aliases": { 34 | "JetBoxFile": "JetBox\\Repositories\\Support\\Facades\\JetBoxFile" 35 | } 36 | } 37 | }, 38 | "minimum-stability": "dev", 39 | "prefer-stable": true 40 | } 41 | -------------------------------------------------------------------------------- /config/repository.php: -------------------------------------------------------------------------------- 1 | 'App\\Models', 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Repository Folder Path 19 | |-------------------------------------------------------------------------- 20 | | 21 | | App\\Repositories 22 | | 23 | */ 24 | 25 | 'repository_namespace' => 'App\\Repositories', 26 | ]; 27 | -------------------------------------------------------------------------------- /src/Console/Commands/MakeAbstractRepositoryCommand.php: -------------------------------------------------------------------------------- 1 | makeAbstractRepository(); 68 | 69 | return $this->checkRepositoryName($stub); 70 | } 71 | 72 | /** 73 | * @param $stub 74 | * @return array|string|string[]|void 75 | */ 76 | protected function checkRepositoryName($stub) 77 | { 78 | $repository = substr($this->getNameInput(), -strlen($this->type)); 79 | 80 | if ($repository) { 81 | $modelName = substr($this->getNameInput(), 0, -strlen($this->type)); 82 | $modelName = Str::singular($modelName); 83 | $modelNamespace = config('repository.model_namespace') . '\\' . $modelName; 84 | 85 | $stub = str_replace('DummyModelNamespace', $modelNamespace, $stub); 86 | $stub = str_replace('DummyModelClass', $modelName, $stub); 87 | 88 | return $stub; 89 | } 90 | 91 | $this->error('Error Repository must finish the name of the Repository Example {Model}{Repository}'); 92 | } 93 | 94 | /** 95 | * @return void 96 | */ 97 | protected function makeAbstractRepository(): void 98 | { 99 | $str = config('repository.repository_namespace'); 100 | $str = str_replace('A', 'a', $str); 101 | $str = base_path("$str/AbstractRepository.php"); 102 | $str = str_replace('\\', '/', $str); 103 | 104 | if (!file_exists($str)) { 105 | $this->call('make:abstract-repository', [ 106 | 'name' => 'AbstractRepository' 107 | ]); 108 | } 109 | } 110 | 111 | /** 112 | * @return array[] 113 | */ 114 | protected function getArguments(): array 115 | { 116 | return [ 117 | ['name', InputArgument::REQUIRED, 'The name of the repository class'], 118 | ]; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Console/Commands/RepositoryInstallCommand.php: -------------------------------------------------------------------------------- 1 | info('Publishing the Repository config, and make AbstractRepository'); 42 | 43 | $this->call('vendor:publish', [ 44 | '--provider' => RepositoryServiceProvider::class 45 | ]); 46 | 47 | $this->call('make:abstract-repository', [ 48 | 'name' => 'AbstractRepository' 49 | ]); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Constants/AppConstants.php: -------------------------------------------------------------------------------- 1 | getConstants(); 47 | 48 | $values = array_filter($constants, function ($key, $name) use ($constantName) { 49 | return strpos($name, mb_strtoupper($constantName)) === 0; 50 | }, ARRAY_FILTER_USE_BOTH); 51 | 52 | return array_values($values); 53 | } 54 | 55 | /** 56 | * @return array 57 | */ 58 | public static function permissions(): array 59 | { 60 | return static::getConstants('permission'); 61 | } 62 | 63 | /** 64 | * @return array 65 | */ 66 | public static function status(): array 67 | { 68 | return static::getConstants('status'); 69 | } 70 | 71 | /** 72 | * @return array 73 | */ 74 | public static function roles(): array 75 | { 76 | return static::getConstants('role'); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Constants/ErrorConstants.php: -------------------------------------------------------------------------------- 1 | getNamespace(); 45 | } catch (Exception $exception) { 46 | return 'App\\'; 47 | } 48 | } 49 | 50 | /** 51 | * @return mixed 52 | */ 53 | public function newModel() 54 | { 55 | $model = $this->modelName(); 56 | 57 | return new $model; 58 | } 59 | 60 | /** 61 | * @return bool|Closure|mixed 62 | */ 63 | public function modelName() 64 | { 65 | $resolver = static::$modelNameResolver ?: function (self $model) { 66 | 67 | $modelBaseName = Str::replaceLast('Repository', '', class_basename($model)); 68 | 69 | $appNamespace = static::getNamespace(); 70 | 71 | return class_exists($appNamespace.'Models\\'.$modelBaseName) 72 | ? $appNamespace.'Models\\'.$modelBaseName 73 | : $appNamespace.$modelBaseName; 74 | }; 75 | 76 | return $this->model ?: $resolver($this); 77 | } 78 | 79 | /** 80 | * @param callable $resolver 81 | */ 82 | public static function modelNameResolver(callable $resolver) 83 | { 84 | static::$modelNameResolver = $resolver; 85 | } 86 | 87 | /** 88 | * @param string $orderByColumn 89 | * @param string $orderByDirection 90 | */ 91 | public function querySortable(string $orderByColumn, string $orderByDirection): void 92 | { 93 | $this->orderByColumn = $orderByColumn; 94 | $this->orderByDirection = $orderByDirection; 95 | } 96 | 97 | /** 98 | * @return mixed 99 | * @throws RepositoryException 100 | */ 101 | public function orderBy() 102 | { 103 | if ($this->orderByDirection === 'desc') { 104 | return $this->newModel()->latest($this->orderByColumn); 105 | } 106 | 107 | if ($this->orderByDirection === 'asc') { 108 | return $this->newModel()->oldest($this->orderByColumn); 109 | } 110 | 111 | throw RepositoryException::orderByDirection($this); 112 | } 113 | 114 | /** 115 | * @param int|object $model 116 | * @return mixed 117 | */ 118 | private function findModel($model) 119 | { 120 | if (is_int($model)) 121 | return $this->find($model); 122 | 123 | return $model; 124 | } 125 | 126 | /** 127 | * @param string[] $columns 128 | * @param false $take 129 | * @param false $pagination 130 | * @param array $where 131 | * @return mixed 132 | */ 133 | public function get($columns = ['*'], $take = false, $pagination = false, array $where = []) 134 | { 135 | $builder = $this->orderBy(); 136 | 137 | if ($take) { 138 | $builder->take($take); 139 | } 140 | 141 | if ($pagination) { 142 | return $builder->paginate($pagination); 143 | } 144 | 145 | if ($where) { 146 | $builder->where($where); 147 | } 148 | 149 | return $builder->get($columns); 150 | } 151 | 152 | /** 153 | * @param string[] $columns 154 | * @return mixed 155 | */ 156 | public function all($columns = ['*']) 157 | { 158 | return $this 159 | ->orderBy() 160 | ->get($columns); 161 | } 162 | 163 | /** 164 | * @param $take 165 | * @param string[] $columns 166 | * @return mixed 167 | */ 168 | public function take($take, $columns = ['*']) 169 | { 170 | return $this 171 | ->orderBy() 172 | ->take($take) 173 | ->get($columns); 174 | } 175 | 176 | /** 177 | * @param false $perPage 178 | * @param string[] $columns 179 | * @return mixed 180 | */ 181 | public function paginate($perPage = false, $columns = ['*']) 182 | { 183 | return $this 184 | ->orderBy() 185 | ->paginate($perPage, $columns); 186 | } 187 | 188 | /** 189 | * @param $relations 190 | * @param string[] $columns 191 | * @param int $paginate 192 | * @return mixed 193 | */ 194 | public function withPaginate($relations, $columns = ['*'], $paginate = 15) 195 | { 196 | return $this 197 | ->orderBy() 198 | ->with($relations) 199 | ->paginate($paginate); 200 | } 201 | 202 | /** 203 | * @param false $perPage 204 | * @return mixed 205 | */ 206 | public function simplePaginate($perPage = false, $columns = ['*']) 207 | { 208 | return $this 209 | ->orderBy() 210 | ->simplePaginate($perPage, $columns); 211 | } 212 | 213 | /** 214 | * @param $take 215 | * @param string[] $columns 216 | * @return mixed 217 | */ 218 | public function limit($take, $columns = ['*']) 219 | { 220 | return $this 221 | ->orderBy() 222 | ->limit($take) 223 | ->get($columns); 224 | } 225 | 226 | /** 227 | * @param $id 228 | * @param string[] $columns 229 | * @return mixed 230 | */ 231 | public function find($id, $columns = ['*']) 232 | { 233 | return $this->model->find($id, $columns); 234 | } 235 | 236 | /** 237 | * @param $ids 238 | * @param string[] $columns 239 | * @return mixed 240 | */ 241 | public function findMany($ids, $columns = ['*']) 242 | { 243 | return $this 244 | ->orderBy() 245 | ->findMany($ids, $columns); 246 | } 247 | 248 | /** 249 | * @param $id 250 | * @param string[] $columns 251 | * @return mixed 252 | */ 253 | public function findOrFail($id, $columns = ['*']) 254 | { 255 | return $this->model->findOrFail($id, $columns); 256 | } 257 | 258 | /** 259 | * @param string[] $columns 260 | * @return mixed 261 | */ 262 | public function first($columns = ['*']) 263 | { 264 | return $this->model->first($columns); 265 | } 266 | 267 | /** 268 | * @param string[] $columns 269 | * @return mixed 270 | */ 271 | public function firstOrFail($columns = ['*']) 272 | { 273 | return $this->model->firstOrFail($columns); 274 | } 275 | 276 | /** 277 | * @param Closure|string|array|Expression $column 278 | * @param null $value 279 | * @param string[] $columns 280 | * @return mixed 281 | */ 282 | public function where($column, $value = null, $columns = ['*']) 283 | { 284 | return $this 285 | ->model 286 | ->where($column, $value) 287 | ->first($columns); 288 | } 289 | 290 | /** 291 | * @param Closure|string|array|Expression $column 292 | * @param null $value 293 | * @param string[] $columns 294 | * @return mixed 295 | */ 296 | public function whereOrFail($column, $value = null, $columns = ['*']) 297 | { 298 | return $this 299 | ->model 300 | ->where($column, $value) 301 | ->firstOrFail($columns); 302 | } 303 | 304 | /** 305 | * @param Closure|string|array|Expression $column 306 | * @param null $value 307 | * @param string[] $columns 308 | * @return mixed 309 | */ 310 | public function whereAll($column, $value = null, $columns = ['*']) 311 | { 312 | return $this 313 | ->orderBy() 314 | ->where($column, $value) 315 | ->get($columns); 316 | } 317 | 318 | /** 319 | * @param $column 320 | * @param $relations 321 | * @param null $value 322 | * @param string[] $columns 323 | * @return mixed 324 | */ 325 | public function whereWithAll($column, $relations, $value = null, $columns = ['*']) 326 | { 327 | return $this 328 | ->orderBy() 329 | ->where($column, $value) 330 | ->with($relations) 331 | ->get($columns); 332 | } 333 | 334 | /** 335 | * @param string|Expression $column 336 | * @param array $value 337 | * @param string[] $columns 338 | * @return mixed 339 | */ 340 | public function whereBetween($column, $value = [], $columns = ['*']) 341 | { 342 | return $this 343 | ->orderBy() 344 | ->whereBetween($column, $value) 345 | ->get($columns); 346 | } 347 | 348 | /** 349 | * @param $relations 350 | * @param string[] $columns 351 | * @return mixed 352 | */ 353 | public function with($relations, $columns = ['*']) 354 | { 355 | return $this 356 | ->orderBy() 357 | ->with($relations) 358 | ->get($columns); 359 | } 360 | 361 | /** 362 | * @param $relations 363 | * @param string[] $columns 364 | * @return mixed 365 | */ 366 | public function withCount($relations, $columns = ['*']) 367 | { 368 | return $this 369 | ->orderBy() 370 | ->withCount($relations) 371 | ->get($columns); 372 | } 373 | 374 | /** 375 | * @param $column 376 | * @param null $key 377 | * @return mixed|void 378 | */ 379 | public function pluck($column, $key = null) 380 | { 381 | return $this->model->pluck($column, $key); 382 | } 383 | 384 | /** 385 | * @param array $attributes 386 | * @return mixed 387 | */ 388 | public function create(array $attributes) 389 | { 390 | return $this->model->create($attributes); 391 | } 392 | 393 | /** 394 | * @param array $attributes 395 | * @return mixed 396 | */ 397 | public function forceCreate(array $attributes) 398 | { 399 | return $this->model->forceCreate($attributes); 400 | } 401 | 402 | /** 403 | * @param array $attributes 404 | * @param int|object $model 405 | * @param bool $tap 406 | * @param bool $forceFill 407 | * @return mixed 408 | */ 409 | public function update(array $attributes, $model, bool $tap = false, bool $forceFill = false) 410 | { 411 | $model = $this->findModel($model); 412 | 413 | if ($tap) 414 | $model = tap($model); 415 | if ($forceFill) 416 | $model->forceFill($attributes); 417 | else 418 | $model->fill($attributes); 419 | 420 | return $model->update(); 421 | } 422 | 423 | /** 424 | * @param array $attributes 425 | * @param int|object $model 426 | * @param bool $tap 427 | * @return mixed 428 | * 429 | * forceFill 430 | */ 431 | public function updateForce(array $attributes, $model, bool $tap = false) 432 | { 433 | return $this->update($attributes, $model, $tap, true); 434 | } 435 | 436 | /** 437 | * @param int|object $model 438 | * @param bool $tap 439 | * @param bool $forceDelete 440 | * @return mixed 441 | */ 442 | public function delete($model, bool $tap = false, bool $forceDelete = false) 443 | { 444 | $model = $this->findModel($model); 445 | 446 | if ($tap) 447 | $model = tap($model); 448 | if ($forceDelete) 449 | return $model->forceDelete(); 450 | 451 | return $model->delete(); 452 | } 453 | 454 | /** 455 | * @param int|object $model 456 | * @param bool $tap 457 | * @return mixed 458 | */ 459 | public function forceDelete($model, bool $tap = false) 460 | { 461 | return $this->delete($model, $tap, true); 462 | } 463 | 464 | /** 465 | * @param array $attribute 466 | * @param bool $tap 467 | * @return mixed 468 | */ 469 | public function save(array $attribute = [], bool $tap = false) 470 | { 471 | $model = $this->newModel()->fill($attribute); 472 | 473 | if ($tap) $model = tap($model); 474 | 475 | return $model->save(); 476 | } 477 | } 478 | -------------------------------------------------------------------------------- /src/Exceptions/BaseException.php: -------------------------------------------------------------------------------- 1 | getMessage(), 'error', [ 16 | 'code' => $this->getCode(), 17 | 'line' => $this->getLine(), 18 | 'function' => $this->getTrace()[0]['function'], 19 | 'file' => $this->getFile(), 20 | 'type' => $this->getTrace()[0]['type'], 21 | ]); 22 | } 23 | 24 | /** 25 | * @param string|null $type 26 | * @return JsonResponse 27 | */ 28 | public function responseError(string $type = null): JsonResponse 29 | { 30 | $errorResponse = [ 31 | 'status' => 'error', 32 | 'message' => $this->getMessage(), 33 | 'type' => $type 34 | ]; 35 | $statusCode = $this->getCode(); 36 | 37 | return response()->json($errorResponse, $statusCode); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Exceptions/RepositoryException.php: -------------------------------------------------------------------------------- 1 | orderByDirection' ${message}"; 17 | 18 | return new self ($errorMessage); 19 | } 20 | 21 | /** 22 | * Report Error Log File 23 | */ 24 | public function report(): void 25 | { 26 | $this->reportError(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Helpers/helpers.php: -------------------------------------------------------------------------------- 1 | user(); 15 | } 16 | } 17 | 18 | if (! function_exists('is_json')) { 19 | /** 20 | * is json 21 | * 22 | * @param string $str 23 | * @param bool $returnData 24 | * @return bool|mixed 25 | */ 26 | function is_json(string $str, bool $returnData = false) 27 | { 28 | return Utility::is_json($str, $returnData); 29 | } 30 | } 31 | 32 | if (! function_exists('lLog')) { 33 | /** 34 | * 'emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug' 35 | * 36 | * @param string $message 37 | * @param string $log 38 | * @param array $context 39 | * @param string|null $disk 40 | * @return void 41 | */ 42 | function lLog(string $message, string $log = 'info', array $context = [], string $disk = null): void 43 | { 44 | logger()->driver($disk)->{$log}($message, $context); 45 | } 46 | } 47 | 48 | if (! function_exists('numberFormatShort')) { 49 | /** 50 | * 3560 -> "3.56K" 51 | * 52 | * @param $n 53 | * @param int $precision 54 | * @return void 55 | */ 56 | function numberFormatShort($n, int $precision = 2): string 57 | { 58 | return Utility::numberFormatShort($n, $precision); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/RepositoryServiceProvider.php: -------------------------------------------------------------------------------- 1 | makeFileService(); 22 | } 23 | 24 | /** 25 | * Bootstrap services. 26 | * 27 | * @return void 28 | */ 29 | public function boot() 30 | { 31 | $this->publishes([ 32 | __DIR__ . '/../config/repository.php' => config_path('repository.php') 33 | ], 'repository-config'); 34 | 35 | $this->mergeConfigFrom(__DIR__ . '/../config/repository.php', 'repository'); 36 | 37 | if ($this->app->runningInConsole()) { 38 | $this->commands([ 39 | MakeAbstractRepositoryCommand::class, 40 | MakeRepositoryCommand::class, 41 | RepositoryInstallCommand::class 42 | ]); 43 | } 44 | } 45 | 46 | /** 47 | * File Contract 48 | */ 49 | private function makeFileService() 50 | { 51 | $this->app->singleton(FileContract::class, function ($app) { 52 | return new FileService(); 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Services/FileService.php: -------------------------------------------------------------------------------- 1 | hashName($file); 18 | return Storage::disk($disk)->putFileAs($path, $file, $name, $options); 19 | } 20 | 21 | /** 22 | * @param object $file 23 | * @return string 24 | */ 25 | private function hashName(object $file): string 26 | { 27 | $str = Str::random(40); 28 | 29 | $extension = '.' . $file->guessExtension(); 30 | 31 | return $str . $extension; 32 | } 33 | 34 | /** 35 | * @param Model $model 36 | * @param string $field 37 | * @param string $path 38 | * @param string $disk 39 | * @return bool|null 40 | */ 41 | public function delete(Model $model, string $field, string $path, string $disk = 'public'): ?bool 42 | { 43 | if (is_null($model->{$field})) return null; 44 | 45 | $mediaPath = "$path/{$model->{$field}}"; 46 | $mediaExists = Storage::disk($disk)->exists($mediaPath); 47 | 48 | if ($mediaExists) return Storage::disk($disk)->delete($mediaPath); 49 | 50 | return false; 51 | } 52 | 53 | /** 54 | * @param int $sizeInBytes 55 | * @return string 56 | */ 57 | public function numberFormatSizeUnits(int $sizeInBytes): string 58 | { 59 | $units = ['B', 'KB', 'MB', 'GB', 'TB']; 60 | 61 | if ($sizeInBytes == 0) { 62 | return '0 '.$units[1]; 63 | } 64 | 65 | for ($i = 0; $sizeInBytes > 1024; $i++) { 66 | $sizeInBytes /= 1024; 67 | } 68 | 69 | return round($sizeInBytes, 2).' '.$units[$i]; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Support/Facades/JetBoxFile.php: -------------------------------------------------------------------------------- 1 | "3.56K" 35 | */ 36 | public static function numberFormatShort($n, int $precision = 2): string 37 | { 38 | if ($n < 900) 39 | $format = number_format($n, $precision); // 0 - 900 40 | elseif ($n < 900000) 41 | $format = number_format($n / 1000, $precision) . 'K'; // 0.9k-850k 42 | elseif ($n < 900000000) 43 | $format = number_format($n / 1000000, $precision) . 'M'; // 0.9m-850m 44 | elseif ($n < 900000000000) 45 | $format = number_format($n / 1000000000, $precision) . 'B'; // 0.9b-850b 46 | else 47 | $format = number_format($n / 1000000000000, $precision) . 'T'; // 0.9t+ 48 | 49 | if ($precision > 0) 50 | $dotZero = '.' . str_repeat('0', $precision); 51 | 52 | return str_replace($dotZero, '', $format); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Traits/EnvironmentTrait.php: -------------------------------------------------------------------------------- 1 | environmentVariableModified($key, $value); 19 | 20 | $contents = str_replace($oldValue, $newValue, $getContents); 21 | file_put_contents($path, $contents); 22 | } 23 | 24 | /** 25 | * @param string $key 26 | * @param $value 27 | * @return string[] 28 | */ 29 | private function environmentVariableModified(string $key, $value): array 30 | { 31 | $key = Str::upper($key); 32 | $old = env($key); 33 | 34 | $oldValue = "$key=$old"; 35 | $newValue = "$key=$value"; 36 | 37 | return [$oldValue, $newValue]; 38 | } 39 | 40 | /** 41 | * @param array $data 42 | */ 43 | public function environmentVariableAllUpdate(array $data): void 44 | { 45 | $path = base_path('.env'); 46 | file_put_contents($path, $data); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Traits/Translatable.php: -------------------------------------------------------------------------------- 1 | getLocales($locales, $fallback); 19 | 20 | $query->with(['translations' => function (Relation $q) use ($locales, $fallback) { 21 | 22 | if (is_array($locales)) { 23 | $q->whereIn('locale', $locales); 24 | } else { 25 | $q->where('locale', $locales); 26 | } 27 | 28 | if ($fallback !== false) { 29 | $q->orWhere('locale', $fallback); 30 | } 31 | }]); 32 | } 33 | 34 | /** 35 | * @param $attribute 36 | * @param null $locale 37 | * @param bool $fallback 38 | * @return mixed|null 39 | */ 40 | public function getTranslated($attribute, $locale = null, $fallback = true) 41 | { 42 | if (!in_array($attribute, $this->getTranslatableAttributes())) { 43 | return $this->getAttribute($attribute); 44 | } 45 | 46 | list($locale, $fallback) = $this->getLocales($locale, $fallback); 47 | 48 | if (!$this->relationLoaded('translations')) { 49 | $this->load('translations'); 50 | } 51 | 52 | $translations = $this->getRelation('translations') 53 | ->where('column_name', $attribute); 54 | 55 | $localeTranslation = $translations->where('locale', $locale)->first(); 56 | 57 | if ($localeTranslation && $localeTranslation->value) { 58 | return $localeTranslation->value; 59 | } 60 | 61 | $fallbackTranslation = $translations->where('locale', $fallback)->first(); 62 | 63 | if ($fallbackTranslation && $fallback !== false) { 64 | return $fallbackTranslation->value; 65 | } 66 | 67 | return null; 68 | } 69 | 70 | /** 71 | * @param $locales 72 | * @param $fallback 73 | * @return array 74 | */ 75 | public function getLocales($locales, $fallback): array 76 | { 77 | if (is_null($locales)) { 78 | $locales = app()->getLocale(); 79 | } 80 | 81 | if ($fallback === true) { 82 | $fallback = config('app.fallback_locale', 'en'); 83 | } 84 | 85 | return [$locales, $fallback]; 86 | } 87 | 88 | /** 89 | * @return array 90 | */ 91 | public function getTranslatableAttributes(): array 92 | { 93 | return property_exists($this, 'translatable') ? $this->translatable : []; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /stubs/abstract-repository.stub: -------------------------------------------------------------------------------- 1 |