├── .gitignore ├── stubs ├── show.stub ├── index.stub ├── lang.stub ├── create.stub ├── edit.stub ├── Entity.stub ├── Interface.stub ├── fields-input.stub ├── fields-textArea.stub ├── Resource.stub ├── Repository.stub ├── Request.stub └── Controller.stub ├── src ├── Forms │ ├── Select.php │ ├── Input.php │ ├── TextArea.php │ ├── Forms.php │ └── FormGenerator.php ├── Utility │ ├── JsonResource.php │ ├── Entity.php │ ├── Request.php │ ├── ContractInterface.php │ ├── AbstractRepository.php │ └── Controller.php ├── lang │ └── repository-generator.php ├── config │ └── repository.php ├── GeneratorServiceProvider.php ├── Commands │ ├── Remover.php │ └── Generator.php └── RepositoryServiceProvider.php ├── LICENSE ├── composer.json ├── .scrutinizer.yml ├── README.md └── phpcs.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | -------------------------------------------------------------------------------- /stubs/show.stub: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 | @endsection -------------------------------------------------------------------------------- /stubs/index.stub: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 | @endsection -------------------------------------------------------------------------------- /stubs/lang.stub: -------------------------------------------------------------------------------- 1 | '{{modelName}}', 5 | ]; -------------------------------------------------------------------------------- /stubs/create.stub: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 | {{form}} 6 | 7 | @endsection -------------------------------------------------------------------------------- /stubs/edit.stub: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 | {{form}} 6 | 7 | @endsection -------------------------------------------------------------------------------- /src/Forms/Select.php: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /stubs/fields-textArea.stub: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 |
-------------------------------------------------------------------------------- /src/Utility/JsonResource.php: -------------------------------------------------------------------------------- 1 | 'Edit', 11 | 'create' => 'Create', 12 | 'view' => 'View', 13 | 'show' => 'Show', 14 | 'success' => 'Process was successfully finished!', 15 | 'not_modified' => 'Process was completed with no changes!', 16 | 'error' => 'An error occur, please try again later!', 17 | 'not_found' => 'What you are looking for is not found!', 18 | 'no_content' => 'No content to show!', 19 | ]; 20 | -------------------------------------------------------------------------------- /src/Forms/Input.php: -------------------------------------------------------------------------------- 1 | column->getNotnull() ? 'required' : ''; 16 | 17 | return str_replace( 18 | [ 19 | '{{columnName}}', 20 | '{{type}}', 21 | '{{required}}', 22 | '{{label}}', 23 | ], 24 | [ 25 | $this->column->getName(), 26 | $this->getType(), 27 | $required, 28 | ucfirst(str_replace('_', ' ', $this->column->getName())), 29 | ], 30 | $this->getFormStub('input') 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Forms/TextArea.php: -------------------------------------------------------------------------------- 1 | column->getNotnull() ? 'required' : ''; 16 | 17 | return str_replace( 18 | [ 19 | '{{columnName}}', 20 | '{{type}}', 21 | '{{required}}', 22 | '{{label}}', 23 | ], 24 | [ 25 | $this->column->getName(), 26 | $this->getType(), 27 | $required, 28 | ucfirst(str_replace('_', ' ', $this->column->getName())), 29 | ], 30 | $this->getFormStub('textArea') 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /stubs/Repository.stub: -------------------------------------------------------------------------------- 1 | path(), 'api')) { 32 | $errors = (new ValidationException($validator))->errors(); 33 | throw new HttpResponseException(Response::json(['success' => false, 'errors' => $errors, 34 | ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)); 35 | } 36 | parent::failedValidation($validator); 37 | } 38 | 39 | public function rules() 40 | { 41 | App::setLocale($this->header('Language', 'en')); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/config/repository.php: -------------------------------------------------------------------------------- 1 | realpath(__DIR__.'/../app/'), 10 | 'route_path' => realpath('routes/'), 11 | 'resources_path' => realpath('resources'), 12 | 'stubs_path' => realpath('resources').'/stubs/', 13 | 'lang_path' => realpath('resources').'/lang/', 14 | 'config_path' => realpath('config'), 15 | 16 | //relative to app path 17 | 'interface' => 'Interface', 18 | 'model' => 'Entity', 19 | 'repository' => 'Repository', 20 | 21 | //Base extend classes 22 | 'base_controller'=>'Shamaseen\Repository\Generator\Utility\Controller', 23 | 'base_resource'=>'Shamaseen\Repository\Generator\Utility\JsonResource', 24 | 'base_interface'=>'Shamaseen\Repository\Generator\Utility\ContractInterface', 25 | 'base_model'=>'Shamaseen\Repository\Generator\Utility\Entity', 26 | 'base_repository'=>'Shamaseen\Repository\Generator\Utility\AbstractRepository', 27 | 'base_request'=>'Shamaseen\Repository\Generator\Utility\Request', 28 | 29 | //namespaces 30 | 'controllers_folder' => 'Http\Controllers', 31 | 'resources_folder' => 'Http\Resources', 32 | 'requests_folder' => 'Http\Requests', 33 | 34 | 'languages' => [ 35 | 'en', 36 | ], 37 | ]; 38 | -------------------------------------------------------------------------------- /stubs/Request.stub: -------------------------------------------------------------------------------- 1 | method(); 36 | if (null !== $this->get('_method', null)) { 37 | $method = $this->get('_method'); 38 | } 39 | $this->offsetUnset('_method'); 40 | switch ($method) { 41 | case 'DELETE': 42 | case 'GET': 43 | $this->rules = []; 44 | break; 45 | 46 | case 'POST': 47 | 48 | break; 49 | // in case of edit 50 | case 'PUT': 51 | case 'PATCH': 52 | 53 | break; 54 | default: 55 | break; 56 | } 57 | 58 | return $this->rules; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shamaseen/repository-generator", 3 | "description": "repository pattern files generator", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Mohammad Shamaseen", 9 | "email": "m.shamaseen@outlook.com" 10 | }, 11 | { 12 | "name": "Hamza Alayed", 13 | "email": "developerh108@gmail.com" 14 | } 15 | ], 16 | "extra": { 17 | "laravel": { 18 | "providers": [ 19 | "Shamaseen\\Repository\\Generator\\GeneratorServiceProvider", 20 | "Shamaseen\\Repository\\Generator\\RepositoryServiceProvider" 21 | ] 22 | } 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Shamaseen\\Repository\\Generator\\": "src/" 27 | }, 28 | "files": [ 29 | "vendor/laravel/framework/src/Illuminate/Foundation/helpers.php" 30 | ] 31 | }, 32 | 33 | "minimum-stability": "stable", 34 | "prefer-stable": true, 35 | 36 | "require": { 37 | "illuminate/console": ">5.7", 38 | "illuminate/support": ">5.7", 39 | "doctrine/dbal": ">2.8", 40 | "illuminate/database": ">5.7", 41 | "illuminate/routing": ">5.7", 42 | "illuminate/validation": ">5.7" 43 | }, 44 | "require-dev": { 45 | "friendsofphp/php-cs-fixer": "^2.14", 46 | "sebastian/phpcpd": "^4.1", 47 | "phploc/phploc": "^4.0", 48 | "phpmd/phpmd": "^2.6" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/GeneratorServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 21 | $this->commands([ 22 | Generator::class, 23 | Remover::class 24 | ]); 25 | } 26 | 27 | $this->publishes([ 28 | __DIR__.'/config' => realpath('config'), 29 | ], 'repository-generator'); 30 | 31 | if (null === $this->app['config']->get('repository')) { 32 | $this->app['config']->set('repository', require __DIR__.'/config/repository.php'); 33 | } 34 | $this->mergeConfigFrom(__DIR__.'/config/repository.php', 'repository-config'); 35 | $resourcesPathStub = resource_path('/stubs'); 36 | $stubPath = realpath(__DIR__.'/../stubs'); 37 | $langPath = Config::get('repository.lang_path').'/en'; 38 | 39 | if (!is_dir($resourcesPathStub)) { 40 | mkdir($resourcesPathStub, 0777, true); 41 | } 42 | 43 | $this->publishes([ 44 | $stubPath => Config::get('repository.stubs_path', $resourcesPathStub), 45 | __DIR__.'/lang' => $langPath, 46 | ], 'repository-stub'); 47 | } 48 | 49 | /** 50 | * Register services. 51 | */ 52 | public function register() 53 | { 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Forms/Forms.php: -------------------------------------------------------------------------------- 1 | column = $column; 31 | } 32 | 33 | abstract public function template(); 34 | 35 | public function getType(): string 36 | { 37 | switch ($this->column->getName()) { 38 | case 'email': 39 | return 'email'; 40 | case 'password': 41 | return 'password'; 42 | } 43 | 44 | switch ($this->column->getType()) { 45 | case 'integer': 46 | case 'int': 47 | case 'mediumint': 48 | case 'bigint': 49 | case 'decimal': 50 | case 'float': 51 | case 'double': 52 | return 'number'; 53 | 54 | case 'time': 55 | return 'time'; 56 | 57 | case 'date': 58 | case 'datetime': 59 | case 'timestamp': 60 | case 'year': 61 | return 'date'; 62 | 63 | case 'boolean': 64 | case 'bool': 65 | case 'varchat': 66 | case 'enum': 67 | case 'text': 68 | default: 69 | return 'text'; 70 | } 71 | } 72 | 73 | public function getFormStub($type) 74 | { 75 | return file_get_contents(Config::get('repository.stubs_path').'/fields-'.$type.'.stub'); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | before_commands: 2 | - "composer install --prefer-source" 3 | 4 | tools: 5 | # Code Coverage 6 | php_code_coverage: 7 | enabled: true 8 | test_command: phpunit 9 | filter: 10 | excluded_paths: 11 | - 'vendor/*' 12 | - 'tests/*' 13 | 14 | 15 | # Code Sniffer 16 | php_code_sniffer: 17 | enabled: true 18 | config: 19 | standard: PSR2 20 | filter: 21 | excluded_paths: 22 | - 'vendor/*' 23 | 24 | 25 | # Copy/Paste Detector 26 | php_cpd: 27 | enabled: true 28 | excluded_dirs: 29 | - 'vendor' 30 | 31 | 32 | # PHP CS Fixer (http://http://cs.sensiolabs.org/). 33 | php_cs_fixer: 34 | enabled: true 35 | config: 36 | level: psr2 37 | filter: 38 | excluded_paths: 39 | - 'vendor/*' 40 | 41 | 42 | # Analyzes the size and structure of a PHP project. 43 | php_loc: 44 | enabled: true 45 | command: phploc 46 | excluded_dirs: 47 | - vendor 48 | 49 | 50 | # PHP Mess Detector (http://phpmd.org). 51 | php_mess_detector: 52 | enabled: true 53 | 54 | config: 55 | rulesets: 56 | - codesize 57 | - unusedcode 58 | - naming 59 | - design 60 | - controversial 61 | filter: 62 | excluded_paths: 63 | - 'vendor/*' 64 | 65 | 66 | # Analyzes the size and structure of a PHP project. 67 | php_pdepend: 68 | enabled: true 69 | excluded_dirs: 70 | - vendor 71 | 72 | # Runs Scrutinizer's PHP Analyzer Tool 73 | php_analyzer: 74 | enabled: true 75 | filter: 76 | excluded_paths: 77 | - 'vendor/*' 78 | 79 | # Security Advisory Checker 80 | sensiolabs_security_checker: true 81 | build: 82 | environment: 83 | php: 84 | version: '7.3' 85 | nodes: 86 | analysis: 87 | dependencies: 88 | after: 89 | - composer require --dev squizlabs/php_codesniffer 90 | 91 | tests: 92 | override: 93 | - 94 | command: phpcs-run 95 | use_website_config: false 96 | - php-scrutinizer-run 97 | -------------------------------------------------------------------------------- /stubs/Controller.stub: -------------------------------------------------------------------------------- 1 | getFormInputClass($column); 28 | 29 | return $fileInput->template(); 30 | } 31 | 32 | /** 33 | * @param Column $column 34 | * 35 | * @return Input|TextArea 36 | */ 37 | public function getFormInputClass(Column $column) 38 | { 39 | switch ($column->getType()->getName()) { 40 | case 'text': 41 | return new TextArea($column); 42 | case 'integer': 43 | case 'int': 44 | case 'mediumint': 45 | case 'bigint': 46 | case 'decimal': 47 | case 'float': 48 | case 'double': 49 | case 'enum': 50 | case 'date': 51 | case 'datetime': 52 | case 'timestamp': 53 | case 'time': 54 | case 'bool': 55 | case 'year': 56 | case 'boolean': 57 | case 'varchat': 58 | default: 59 | return new Input($column); 60 | } 61 | } 62 | 63 | /** 64 | * @param Model $entity 65 | * @param string $method 66 | * 67 | * @return string 68 | */ 69 | public function generateForm(Model $entity, string $method = 'post'): string 70 | { 71 | $html = '
72 | '; 73 | $html .= $this->getInputs($entity); 74 | $html .= '
'; 75 | 76 | return $html; 77 | } 78 | 79 | /** 80 | * @param Model $entity 81 | * 82 | * @return array 83 | */ 84 | public function getFillables(Model $entity): array 85 | { 86 | if (!empty($entity->getFillable())) { 87 | return $entity->getFillable(); 88 | } 89 | 90 | $columns = Schema::getColumnListing($entity->getTable()); 91 | 92 | foreach ($entity->getGuarded() as $guarded) { 93 | if (false !== ($key = array_search($guarded, $columns))) { 94 | unset($columns[$key]); 95 | } 96 | } 97 | 98 | return $columns; 99 | } 100 | 101 | /** 102 | * @param Model $entity 103 | * 104 | * @return string 105 | */ 106 | public function getInputs(Model $entity): string 107 | { 108 | if ($this->inputs) { 109 | return $this->inputs; 110 | } 111 | 112 | return $this->generateInputs($entity); 113 | } 114 | 115 | /** 116 | * @param Model $entity 117 | * 118 | * @return string 119 | */ 120 | public function generateInputs(Model $entity): string 121 | { 122 | $html = ''; 123 | foreach ($this->getFillables($entity) as $fillable) { 124 | $column = DB::connection()->getDoctrineColumn($entity->getTable(), $fillable); 125 | 126 | $html .= $this->generateFormInput($column); 127 | } 128 | $html .= ""; 129 | $this->inputs = $html; 130 | 131 | return $html; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Commands/Remover.php: -------------------------------------------------------------------------------- 1 | argument('name')) ?? []; 55 | 56 | if (!$file) { 57 | return 'Something wrong with the inputs !'; 58 | } 59 | 60 | $this->repoName = $file[count($file) - 1]; 61 | 62 | unset($file[count($file) - 1]); 63 | $path = implode('\\', $file); 64 | 65 | if (!$this->confirm('This will delete ' . $this->repoName . ' files and folder, Do you want to continue ?')) { 66 | return false; 67 | } 68 | 69 | $model = Str::plural(Config::get('repository.model')); 70 | $interface = Str::plural(Config::get('repository.interface')); 71 | $repository = Str::plural(Config::get('repository.repository')); 72 | $controllerFolder = Config::get('repository.controllers_folder'); 73 | $requestFolder = Config::get('repository.requests_folder'); 74 | $resourceFolder = Config::get('repository.resources_folder'); 75 | 76 | $this->remove('Entity', $model, $path); 77 | $this->remove('Controller', $controllerFolder, $path); 78 | $this->remove('Resource', $resourceFolder, $path); 79 | $this->remove('Request', $requestFolder, $path); 80 | $this->remove('Repository', $repository, $path); 81 | $this->remove('Interface', $interface, $path); 82 | return true; 83 | } 84 | 85 | public function remove($type, $folder, $relativePath): bool 86 | { 87 | $folder = str_replace('\\', '/', $folder); 88 | $relativePath = str_replace('\\', '/', $relativePath); 89 | 90 | switch ($type) { 91 | case 'Entity': 92 | $filePath = Config::get('repository.app_path') . "/$folder/$relativePath/"; 93 | $fileName = "$this->repoName.php"; 94 | break; 95 | case 'Controller': 96 | case 'Request': 97 | case 'Resource': 98 | case 'Repository': 99 | case 'Interface': 100 | default: 101 | $filePath = Config::get('repository.app_path') . "/$folder/$relativePath/"; 102 | $fileName = "$this->repoName$type.php"; 103 | } 104 | if (!is_file($filePath . $fileName)) { 105 | $this->warn($filePath . $fileName . ' is not a valid file'); 106 | return false; 107 | } 108 | 109 | unlink($filePath . $fileName); 110 | if (!(new FilesystemIterator($filePath))->valid()) { 111 | rmdir($filePath); 112 | } 113 | return true; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/RepositoryServiceProvider.php: -------------------------------------------------------------------------------- 1 | app['config']->get('repository')) { 44 | $this->app['config']->set('repository', require __DIR__ . '/config/repository.php'); 45 | } 46 | $interfaces = Str::plural(Config::get('repository.interface')); 47 | $repositories = Str::plural(Config::get('repository.repository')); 48 | $interface = Config::get('repository.interface'); 49 | $repository = Config::get('repository.repository'); 50 | 51 | $contractsFolder = Config::get('repository.app_path') . '/' . $interfaces; 52 | 53 | if (is_dir($contractsFolder)) { 54 | $directory = new RecursiveDirectoryIterator($contractsFolder); 55 | $iterator = new RecursiveIteratorIterator($directory); 56 | $regex = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); 57 | foreach ($regex as $name => $value) { 58 | if ($name) { 59 | 60 | $contract = strstr($name, 'app/') ?: strstr($name, 'app\\'); 61 | $contract = rtrim($contract, '.php'); 62 | 63 | $contractName = str_replace('/', '\\', ucfirst($contract)); 64 | 65 | //replace only first occurrence 66 | $pos = strpos($contractName, $interfaces); 67 | $repositoryClass = ''; 68 | if ($pos !== false) { 69 | $repositoryClass = substr_replace($contractName, $repositories, $pos, strlen($interfaces)); 70 | if (is_array($repositoryClass)) { 71 | $repositoryClass = implode('', $repositoryClass); 72 | } 73 | } 74 | 75 | //replace only last occurrence 76 | $pos = strrpos($repositoryClass, $interface); 77 | if ($pos !== false) { 78 | $repositoryClass = substr_replace($repositoryClass, $repository, $pos, strlen($interface)); 79 | } 80 | 81 | $this->providers[] = $contractName; 82 | $this->bindings[$contractName] = $repositoryClass; 83 | 84 | if ( 85 | interface_exists($contractName) && 86 | in_array(ContractInterface::class, class_implements($contractName)) 87 | ) { 88 | $this->providers[] = $contractName; 89 | $this->bindings[$contractName] = $repositoryClass; 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * Bootstrap services. 98 | */ 99 | public function boot() 100 | { 101 | } 102 | 103 | /** 104 | * Register services. 105 | */ 106 | public function register() 107 | { 108 | } 109 | 110 | /** 111 | * Get the services provided by the provider. 112 | * 113 | * @return array 114 | */ 115 | public function provides(): array 116 | { 117 | return $this->providers; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Utility/ContractInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Repository Generator Coding Standards 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | *.php 73 | 74 | 75 | 76 | *.php 77 | 78 | 79 | 80 | src 81 | 82 | */src/stubs/* 83 | */database/* 84 | */cache/* 85 | */*.js 86 | */*.css 87 | */*.xml 88 | */*.blade.php 89 | */autoload.php 90 | */storage/* 91 | */docs/* 92 | */vendor/* 93 | */migrations/* 94 | */config/* 95 | */public/index.php 96 | */*.blade.php 97 | */Middleware/* 98 | */Console/Kernel.php 99 | */Exceptions/Handler.php 100 | */Http/Kernel.php 101 | */Providers/* 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/Commands/Generator.php: -------------------------------------------------------------------------------- 1 | FormGenerator = new FormGenerator(); 53 | } 54 | 55 | /** 56 | * Execute the console command. 57 | * 58 | * @throws ReflectionException 59 | */ 60 | public function handle() 61 | { 62 | $file = preg_split(' ([/\\\]) ', (string)$this->argument('name')) ?? []; 63 | 64 | if (!$file) { 65 | return 'Something wrong with the inputs !'; 66 | } 67 | 68 | $this->repoName = $file[count($file) - 1]; 69 | 70 | unset($file[count($file) - 1]); 71 | $path = implode('\\', $file); 72 | 73 | if ($this->option('only-view')) { 74 | $this->makeViewsAndLanguage($path); 75 | $this->dumpAutoload(); 76 | return true; 77 | } 78 | 79 | return $this->makeRepositoryPatternFiles($path); 80 | } 81 | 82 | public function makeRepositoryPatternFiles($path): bool 83 | { 84 | $model = Str::plural(Config::get('repository.model', 'Entity')); 85 | $interface = Str::plural(Config::get('repository.interface', 'Interface')); 86 | $repository = Str::plural(Config::get('repository.repository', 'Repository')); 87 | $controller = Config::get('repository.controllers_folder', 'Http\Controllers'); 88 | $request = Config::get('repository.requests_folder', 'Http\Requests'); 89 | $resource = Config::get('repository.resources_folder', 'Http\Resources'); 90 | 91 | $base = "Shamaseen\Repository\Generator\Utility"; 92 | $modelBase = Config::get('repository.base_model', "$base\Entity"); 93 | $interfaceBase = Config::get('repository.base_interface', "$base\ContractInterface"); 94 | $repositoryBase = Config::get('repository.base_repository', "$base\AbstractRepository"); 95 | $controllerBase = Config::get('repository.base_controller', "$base\Controller"); 96 | $requestBase = Config::get('repository.base_request', "$base\Request"); 97 | $resourceBase = Config::get('repository.base_resource', "$base\JsonResource"); 98 | 99 | $this->generate($path, $controller, 'Controller', '', $controllerBase); 100 | $this->generate($path, $resource, 'Resource', '', $resourceBase); 101 | $this->generate($path, $model, 'Entity', '', $modelBase); 102 | $this->generate($path, $request, 'Request', '', $requestBase); 103 | $this->generate($path, $interface, 'Interface', '', $interfaceBase); 104 | $this->generate($path, $repository, 'Repository', '', $repositoryBase); 105 | 106 | $this->dumpAutoload(); 107 | 108 | return true; 109 | } 110 | 111 | /** 112 | * @param $path 113 | * 114 | * @return null 115 | * @throws ReflectionException 116 | */ 117 | public function makeViewsAndLanguage($path) 118 | { 119 | $entity = $this->getEntity($path); 120 | 121 | $createHtml = ''; 122 | $editHtml = ''; 123 | if ($entity instanceof Model) { 124 | $createHtml = $this->FormGenerator->generateForm($entity); 125 | $editHtml = $this->FormGenerator->generateForm($entity, 'put'); 126 | } else { 127 | $message = "There is no entity for $this->repoName, 128 | do you want to continue (this will disable form generator) ?"; 129 | if (!$this->confirm($message)) { 130 | echo 'Dispatch ..'; 131 | return null; 132 | } 133 | } 134 | $repositoryName = lcfirst($this->repoName); 135 | $viewsPath = Config::get('repository.resources_path') . '/views'; 136 | $languagePath = Config::get('repository.lang_path'); 137 | 138 | foreach (Config::get('repository.languages') as $lang) { 139 | $this->generate($repositoryName, $languagePath . $lang, 'lang'); 140 | } 141 | 142 | $this->generate($repositoryName, $viewsPath, 'create', $createHtml); 143 | $this->generate($repositoryName, $viewsPath, 'edit', $editHtml); 144 | $this->generate($repositoryName, $viewsPath, 'index'); 145 | $this->generate($repositoryName, $viewsPath, 'show'); 146 | return null; 147 | } 148 | 149 | /** 150 | * @param $path 151 | * 152 | * @return bool|object 153 | * @throws ReflectionException 154 | * 155 | */ 156 | public function getEntity($path) 157 | { 158 | $myClass = 'App\Entities\\' . $path . '\\' . $this->repoName; 159 | if (!class_exists($myClass)) { 160 | return false; 161 | } 162 | 163 | $reflect = new ReflectionClass($myClass); 164 | 165 | return $reflect->newInstance(); 166 | } 167 | 168 | /** 169 | * Get stub content to generate needed files. 170 | * 171 | * @param string $type determine which stub should choose to get content 172 | * 173 | * @return false|string 174 | */ 175 | protected function getStub(string $type) 176 | { 177 | return file_get_contents(Config::get('repository.stubs_path') . "/$type.stub"); 178 | } 179 | 180 | /** 181 | * @param string $path Class path 182 | * @param string $folder default path to generate in 183 | * @param string $type define which kind of files should generate 184 | * @param string $form 185 | * @param string $base 186 | * 187 | * @return bool 188 | */ 189 | protected function generate(string $path, string $folder, string $type, string $form = '', string $base = ''): bool 190 | { 191 | $path = $path ? '\\' . $path : ''; 192 | $content = $this->getStub($type); 193 | 194 | if (false === $content) { 195 | echo 'file ' . $type . '.stub is not exist !'; 196 | 197 | return false; 198 | } 199 | 200 | $template = str_replace( 201 | [ 202 | '{{base}}', 203 | '{{modelName}}', 204 | '{{lcPluralModelName}}', 205 | '{{folder}}', 206 | '{{path}}', 207 | '{{modelBaseFolderName}}', 208 | '{{interfaceBaseFolderName}}', 209 | '{{form}}', 210 | ], 211 | [ 212 | $base, 213 | $this->repoName, 214 | Str::plural(lcfirst($this->repoName)), 215 | Str::plural($folder), 216 | $path, 217 | Str::plural(Config::get('repository.model', 'Entity')), 218 | Str::plural(Config::get('repository.interface', 'Interface')), 219 | $form, 220 | ], 221 | $content 222 | ); 223 | 224 | $folder = str_replace('\\', '/', $folder); 225 | $path = str_replace('\\', '/', $path); 226 | $this->type($type, $folder, $path, $template); 227 | 228 | return true; 229 | } 230 | 231 | /** 232 | * Check if folder exist. 233 | * 234 | * @param string $path class path 235 | * 236 | * @return string 237 | */ 238 | public function getFolderOrCreate(string $path): string 239 | { 240 | if (!file_exists($path)) { 241 | mkdir($path, 0777, true); 242 | } 243 | 244 | return $path; 245 | } 246 | 247 | /** 248 | * @param string $path Class path 249 | * @param string $folder default path to generate in 250 | * @param string $type define which kind of files should generate 251 | * @param string $template temple file 252 | * 253 | */ 254 | private function type(string $type, string $folder, string $path, string $template) 255 | { 256 | switch ($type) { 257 | case 'Entity': 258 | $filePath = $this->getFolderOrCreate(Config::get('repository.app_path') . "/$folder/$path"); 259 | $filePath = rtrim($filePath, '/'); 260 | $content = "$filePath/$this->repoName.php"; 261 | 262 | break; 263 | case 'Controller': 264 | case 'Resource': 265 | case 'Request': 266 | case 'Repository': 267 | case 'Interface': 268 | $filePath = $this->getFolderOrCreate(Config::get('repository.app_path') . "/$folder/$path"); 269 | $filePath = rtrim($filePath, '/'); 270 | $content = "$filePath/{$this->repoName}$type.php"; 271 | break; 272 | case 'create': 273 | case 'edit': 274 | case 'index': 275 | case 'show': 276 | $filePath = $this->getFolderOrCreate($folder . '/' . Str::plural($path)) . '/'; 277 | $repoName = lcfirst($type); 278 | $content = $filePath . $repoName . '.blade.php'; 279 | break; 280 | default: 281 | $filePath = $this->getFolderOrCreate($folder) . '/'; 282 | $repoName = lcfirst($this->repoName); 283 | $content = $filePath . $repoName . '.php'; 284 | } 285 | 286 | if (is_dir($filePath) && file_exists($content)) { 287 | // Ask to replace exiting file 288 | if (!$this->confirm("This file, $content already exit, do you want to replace?")) { 289 | $this->line('File Not Replaced'); 290 | return; 291 | } 292 | } 293 | 294 | file_put_contents($content, $template); 295 | } 296 | 297 | private function dumpAutoload() 298 | { 299 | shell_exec('composer dump-autoload'); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /src/Utility/AbstractRepository.php: -------------------------------------------------------------------------------- 1 | app = $app; 70 | $this->makeModel(); 71 | } 72 | 73 | /** 74 | * @throws BindingResolutionException 75 | */ 76 | protected function makeModel() 77 | { 78 | $this->model = $this->app->make($this->getModelClass()); 79 | } 80 | 81 | /** 82 | * @return string 83 | */ 84 | abstract protected function getModelClass(): string; 85 | 86 | /** 87 | * @param int $limit 88 | * @param array $criteria 89 | * 90 | * @return Paginator 91 | */ 92 | public function simplePaginate(int $limit = 10, array $criteria = []): Paginator 93 | { 94 | return $this->filter($criteria)->simplePaginate($limit); 95 | } 96 | 97 | /** 98 | * @return \Illuminate\Database\Query\Builder|Entity 99 | */ 100 | public function builder() 101 | { 102 | return $this->model->query(); 103 | } 104 | 105 | /** 106 | * @param array $criteria 107 | * 108 | * @return Builder 109 | */ 110 | public function filter(array $criteria = []): Builder 111 | { 112 | $criteria = $this->order($criteria); 113 | 114 | /** @var Entity $latest */ 115 | $latest = $this->model->with($this->with); 116 | if ('' != $this->order) { 117 | $latest->orderBy($this->order, $this->direction); 118 | } 119 | 120 | if (isset($criteria['search'])) { 121 | foreach ($this->model->searchable as $method => $columns) { 122 | if (method_exists($this->model, $method)) { 123 | $latest->orWhereHas($method, function ($query) use ($criteria, $columns) { 124 | /* @var $query Builder */ 125 | $query->where(function ($query2) use ($criteria, $columns) { 126 | /* @var $query2 Builder */ 127 | foreach ((array)$columns as $column) { 128 | $query2->orWhere($column, 'like', '%' . $criteria['search'] . '%'); 129 | } 130 | }); 131 | }); 132 | } else { 133 | $latest->orWhere($columns, 'like', '%' . $criteria['search'] . '%'); 134 | } 135 | } 136 | } 137 | unset($criteria['search']); 138 | 139 | if ($this->trash) { 140 | $latest->onlyTrashed(); 141 | } 142 | if ($this->withTrash) { 143 | $latest->withTrashed(); 144 | } 145 | 146 | return $latest->where($criteria); 147 | } 148 | 149 | /** 150 | * prepare order for query. 151 | * 152 | * @param array $criteria 153 | * 154 | * @return array 155 | */ 156 | private function order(array $criteria = []): array 157 | { 158 | if (isset($criteria['order'])) { 159 | $this->order = $criteria['order']; 160 | unset($criteria['order']); 161 | } 162 | 163 | if (isset($criteria['direction'])) { 164 | $this->direction = $criteria['direction']; 165 | unset($criteria['direction']); 166 | } 167 | unset($criteria['page']); 168 | 169 | return $criteria; 170 | } 171 | 172 | /** 173 | * @param int $limit 174 | * @param array $criteria 175 | * 176 | * @return LengthAwarePaginator 177 | */ 178 | public function paginate(int $limit = 10, array $criteria = []): LengthAwarePaginator 179 | { 180 | return $this->filter($criteria)->paginate($limit); 181 | } 182 | 183 | /** 184 | * @param array $criteria 185 | * 186 | * @param array $columns 187 | * @return Builder[]|Collection 188 | */ 189 | public function get(array $criteria = [], array $columns = ['*']): LengthAwarePaginator 190 | { 191 | return $this->filter($criteria)->get($columns); 192 | } 193 | 194 | /** 195 | * @param int $entityId 196 | * @param array $data 197 | * 198 | * @return bool|Collection|Model|Entity 199 | */ 200 | public function update(int $entityId = 0, array $data = []) 201 | { 202 | $item = $this->model->findOrFail($entityId); 203 | 204 | if ($item->update($data)) { 205 | return $item; 206 | } 207 | 208 | return false; 209 | } 210 | 211 | /** 212 | * @param int $entityId 213 | * 214 | * @return bool 215 | * @throws Exception 216 | * 217 | */ 218 | public function delete(int $entityId = 0): bool 219 | { 220 | $item = $this->model->findOrFail($entityId); 221 | 222 | return $item->delete(); 223 | } 224 | 225 | /** 226 | * @param array $data 227 | * 228 | * @return bool 229 | */ 230 | public function insert(array $data = []): bool 231 | { 232 | return $this->model->insert($data); 233 | } 234 | 235 | /** 236 | * @param string $name 237 | * @param string $entityId 238 | * @param array $criteria 239 | * 240 | * @return array 241 | */ 242 | public function pluck(string $name = 'name', string $entityId = 'id', array $criteria = []): array 243 | { 244 | return $this->filter($criteria)->pluck($name, $entityId)->toArray(); 245 | } 246 | 247 | /** 248 | * @param int $entityId 249 | * @param array $columns 250 | * 251 | * @return Model|null 252 | */ 253 | public function find(int $entityId = 0, array $columns = ['*']): ?Model 254 | { 255 | if ($this->allowCaching) { 256 | if (isset($this->cache[$entityId])) { 257 | return $this->cache[$entityId]; 258 | } 259 | } 260 | 261 | $entity = $this->model->with($this->with)->find($entityId, $columns); 262 | 263 | if ($this->allowCaching) { 264 | $this->cache[$entityId] = $entity; 265 | } 266 | 267 | return $entity; 268 | } 269 | 270 | /** 271 | * @param $entityId 272 | * @param array $columns 273 | * 274 | * @return Model|Collection|static|static[] 275 | * @throws ModelNotFoundException 276 | * 277 | */ 278 | public function findOrFail($entityId = 0, array $columns = ['*']) 279 | { 280 | if ($this->allowCaching) { 281 | if (isset($this->cache[$entityId])) { 282 | return $this->cache[$entityId]; 283 | } 284 | } 285 | 286 | $entity = $this->model->with($this->with)->findOrFail($entityId, $columns); 287 | 288 | if ($this->allowCaching) { 289 | $this->cache[$entityId] = $entity; 290 | } 291 | 292 | return $entity; 293 | } 294 | 295 | /** 296 | * @param array $filter 297 | * @param array $columns 298 | * 299 | * @return Model|null|object 300 | */ 301 | public function first(array $filter = [], array $columns = ['*']) 302 | { 303 | if ($this->allowCaching) { 304 | if (isset($this->cache['first'])) { 305 | return $this->cache['first']; 306 | } 307 | } 308 | 309 | $entity = $this->filter($filter)->with($this->with)->select($columns)->first(); 310 | 311 | if ($this->allowCaching) { 312 | $this->cache['first'] = $entity; 313 | } 314 | 315 | return $entity; 316 | } 317 | 318 | /** 319 | * @param array $filter 320 | * @param array $columns 321 | * 322 | * @return Model|null|object 323 | */ 324 | public function last(array $filter = [], array $columns = ['*']) 325 | { 326 | if ($this->allowCaching) { 327 | if (isset($this->cache['last'])) { 328 | return $this->cache['last']; 329 | } 330 | } 331 | 332 | $entity = $this->filter($filter)->with($this->with)->select($columns)->orderBy('id', 'desc')->first(); 333 | 334 | if ($this->allowCaching) { 335 | $this->cache['last'] = $entity; 336 | } 337 | 338 | return $entity; 339 | } 340 | 341 | /** 342 | * @param $haystack 343 | * @param $needle 344 | * 345 | * @return Entity[]|Model[]|Collection 346 | */ 347 | public function search($haystack, $needle) 348 | { 349 | return $this->model->where($haystack, 'like', $needle)->get(); 350 | } 351 | 352 | /** 353 | * @param array $criteria 354 | * @param array $columns 355 | * 356 | * @return Model|null|object 357 | */ 358 | public function findBy(array $criteria = [], array $columns = ['*']) 359 | { 360 | return $this->model->with($this->with)->select($columns)->where($criteria)->first(); 361 | } 362 | 363 | /** 364 | * @param array $data 365 | * 366 | * @return Entity|Model 367 | */ 368 | public function create(array $data = []) 369 | { 370 | return $this->model->create($data); 371 | } 372 | 373 | /** 374 | * @param array $data 375 | * 376 | * @return Model 377 | */ 378 | public function createOrUpdate(array $data = []): Model 379 | { 380 | return $this->model->updateOrCreate($data); 381 | } 382 | 383 | /** 384 | * @param array $data 385 | * 386 | * @return Model 387 | */ 388 | public function createOrFirst(array $data = []): Model 389 | { 390 | return $this->model->firstOrCreate($data); 391 | } 392 | 393 | /** 394 | * Get entity name. 395 | * 396 | * @return string 397 | */ 398 | public function entityName(): string 399 | { 400 | return $this->getModelClass(); 401 | } 402 | 403 | /** 404 | * @param int $entityId 405 | * 406 | * @return bool 407 | */ 408 | public function restore(int $entityId = 0): bool 409 | { 410 | /** @var Entity|null $entity */ 411 | $entity = $this->model->withTrashed() 412 | ->whereId($entityId) 413 | ->first(); 414 | if ($entity) { 415 | return $entity->restore() ?? false; 416 | } 417 | 418 | return false; 419 | } 420 | 421 | /** 422 | * @param int $entityId 423 | * 424 | * @return bool 425 | */ 426 | public function forceDelete(int $entityId = 0): bool 427 | { 428 | /** @var Entity|null $entity */ 429 | $entity = $this->model->withTrashed() 430 | ->whereId($entityId) 431 | ->first(); 432 | if ($entity) { 433 | return $entity->forceDelete() ?? false; 434 | } 435 | 436 | return false; 437 | } 438 | 439 | public function trash() 440 | { 441 | $this->trash = true; 442 | $this->withTrash = false; 443 | } 444 | 445 | public function withTrash() 446 | { 447 | $this->trash = false; 448 | $this->withTrash = true; 449 | } 450 | 451 | public function disableCaching(): AbstractRepository 452 | { 453 | $this->allowCaching = false; 454 | return $this; 455 | } 456 | } 457 | -------------------------------------------------------------------------------- /src/Utility/Controller.php: -------------------------------------------------------------------------------- 1 | menu = new Collection(); 71 | $this->breadcrumbs = new Collection(); 72 | 73 | $language = $request->header('Language', 'en'); 74 | if (!in_array($language, Config::get('app.locales', []))) { 75 | $language = 'en'; 76 | } 77 | $limit = $request->get('limit', 10); 78 | 79 | if ($request->get('with-trash', false)) { 80 | $interface->withTrash(); 81 | } 82 | if ($request->get('only-trash', false)) { 83 | $interface->trash(); 84 | } 85 | 86 | $request->offsetUnset('only-trash'); 87 | $request->offsetUnset('with-trash'); 88 | $request->offsetUnset('limit'); 89 | 90 | if ($limit <= $this->maxLimit) { 91 | $this->limit = $limit; 92 | } 93 | 94 | App::setLocale($language); 95 | switch ($language) { 96 | case 'ar': 97 | $dir = 'rtl'; 98 | $align = 'right'; 99 | $dirInverse = 'ltr'; 100 | $alignInverse = 'left'; 101 | break; 102 | 103 | case 'en': 104 | default: 105 | $dir = 'ltr'; 106 | $align = 'left'; 107 | $dirInverse = 'rtl'; 108 | $alignInverse = 'right'; 109 | break; 110 | } 111 | 112 | View::share('dir', $dir); 113 | View::share('align', $align); 114 | View::share('alignInverse', $alignInverse); 115 | View::share('dirInverse', $dirInverse); 116 | 117 | $this->interface = $interface; 118 | $this->isAPI = $request->expectsJson(); 119 | 120 | if (!$this->isAPI) { 121 | $this->breadcrumbs = new Collection(); 122 | $this->search = new Collection(); 123 | View::share('pageTitle', $this->pageTitle . ' | ' . Config::get('app.name')); 124 | View::share('breadcrumbs', $this->breadcrumbs); 125 | View::share('menu', $this->menu); 126 | View::share('search', $this->search); 127 | View::share('selectedMenu', $this->selectedMenu); 128 | } 129 | $this->resource = $resource; 130 | if (is_null($resource)) { 131 | $this->resource = new JsonResource([]); 132 | } 133 | 134 | $this->request = $request; 135 | } 136 | 137 | /** 138 | * Display a listing of the resource. 139 | * 140 | * 141 | * @return Factory|JsonResponse|\Illuminate\View\View 142 | */ 143 | public function index() 144 | { 145 | $data = $this->interface->simplePaginate($this->limit, $this->request->all()); 146 | 147 | if (!$this->isAPI) { 148 | View::share('pageTitle', 'List ' . $this->pageTitle . ' | ' . Config::get('app.name')); 149 | $this->breadcrumbs->put('index', [ 150 | 'link' => $this->routeIndex, 151 | 'text' => $this->pageTitle, 152 | ]); 153 | 154 | return view($this->viewIndex, $this->params) 155 | ->with('entities', $data) 156 | ->with('createRoute', $this->createRoute) 157 | ->with('filters', $this->request->all()); 158 | } 159 | 160 | $resource = $this->resource::collection($data); 161 | if ($data->hasMorePages()) { 162 | $custom = collect([ 163 | 'code' => JsonResponse::HTTP_PARTIAL_CONTENT, 164 | 'message' => __('repository-generator.partial_content') 165 | ]); 166 | $resource = $custom->merge(['data' => $resource]); 167 | return response()->json($resource, JsonResponse::HTTP_PARTIAL_CONTENT); 168 | } 169 | 170 | if ($data->isEmpty()) { 171 | $custom = collect([ 172 | 'code' => JsonResponse::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, 173 | 'message' => __('repository-generator.no_content') 174 | ]); 175 | $resource = $custom->merge(['data' => $resource]); 176 | return response()->json($resource, JsonResponse::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); 177 | } 178 | 179 | $custom = collect(['code' => JsonResponse::HTTP_OK, 'message' => __('repository-generator.success')]); 180 | $resource = $custom->merge(['data' => $resource]); 181 | return response()->json($resource, JsonResponse::HTTP_OK); 182 | } 183 | 184 | /** 185 | * Show the form for creating a new resource. 186 | * 187 | * @return Factory|JsonResponse|\Illuminate\View\View 188 | */ 189 | public function create() 190 | { 191 | if (!$this->isAPI) { 192 | View::share('pageTitle', 'Create ' . $this->pageTitle . ' | ' . Config::get('app.name')); 193 | $this->breadcrumbs->put('create', [ 194 | 'link' => $this->createRoute, 195 | 'text' => trans('repository-generator.create'), 196 | ]); 197 | 198 | return view($this->viewCreate, $this->params); 199 | } 200 | 201 | return response()->json( 202 | [ 203 | 'status' => true, 204 | 'message' => __('repository-generator.no_content'), 205 | 'data' => [] 206 | ], 207 | JsonResponse::HTTP_NO_CONTENT 208 | ); 209 | } 210 | 211 | /** 212 | * Store a newly created resource in storage. 213 | * 214 | * @return JsonResponse|RedirectResponse 215 | */ 216 | public function store() 217 | { 218 | $entity = $this->interface->create($this->request->except(['_token', '_method'])); 219 | 220 | return $this->makeResponse($entity, true); 221 | } 222 | 223 | /** 224 | * Display the specified resource. 225 | * 226 | * @param int $entityId 227 | * 228 | * @return Factory|JsonResponse|RedirectResponse|\Illuminate\View\View 229 | */ 230 | public function show(int $entityId) 231 | { 232 | $entity = $this->interface->find($entityId); 233 | if (!$this->isAPI) { 234 | if (!$entity) { 235 | return Redirect::to($this->routeIndex)->with('warning', __('repository-generator.not_found')); 236 | } 237 | View::share('pageTitle', 'View ' . $this->pageTitle . ' | ' . Config::get('app.name')); 238 | $this->breadcrumbs->put('view', [ 239 | 'link' => '', 240 | 'text' => __('repository-generator.show'), 241 | ]); 242 | 243 | return view($this->viewShow, $this->params) 244 | ->with('entity', $entity); 245 | } 246 | 247 | if (!$entity) { 248 | return response()->json( 249 | [ 250 | 'status' => false, 251 | 'message' => __('repository-generator.not_found'), 252 | 'data' => [] 253 | ], 254 | JsonResponse::HTTP_NOT_FOUND 255 | ); 256 | } 257 | $resource = new $this->resource($entity); 258 | return response()->json( 259 | [ 260 | 'status' => true, 261 | 'message' => __('repository-generator.success'), 262 | 'data' => $resource 263 | ], 264 | JsonResponse::HTTP_OK 265 | ); 266 | } 267 | 268 | /** 269 | * Show the form for editing the specified resource. 270 | * 271 | * @param int $entityId 272 | * 273 | * @return Factory|JsonResponse|RedirectResponse|\Illuminate\View\View 274 | */ 275 | public function edit(int $entityId) 276 | { 277 | $entity = $this->interface->find($entityId); 278 | if (!$this->isAPI) { 279 | if (!$entity) { 280 | return Redirect::to($this->routeIndex)->with('warning', __('repository-generator.not_found')); 281 | } 282 | $this->breadcrumbs->put('edit', [ 283 | 'link' => '', 284 | 'text' => __('repository-generator.edit'), 285 | ]); 286 | 287 | return view($this->viewEdit, $this->params) 288 | ->with('entity', $entity); 289 | } 290 | 291 | return response()->json( 292 | [ 293 | 'status' => false, 294 | 'message' => __('repository-generator.not_found'), 295 | 'data' => [] 296 | ], 297 | JsonResponse::HTTP_NOT_FOUND 298 | ); 299 | } 300 | 301 | /** 302 | * Update the specified resource in storage. 303 | * 304 | * @param int $entityId 305 | * @return JsonResponse|RedirectResponse 306 | */ 307 | public function update(int $entityId) 308 | { 309 | $entity = $this->interface->update($entityId, $this->request->except(['_token', '_method'])); 310 | 311 | return $this->makeResponse($entity, true); 312 | } 313 | 314 | /** 315 | * Remove the specified resource from storage. 316 | * 317 | * @param int $entityId 318 | * 319 | * @return JsonResponse|RedirectResponse 320 | * @throws Exception 321 | */ 322 | public function destroy(int $entityId) 323 | { 324 | $deleted = $this->interface->delete($entityId); 325 | 326 | return $this->makeResponse($deleted); 327 | } 328 | 329 | /** 330 | * Restore the specified resource from storage. 331 | * 332 | * @param int $entityId 333 | * 334 | * @return JsonResponse|RedirectResponse 335 | */ 336 | public function restore(int $entityId) 337 | { 338 | $entity = $this->interface->restore($entityId); 339 | 340 | return $this->makeResponse($entity); 341 | } 342 | 343 | /** 344 | * Restore the specified resource from storage. 345 | * 346 | * @param int $entityId 347 | * 348 | * @return RedirectResponse 349 | */ 350 | public function forceDelete(int $entityId) 351 | { 352 | $entity = $this->interface->forceDelete($entityId); 353 | 354 | return $this->makeResponse($entity); 355 | } 356 | 357 | /** 358 | * Make response for web or json. 359 | * 360 | * @param mixed $entity 361 | * @param bool $appendEntity 362 | * 363 | * @return JsonResponse|RedirectResponse 364 | */ 365 | public function makeResponse($entity, bool $appendEntity = false) 366 | { 367 | if (!$this->isAPI) { 368 | if ($entity) { 369 | return Redirect::to($this->routeIndex)->with('message', __('repository-generator.success')); 370 | } 371 | 372 | if (null === $entity) { 373 | return Redirect::to($this->routeIndex)->with('warning', __('repository-generator.not_found')); 374 | } 375 | 376 | return Redirect::to($this->routeIndex)->with('error', __('repository-generator.not_modified')); 377 | } 378 | 379 | if ($entity) { 380 | if ($appendEntity) { 381 | return response()->json( 382 | [ 383 | 'status' => true, 384 | 'message' => __('repository-generator.success'), 385 | 'data' => new JsonResource($entity) 386 | ], 387 | JsonResponse::HTTP_OK 388 | ); 389 | } 390 | 391 | return response()->json( 392 | [ 393 | 'status' => false, 394 | 'message' => __('repository-generator.no_content'), 395 | 'data' => [] 396 | ], 397 | JsonResponse::HTTP_NO_CONTENT 398 | ); 399 | } 400 | 401 | if (null === $entity) { 402 | return response()->json( 403 | [ 404 | 'status' => false, 405 | 'message' => __('repository-generator.not_found'), 406 | 'data' => [] 407 | ], 408 | JsonResponse::HTTP_NOT_FOUND 409 | ); 410 | } 411 | 412 | return response()->json( 413 | [ 414 | 'status' => false, 415 | 'message' => __('repository-generator.not_modified'), 416 | 'data' => [] 417 | ], 418 | JsonResponse::HTTP_NOT_MODIFIED 419 | ); 420 | } 421 | } 422 | --------------------------------------------------------------------------------