├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── config └── laravel-crod.php └── src ├── Commands ├── MakeCrudCommand.php ├── MakeQueryCommand.php └── Modules │ ├── MakeCrudModuleCommand.php │ └── MakeQueryModuleCommand.php ├── Datas ├── OptionData.php ├── QueryData.php └── QueryModuleData.php ├── Facades └── LaravelCrodServiceFacade.php ├── LaravelCrodServiceProvider.php ├── Services └── LaravelCrodService.php ├── Stubs ├── blade.stub ├── controller.stub ├── factory.stub ├── feature-test.stub ├── form-request.stub ├── model.stub ├── module │ ├── blade.stub │ ├── controller.stub │ ├── factory.stub │ ├── feature-test.stub │ ├── model.stub │ ├── pest-test.stub │ ├── provider.stub │ ├── repository.stub │ ├── request.stub │ ├── route.stub │ ├── seeder.stub │ ├── service.stub │ └── unit-test.stub ├── pest.stub ├── repository.stub ├── seeder.stub ├── service.stub └── unit-test.stub └── Traits ├── AddDataToRepoTrait.php ├── AddDataToServiceTrait.php ├── CommonTrait.php ├── QueryTrait.php └── StubTrait.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Oliver Vogel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Crod 2 | 3 | 4 | 5 | [![PHP Version Require](https://img.shields.io/packagist/dependency-v/milwad/laravel-crod/php.svg)](https://packagist.org/packages/milwad/laravel-crod) 6 | [![Latest Stable Version](https://img.shields.io/packagist/v/milwad/laravel-crod.svg)](https://packagist.org/packages/milwad/laravel-crod) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/milwad/laravel-crod.svg)](https://packagist.org/packages/milwad/laravel-crod) 8 | [![License](https://img.shields.io/packagist/l/milwad/laravel-crod.svg)](https://packagist.org/packages/milwad/laravel-crod) 9 | [![Passed Tests](https://github.com/milwad-dev/laravel-crod/actions/workflows/run-tests.yml/badge.svg)](https://github.com/milwad-dev/laravel-crod/actions/workflows/run-tests.yml) 10 | 11 | *** 12 | Laravel crod is a package for implementing CRUD faster and easier. 13 | You can quickly create controllers, models, migrations, services, repositories, views, and requests. 14 | You can make it automatically fillable for models, query for repositories and services, make resource controllers, and have a lot of options. 15 | 16 | Docs: https://github.com/milwad-dev/laravel-crod/wiki 17 | 18 | ## Requirements 19 | 20 | *** 21 | 22 | - `PHP: ^8.0` 23 | - `Laravel framework: ^9` 24 | - `doctrine/dbal: ^3.6` 25 | 26 | | Crod | L7 | L8 | L9 | L10 | L11 | L12 | 27 | |------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------| 28 | | 1.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | 29 | | 1.1 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | 30 | | 1.2 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | 31 | | 1.3 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | 32 | | 1.4 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | 33 | | 1.5 | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | 34 | 35 | ## Installation 36 | 37 | *** 38 | 39 | ```bash 40 | composer require milwad/laravel-crod 41 | ``` 42 | 43 | After installation, you need to publish config files.
44 | 45 | ```bash 46 | php artisan vendor:publish --provider="Milwad\LaravelCrod\LaravelCrodServiceProvider" --tag="laravel-crod-config" 47 | ``` 48 | 49 | ## Check active commands 50 | 51 | When you install the `Laravel Crod`, a series of commands will be activated for you. For see these commands, you can run below command:
52 | 53 | ```bash 54 | php artisan 55 | ``` 56 | 57 | ![Crod commands](https://s6.uupload.ir/files/carbon_(1)_tqmq.png "Crod commands") 58 | 59 | ## Make CRUD files 60 | 61 | For creating crud files, you need to run the `crud:make` command in your terminal:
62 | 63 | ```bash 64 | php artisan crud:make {name} 65 | ``` 66 | 67 |
68 | 69 | For example
70 | 71 | ```bash 72 | php artisan crud:make Product 73 | ``` 74 | 75 | When you execute this command, after creating the files, you will see a list of options that will create a series of additional files for you, which of course are optional, you can choose and if you need, it will create additional files for you such as `seeder`, `factory`, `repository`, etc. 76 | 77 | ✅ After, you can see `Laravel Crod` creates crud files such as `Model`, `Controller`, `Form-Requests`, `Migrations`, etc. 78 | 79 | ## CRUD Query 80 | 81 | If you run the `crud:query` command, the result is: 82 | 83 | - Add `index`, `create`, `store`, `edit`, `update`, `destroy` functions to your controller 84 | - Get all migration columns and move them to your model fillable 85 | - Add `index`, `findById`, and `delete` functions to your repositories 86 | - Add `store`, `update` functions to your services 87 | - Add resource route (SOON) 88 | 89 | ** You must run the migrate command before the `crud:query` command. **
90 | 91 | ```bash 92 | php artisan migrate 93 | ``` 94 | 95 | For using the automatic query, you can run below command: 96 | 97 | ```bash 98 | php artisan crud:query {table_name} {model} {--id-controller} 99 | ``` 100 | 101 | For example: 102 | 103 | ```bash 104 | php artisan crud:query products Product 105 | ``` 106 | 107 | When you add `--id-controller` option, the `Laravel Crod` creates crud functions without [Route Model Binding](https://laravel.com/docs/routing#route-model-binding) in the controller. 108 | 109 | After you can see `Laravel Crod` added query to service, repository, controller, model, etc. 110 | 111 | ## CRUD for Module 112 | 113 | If you are using Modular Architecture, you can run the `crud:make-module` command. This command creates a new module and creates the default CRUD files such as `Model`, `Controller`, `Migration`, etc: 114 | 115 | ```bash 116 | php artisan crud:make-module {module_name} 117 | ``` 118 | 119 | For example: 120 | 121 | ```bash 122 | php artisan crud:make-module Product 123 | ``` 124 | 125 | When you execute this command, after creating the files, you will see a list of options that will create a series of additional files for you, which of course are optional, you can choose and if you need, it will create additional files for you such as `seeder`, `factory`, `repository`, etc. 126 | 127 | ## CRUD Query for Module 128 | 129 | This command adds a query and a date to the CRUD files for the module. 130 | This command is similar to the `crud:query` command, but this command is for the module. If you have a module, you can write your module name and `Laravel Crod` find it automatically. 131 | 132 | ** You must run your migration file ** 133 | 134 | ``` 135 | php artisan crud:query-module {table_name} {model} {--id-controller} 136 | ``` 137 | 138 | For example: 139 | 140 | ```bash 141 | php artisan crud:query-module products Product 142 | ``` 143 | 144 | OR 145 | 146 | ```bash 147 | php artisan crud:query-module products Product --id-controller 148 | ``` 149 | 150 | When you add `--id-controller` option, the `Laravel Crod` creates crud functions without [Route Model Binding](https://laravel.com/docs/routing#route-model-binding) in the controller. 151 | 152 | After you can see `Laravel Crod` added query to service, repository, controller, model, ... for your module. 153 | 154 | ## Custom path 155 | 156 | You can customize the file path in a config file. `````` 157 | 158 | With `Laravel Crod` config, you can customize the commands, for example, you want to set the route file name. 159 | This config file exists in `config/laravel-crod.php`: 160 | 161 | ```php 162 | 'Repo', 172 | 173 | /* 174 | * Get main controller. 175 | * 176 | * This is a namespace of main controller that default path is `App\Http\Controllers\Controller`. 177 | */ 178 | 'main_controller' => 'App\Http\Controllers\Controller', 179 | 180 | /* 181 | * Are using PEST? 182 | * 183 | * If you are using PEST framework, you can change it this value to `true`. 184 | */ 185 | 'are_using_pest' => false, 186 | 187 | /* 188 | * Route namespace. 189 | * 190 | * This is a word that move into the latest name of route file. 191 | */ 192 | 'route_namespace' => '', 193 | 194 | /* 195 | * Route name. 196 | * 197 | * This is a word that name of route file. 198 | */ 199 | 'route_name' => 'web', 200 | 201 | /* 202 | * Modules config. 203 | * 204 | * You can make custom modules with special folders ... . 205 | */ 206 | 'modules' => [ 207 | 'module_namespace' => 'Modules', // This value is for the name of the folder that the modules are in. 208 | 'model_path' => 'Entities', // This value is for the name of the folder that contains the module models. 209 | 'migration_path' => 'Database\Migrations', // This value is for the name of the folder that contains the module migrations. 210 | 'controller_path' => 'Http\Controllers', // This value is for the name of the folder that contains the module controllers. 211 | 'request_path' => 'Http\Requests', // This value is for the name of the folder that contains the module requests-form. 212 | 'view_path' => 'Resources\Views', // This value is for the name of the folder that contains the module views. 213 | 'service_path' => 'Services', // This value is for the name of the folder that contains the module services. 214 | 'repository_path' => 'Repositories', // This value is for the name of the folder that contains the module Repositories. 215 | 'feature_test_path' => 'Tests\Feature', // This value is for the name of the folder that contains the module feature-tests. 216 | 'unit_test_path' => 'Tests\Unit', // This value is for the name of the folder that contains the module unit-tests. 217 | 'provider_path' => 'Providers', // This value is for the name of the folder that contains the module providers. 218 | 'factory_path' => 'Database\Factories', // This value is for the name of the folder that contains the module factories. 219 | 'seeder_path' => 'Database\Seeders', // This value is for the name of the folder that contains the module seeders. 220 | 'route_path' => 'Routes', // This value is for the name of the folder that contains the module routes. 221 | ], 222 | 223 | /* 224 | * Queries. 225 | * 226 | * This is some config for add queries. 227 | */ 228 | 'queries' => [ 229 | /* 230 | * Except columns in fillable. 231 | * 232 | * This `except_columns_in_fillable` must be arrayed! 233 | * This `except_columns_in_fillable` that remove field from $fillable in model. 234 | */ 235 | 'except_columns_in_fillable' => [ 236 | 'id', 'updated_at', 'created_at', 237 | ], 238 | ], 239 | ]; 240 | ``` 241 | 242 | ## License 243 | 244 | * This package is created and modified by Milwad Khosravi 245 | for Laravel >= 9 and is released under the MIT License. 246 | 247 | ## Testing 248 | 249 | Run the tests with: 250 | 251 | ``` bash 252 | vendor/bin/phpunit 253 | composer test 254 | composer test-coverage 255 | ``` 256 | 257 | ## Contributing 258 | 259 | This project exists thanks to all the people who 260 | contribute. [CONTRIBUTING](https://github.com/milwad-dev/laravel-crod/graphs/contributors) 261 | 262 | 263 | 264 | ## Security 265 | 266 | If you've found a bug regarding security, please email [milwad.dev@gmail.com](mailto:milwad.dev@gmail.com) instead of 267 | using the issue tracker. 268 | 269 | ## Conclusion 270 | 271 | The `Laravel-Crod` is a simple yet powerful package that can help you create CRUD operations for your Laravel models in just a few lines of code. By following this documentation, you should now have a better understanding of how to use the package in your Laravel project. If you have any issues or questions, please feel free to open an issue on the package's GitHub repository. 272 | 273 | ## Donate 274 | 275 | If this package is helpful for you, you can buy a coffee for me :) ❤️ 276 | 277 | - Iraninan Gateway: https://daramet.com/milwad_khosravi 278 | - Paypal Gateway: SOON 279 | - MetaMask Address: `0xf208a562c5a93DEf8450b656c3dbc1d0a53BDE58` 280 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "milwad/laravel-crod", 3 | "description": "Make easy & fast crud", 4 | "keywords": [ 5 | "milwad", 6 | "laravel-crod", 7 | "easy crud" 8 | ], 9 | "minimum-stability": "stable", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Milwad Khosravi", 14 | "email": "milwad.dev@gmail.com", 15 | "homepage": "https://github.com/milwad-dev", 16 | "role": "Author" 17 | } 18 | ], 19 | "require": { 20 | "php": "^8.0", 21 | "binafy/laravel-stub": "^1.1", 22 | "doctrine/dbal": "^3.8|4.*", 23 | "laravel/framework": "^9.0|^10.0|^11.0|^12.0" 24 | }, 25 | "require-dev": { 26 | "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", 27 | "phpunit/phpunit": "^9.0|^10.0|^11.0" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Milwad\\LaravelCrod\\": "src/" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Milwad\\LaravelCrod\\Tests\\": "tests" 37 | } 38 | }, 39 | "config": { 40 | "sort-packages": true 41 | }, 42 | "extra": { 43 | "laravel": { 44 | "providers": [ 45 | "Milwad\\LaravelCrod\\LaravelCrodServiceProvider" 46 | ] 47 | } 48 | }, 49 | "scripts": { 50 | "test": "vendor/bin/phpunit", 51 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /config/laravel-crod.php: -------------------------------------------------------------------------------- 1 | 'Repository', 11 | 12 | /* 13 | * Get main controller. 14 | * 15 | * This is a namespace of main controller that default path is `App\Http\Controllers\Controller`. 16 | */ 17 | 'main_controller' => 'App\Http\Controllers\Controller', 18 | 19 | /* 20 | * Are using PEST? 21 | * 22 | * If you are using PEST framework, you can change it this value to `true`. 23 | */ 24 | 'are_using_pest' => false, 25 | 26 | /* 27 | * Route namespace. 28 | * 29 | * This is a word that move into the latest name of route file. 30 | */ 31 | 'route_namespace' => '', 32 | 33 | /* 34 | * Route name. 35 | * 36 | * This is a word that name of route file. 37 | */ 38 | 'route_name' => 'web', 39 | 40 | /* 41 | * Modules config. 42 | * 43 | * You can make custom modules with special folders ... . 44 | */ 45 | 'modules' => [ 46 | 'module_namespace' => 'Modules', // This value is for the name of the folder that the modules are in. 47 | 'model_path' => 'Entities', // This value is for the name of the folder that contains the module models. 48 | 'migration_path' => 'Database\Migrations', // This value is for the name of the folder that contains the module migrations. 49 | 'controller_path' => 'Http\Controllers', // This value is for the name of the folder that contains the module controllers. 50 | 'request_path' => 'Http\Requests', // This value is for the name of the folder that contains the module requests-form. 51 | 'view_path' => 'Resources\Views', // This value is for the name of the folder that contains the module views. 52 | 'service_path' => 'Services', // This value is for the name of the folder that contains the module services. 53 | 'repository_path' => 'Repositories', // This value is for the name of the folder that contains the module Repositories. 54 | 'feature_test_path' => 'Tests\Feature', // This value is for the name of the folder that contains the module feature-tests. 55 | 'unit_test_path' => 'Tests\Unit', // This value is for the name of the folder that contains the module unit-tests. 56 | 'provider_path' => 'Providers', // This value is for the name of the folder that contains the module providers. 57 | 'factory_path' => 'Database\Factories', // This value is for the name of the folder that contains the module factories. 58 | 'seeder_path' => 'Database\Seeders', // This value is for the name of the folder that contains the module seeders. 59 | 'route_path' => 'Routes', // This value is for the name of the folder that contains the module routes. 60 | ], 61 | 62 | /* 63 | * Queries. 64 | * 65 | * This is some config for add queries. 66 | */ 67 | 'queries' => [ 68 | /* 69 | * Except columns in fillable. 70 | * 71 | * This `except_columns_in_fillable` must be arrayed! 72 | * This `except_columns_in_fillable` that remove field from $fillable in model. 73 | */ 74 | 'except_columns_in_fillable' => [ 75 | 'id', 'updated_at', 'created_at', 76 | ], 77 | ], 78 | ]; 79 | -------------------------------------------------------------------------------- /src/Commands/MakeCrudCommand.php: -------------------------------------------------------------------------------- 1 | alert('Publishing crud files...'); 35 | 36 | $name = $this->argument('name'); 37 | $name_uc = ucfirst($name); 38 | 39 | $this->makeModel($name_uc); 40 | $this->makeMigration(strtolower($name)); 41 | $this->makeController($name_uc); 42 | $this->makeRequest($name_uc); 43 | $this->makeView($name_uc); 44 | 45 | /* 46 | * When all files created, after say to user need to make more files like: factory, seeder, etc. 47 | */ 48 | $this->extraOptionOperation($name_uc); 49 | 50 | $this->info('Crud files successfully generated...'); 51 | } 52 | 53 | /** 54 | * Create model class. 55 | */ 56 | private function makeModel(string $name): void 57 | { 58 | $to = app_path('Models'); 59 | if (!File::isDirectory($to)) { 60 | $to = app_path(); 61 | } 62 | 63 | LaravelStub::from(realpath(__DIR__.'/../Stubs/model.stub')) 64 | ->to($to) 65 | ->name($name) 66 | ->ext('php') 67 | ->replaces([ 68 | '$NAMESPACE$' => 'App\Models', 69 | '$CLASS_NAME$' => $name, 70 | ]) 71 | ->generate(); 72 | } 73 | 74 | /** 75 | * Create migration with call command. 76 | */ 77 | private function makeMigration(string $name): void 78 | { 79 | $name = LaravelCrodServiceFacade::getCurrentNameWithCheckLatestLetter($name); 80 | 81 | $this->call('make:migration', ['name' => "create_{$name}_table", '--create']); 82 | } 83 | 84 | /** 85 | * Create controller class. 86 | */ 87 | private function makeController(string $name): void 88 | { 89 | $currentController = config('laravel-crod.main_controller', 'App\Http\Controllers\Controller'); 90 | 91 | LaravelStub::from(__DIR__.'/../Stubs/controller.stub') 92 | ->to(app_path('Http/Controllers')) 93 | ->name("{$name}Controller") 94 | ->ext('php') 95 | ->replaces([ 96 | '$NAMESPACE$' => 'App\Http\Controllers', 97 | '$CLASS_NAME$' => "{$name}Controller", 98 | '$EXTEND_CONTROLLER$' => $currentController, 99 | ]) 100 | ->generate(); 101 | } 102 | 103 | /** 104 | * Create request classes for store and update operation. 105 | */ 106 | private function makeRequest(string $name) 107 | { 108 | $to = app_path('Http/Requests'); 109 | if (!File::isDirectory($to)) { 110 | File::makeDirectory($to, 0755, true); 111 | } 112 | 113 | LaravelStub::from(realpath(__DIR__.'/../Stubs/form-request.stub')) 114 | ->to($to) 115 | ->name("{$name}StoreRequest") 116 | ->ext('php') 117 | ->replaces([ 118 | '$NAMESPACE$' => 'App\Http\Requests', 119 | '$CLASS_NAME$' => "{$name}StoreRequest", 120 | ]) 121 | ->generate(); 122 | 123 | LaravelStub::from(__DIR__.'/../Stubs/form-request.stub') 124 | ->to($to) 125 | ->name("{$name}UpdateRequest") 126 | ->ext('php') 127 | ->replaces([ 128 | '$NAMESPACE$' => 'App\Http\Requests', 129 | '$CLASS_NAME$' => "{$name}UpdateRequest", 130 | ]) 131 | ->generate(); 132 | } 133 | 134 | /** 135 | * Create views (index, create, edit). 136 | */ 137 | private function makeView(string $name) 138 | { 139 | $name = LaravelCrodServiceFacade::getCurrentNameWithCheckLatestLetter($name); 140 | $to = resource_path('views/'.$name); 141 | if (!File::isDirectory($to)) { 142 | File::makeDirectory($to, 0755, true); 143 | } 144 | 145 | // Index 146 | LaravelStub::from(__DIR__.'/../Stubs/blade.stub') 147 | ->to($to) 148 | ->name('index') 149 | ->ext('blade.php') 150 | ->generate(); 151 | 152 | // Create 153 | LaravelStub::from(__DIR__.'/../Stubs/blade.stub') 154 | ->to($to) 155 | ->name('create') 156 | ->ext('blade.php') 157 | ->generate(); 158 | 159 | // Edit 160 | LaravelStub::from(__DIR__.'/../Stubs/blade.stub') 161 | ->to($to) 162 | ->name('edit') 163 | ->ext('blade.php') 164 | ->generate(); 165 | } 166 | 167 | /** 168 | * Create service class. 169 | */ 170 | private function makeService(string $name): void 171 | { 172 | $to = app_path('Services'); 173 | if (!File::isDirectory($to)) { 174 | File::makeDirectory($to, 0755, true); 175 | } 176 | 177 | LaravelStub::from(__DIR__.'/../Stubs/service.stub') 178 | ->to($to) 179 | ->name("{$name}Service") 180 | ->ext('php') 181 | ->replaces([ 182 | '$NAMESPACE$' => 'App\Services', 183 | '$CLASS_NAME$' => "{$name}Service", 184 | ]) 185 | ->generate(); 186 | } 187 | 188 | /** 189 | * Create repository class. 190 | */ 191 | private function makeRepository(string $name): void 192 | { 193 | $latest = config('laravel-crod.repository_namespace', 'Repository'); 194 | $to = app_path('Repositories'); 195 | if (!File::isDirectory($to)) { 196 | File::makeDirectory($to, 0755, true); 197 | } 198 | 199 | LaravelStub::from(__DIR__.'/../Stubs/repository.stub') 200 | ->to($to) 201 | ->name("{$name}$latest") 202 | ->ext('php') 203 | ->replaces([ 204 | '$NAMESPACE$' => 'App\Repositories', 205 | '$CLASS_NAME$' => "{$name}$latest", 206 | ]) 207 | ->generate(); 208 | } 209 | 210 | /** 211 | * Create feature & unit test. 212 | */ 213 | private function makeTest(string $name): void 214 | { 215 | $featureTo = base_path('tests/Feature'); 216 | if (!File::isDirectory($featureTo)) { 217 | File::makeDirectory($featureTo, 0755, true); 218 | } 219 | 220 | if (config('laravel-crod.are_using_pest', false)) { 221 | LaravelStub::from(__DIR__.'/../Stubs/pest.stub') 222 | ->to($featureTo) 223 | ->name("{$name}Test") 224 | ->ext('php') 225 | ->generate(); 226 | } else { 227 | // Feature 228 | LaravelStub::from(__DIR__.'/../Stubs/feature-test.stub') 229 | ->to($featureTo) 230 | ->name("{$name}Test") 231 | ->ext('php') 232 | ->replaces([ 233 | '$NAMESPACE$' => 'Tests\Feature', 234 | '$CLASS_NAME$' => "{$name}Test", 235 | ]) 236 | ->generate(); 237 | 238 | $unitTo = base_path('tests/Unit'); 239 | if (!File::isDirectory($unitTo)) { 240 | File::makeDirectory($unitTo, 0755, true); 241 | } 242 | 243 | // Unit 244 | LaravelStub::from(__DIR__.'/../Stubs/unit-test.stub') 245 | ->to($unitTo) 246 | ->name("{$name}Test") 247 | ->ext('php') 248 | ->replaces([ 249 | '$NAMESPACE$' => 'Tests\Unit', 250 | '$CLASS_NAME$' => "{$name}Test", 251 | ]) 252 | ->generate(); 253 | } 254 | } 255 | 256 | /** 257 | * Create seeder class. 258 | */ 259 | private function makeSeeder(string $name) 260 | { 261 | LaravelStub::from(__DIR__.'/../Stubs/seeder.stub') 262 | ->to(database_path('seeders')) 263 | ->name("{$name}Seeder") 264 | ->ext('php') 265 | ->replaces([ 266 | '$NAMESPACE$' => 'Database\Seeders', 267 | '$CLASS_NAME$' => "{$name}Seeder", 268 | ]) 269 | ->generate(); 270 | } 271 | 272 | /** 273 | * Create factory class. 274 | */ 275 | private function makeFactory(string $name) 276 | { 277 | LaravelStub::from(__DIR__.'/../Stubs/factory.stub') 278 | ->to(database_path('factories')) 279 | ->name("{$name}Factory") 280 | ->ext('php') 281 | ->replaces([ 282 | '$NAMESPACE$' => 'Database\Factories', 283 | '$CLASS_NAME$' => "{$name}Factory", 284 | ]) 285 | ->generate(); 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /src/Commands/MakeQueryCommand.php: -------------------------------------------------------------------------------- 1 | alert('Add query...'); 25 | 26 | $name = $this->argument('table_name'); 27 | $model = $this->argument('model'); 28 | 29 | $itemsDB = Schema::getColumnListing($name); 30 | $items = $this->addDBColumnsToString($itemsDB); 31 | 32 | $this->addDataToModel($items, "App/Models/$model.php"); 33 | $this->addDataToController($model, "App/Http/Controllers/{$model}Controller.php"); 34 | 35 | if (File::exists($filename = "App/Services/{$model}Service.php")) { 36 | $uses = " 37 | use App\Models\\$model; 38 | "; 39 | $this->addDataToService($model, $filename, $uses); 40 | } 41 | if (File::exists($filename = "App/Repositories/{$model}Repo.php")) { 42 | $this->addDataToRepo($model, $filename); 43 | } 44 | 45 | $this->info('Query added successfully'); 46 | } 47 | 48 | /** 49 | * Add data to controller with $id. 50 | */ 51 | private function controllerId(): string 52 | { 53 | return QueryData::getControllerIdData( 54 | '// Start code - milwad-dev', 55 | '$request', 56 | '$id' 57 | ); 58 | } 59 | 60 | /** 61 | * Add data to controller with route model binding. 62 | */ 63 | private function controllerRouteModelBinding(string $name): string 64 | { 65 | return QueryData::getControllerRouteModelBinding( 66 | '// Start code - milwad-dev', 67 | '$request', 68 | $name, 69 | strtolower($name) 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Commands/Modules/MakeCrudModuleCommand.php: -------------------------------------------------------------------------------- 1 | module_namespace = config('laravel-crod.modules.module_namespace', 'Modules'); 44 | } 45 | 46 | /** 47 | * Execute the console command. 48 | */ 49 | public function handle(): void 50 | { 51 | $name = $this->argument('module_name'); 52 | 53 | $this->alert(sprintf('Publishing crud files for module %s', $this->name)); 54 | 55 | $this->makeModel($name); 56 | $this->makeMigration($name); 57 | $this->makeController($name); 58 | $this->makeRequest($name); 59 | $this->makeView($name); 60 | $this->makeProvider($name); 61 | $this->makeRoute($name); 62 | 63 | /* 64 | * When all files created, after say to user need to make more files like: factory, seeder, etc. 65 | */ 66 | $this->extraOptionOperation($name); 67 | 68 | $this->info(sprintf('Crud files successfully generated for module %s', $name)); 69 | } 70 | 71 | /** 72 | * Create model class for module. 73 | */ 74 | protected function makeModel(string $name): void 75 | { 76 | $modelPath = config('laravel-crod.modules.model_path', 'Entities'); 77 | 78 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/model.stub')) 79 | ->to($this->getDestPath($name, $modelPath)) 80 | ->name($name) 81 | ->ext('php') 82 | ->replaces([ 83 | '$NAMESPACE$' => $this->getNamespace($name, $modelPath), 84 | '$CLASS_NAME$' => $name, 85 | ]) 86 | ->generate(); 87 | } 88 | 89 | /** 90 | * Create migration class for module. 91 | */ 92 | protected function makeMigration(string $name): void 93 | { 94 | $migrationPath = config('laravel-crod.modules.migration_path', 'Database/Migrations'); 95 | $relativePath = "$this->module_namespace/$name/$migrationPath"; 96 | $fullPath = base_path($relativePath); 97 | 98 | // Ensure the directory exists 99 | if (!File::isDirectory($fullPath)) { 100 | File::makeDirectory($fullPath, 0755, true); 101 | } 102 | 103 | // Generate the migration name 104 | $currentNameWithCheckLatestLetter = LaravelCrodServiceFacade::getCurrentNameWithCheckLatestLetter($name); 105 | 106 | // Call the make:migration Artisan command 107 | $this->call('make:migration', [ 108 | 'name' => 'create_'.$currentNameWithCheckLatestLetter.'_table', 109 | '--path' => $relativePath, 110 | '--create' => true, 111 | ]); 112 | } 113 | 114 | /** 115 | * Create controller class for module. 116 | */ 117 | protected function makeController(string $name): void 118 | { 119 | $controllerPath = config('laravel-crod.modules.controller_path', 'Http\Controllers'); 120 | $currentController = config('laravel-crod.main_controller', 'App\Http\Controllers\Controller'); 121 | 122 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/controller.stub')) 123 | ->to($this->getDestPath($name, $controllerPath)) 124 | ->name("{$name}Controller") 125 | ->ext('php') 126 | ->replaces([ 127 | '$NAMESPACE$' => $this->getNamespace($name, $controllerPath), 128 | '$CLASS_NAME$' => "{$name}Controller", 129 | '$EXTEND_CONTROLLER$' => $currentController, 130 | ]) 131 | ->generate(); 132 | } 133 | 134 | /** 135 | * Create request class for module. 136 | */ 137 | protected function makeRequest(string $name) 138 | { 139 | $requestPath = config('laravel-crod.modules.request_path', 'Http\Requests'); 140 | 141 | // Store 142 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/request.stub')) 143 | ->to($this->getDestPath($name, $requestPath)) 144 | ->name("{$name}StoreRequest") 145 | ->ext('php') 146 | ->replaces([ 147 | '$NAMESPACE$' => $this->getNamespace($name, $requestPath), 148 | '$CLASS_NAME$' => "{$name}StoreRequest", 149 | ]) 150 | ->generate(); 151 | 152 | // Update 153 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/request.stub')) 154 | ->to($this->getDestPath($name, $requestPath)) 155 | ->name("{$name}UpdateRequest") 156 | ->ext('php') 157 | ->replaces([ 158 | '$NAMESPACE$' => $this->getNamespace($name, $requestPath), 159 | '$CLASS_NAME$' => "{$name}UpdateRequest", 160 | ]) 161 | ->generate(); 162 | } 163 | 164 | /** 165 | * Create views for module. 166 | */ 167 | protected function makeView(string $name): void 168 | { 169 | $viewPath = config('laravel-crod.modules.view_path', 'Resources\Views'); 170 | $pathSource = $this->getDestPath($name, $viewPath); 171 | 172 | // Index 173 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/blade.stub')) 174 | ->to($pathSource) 175 | ->name('index') 176 | ->ext('blade.php') 177 | ->generate(); 178 | 179 | // Create 180 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/blade.stub')) 181 | ->to($pathSource) 182 | ->name('create') 183 | ->ext('blade.php') 184 | ->generate(); 185 | 186 | // Edit 187 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/blade.stub')) 188 | ->to($pathSource) 189 | ->name('edit') 190 | ->ext('blade.php') 191 | ->generate(); 192 | } 193 | 194 | /** 195 | * Create provider class for module. 196 | */ 197 | protected function makeProvider(string $name): void 198 | { 199 | $providerPath = config('laravel-crod.modules.provider_path', 'Providers'); 200 | 201 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/provider.stub')) 202 | ->to($this->getDestPath($name, $providerPath)) 203 | ->name("{$name}ServiceProvider") 204 | ->ext('php') 205 | ->replaces([ 206 | '$NAMESPACE$' => $this->getNamespace($name, $providerPath), 207 | '$CLASS_NAME$' => "{$name}ServiceProvider", 208 | ]) 209 | ->generate(); 210 | } 211 | 212 | /** 213 | * Create route for module. 214 | */ 215 | protected function makeRoute(string $name): void 216 | { 217 | $routePath = config('laravel-crod.modules.route_path', 'Routes'); 218 | $routeLatest = config('laravel-crod.route_namespace', ''); 219 | $routeName = config('laravel-crod.route_name', 'web'); 220 | 221 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/route.stub')) 222 | ->to($this->getDestPath($name, $routePath)) 223 | ->name($routeName.$routeLatest) 224 | ->ext('php') 225 | ->generate(); 226 | } 227 | 228 | /** 229 | * Create service class for module. 230 | */ 231 | protected function makeService(string $name): void 232 | { 233 | $servicePath = config('laravel-crod.modules.service_path', 'Services'); 234 | 235 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/service.stub')) 236 | ->to($this->getDestPath($name, $servicePath)) 237 | ->name("{$name}Service") 238 | ->ext('php') 239 | ->replaces([ 240 | '$NAMESPACE$' => $this->getNamespace($name, $servicePath), 241 | '$CLASS_NAME$' => "{$name}Service", 242 | ]) 243 | ->generate(); 244 | } 245 | 246 | /** 247 | * Create repository class for module. 248 | */ 249 | protected function makeRepository(string $name): void 250 | { 251 | $repositoryPath = config('laravel-crod.modules.repository_path', 'Repositories'); 252 | $latestName = config('laravel-crod.repository_namespace', 'Repository'); 253 | 254 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/repository.stub')) 255 | ->to($this->getDestPath($name, $repositoryPath)) 256 | ->name("{$name}{$latestName}") 257 | ->ext('php') 258 | ->replaces([ 259 | '$NAMESPACE$' => $this->getNamespace($name, $repositoryPath), 260 | '$CLASS_NAME$' => "{$name}{$latestName}", 261 | ]) 262 | ->generate(); 263 | } 264 | 265 | /** 266 | * Create feature & unit test. 267 | */ 268 | protected function makeTest(string $name): void 269 | { 270 | $featureTestPath = config('laravel-crod.modules.feature_test_path', 'Tests\Feature'); 271 | $unitTestPath = config('laravel-crod.modules.unit_test_path', 'Tests\Unit'); 272 | 273 | if (config('laravel-crod.are_using_pest', false)) { 274 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/pest-test.stub')) 275 | ->to($this->getDestPath($name, $featureTestPath)) 276 | ->name("{$name}Test") 277 | ->ext('php') 278 | ->generate(); 279 | } else { 280 | // Feature 281 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/feature-test.stub')) 282 | ->to($this->getDestPath($name, $featureTestPath)) 283 | ->name("{$name}Test") 284 | ->ext('php') 285 | ->replaces([ 286 | '$NAMESPACE$' => $this->getNamespace($name, $featureTestPath), 287 | '$CLASS_NAME$' => "{$name}Test", 288 | ]) 289 | ->generate(); 290 | 291 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/unit-test.stub')) 292 | ->to($this->getDestPath($name, $unitTestPath)) 293 | ->name("{$name}Test") 294 | ->ext('php') 295 | ->replaces([ 296 | '$NAMESPACE$' => $this->getNamespace($name, $unitTestPath), 297 | '$CLASS_NAME$' => "{$name}Test", 298 | ]) 299 | ->generate(); 300 | } 301 | } 302 | 303 | /** 304 | * Create seeder class for module. 305 | */ 306 | protected function makeSeeder(string $name): void 307 | { 308 | $seederPath = config('laravel-crod.modules.seeder_path', 'Database\Seeders'); 309 | 310 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/seeder.stub')) 311 | ->to($this->getDestPath($name, $seederPath)) 312 | ->name("{$name}Seeder") 313 | ->ext('php') 314 | ->replaces([ 315 | '$NAMESPACE$' => $this->getNamespace($name, $seederPath), 316 | '$CLASS_NAME$' => "{$name}Seeder", 317 | ]) 318 | ->generate(); 319 | } 320 | 321 | /** 322 | * Create factory class for module. 323 | */ 324 | protected function makeFactory(string $name): void 325 | { 326 | $factoryPath = config('laravel-crod.modules.factory_path', 'Database\Factories'); 327 | 328 | LaravelStub::from(realpath(__DIR__.'/../../Stubs/module/factory.stub')) 329 | ->to($this->getDestPath($name, $factoryPath)) 330 | ->name("{$name}Factory") 331 | ->ext('php') 332 | ->replaces([ 333 | '$NAMESPACE$' => $this->getNamespace($name, $factoryPath), 334 | '$CLASS_NAME$' => "{$name}Factory", 335 | ]) 336 | ->generate(); 337 | } 338 | 339 | /** 340 | * Get correct namespace. 341 | */ 342 | protected function getNamespace(string $name, string $path): string 343 | { 344 | return sprintf("%s\%s\%s", $this->module_namespace, $name, $path); 345 | } 346 | 347 | /** 348 | * Get the destination path. 349 | */ 350 | protected function getDestPath(string $name, string $path): string 351 | { 352 | $path = str_replace('\\', '/', $path); 353 | $to = base_path("$this->module_namespace/$name/$path"); 354 | if (!File::isDirectory($to)) { 355 | File::makeDirectory($to, 0755, true); 356 | } 357 | 358 | return $to; 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /src/Commands/Modules/MakeQueryModuleCommand.php: -------------------------------------------------------------------------------- 1 | module_name_space = config('laravel-crod.modules.module_namespace', 'Modules'); 25 | } 26 | 27 | /** 28 | * @throws \Exception 29 | */ 30 | public function handle() 31 | { 32 | $this->alert('Add query...'); 33 | 34 | $name = $this->argument('table_name'); 35 | $model = $this->argument('model'); 36 | 37 | $itemsDB = Schema::getColumnListing($name); 38 | $items = $this->addDBColumnsToString($itemsDB); 39 | 40 | $controllerFilename = "$this->module_name_space/$model/Http/Controllers/{$model}Controller.php"; 41 | 42 | $this->addDataToModel($items, "$this->module_name_space/$model/Entities/$model.php"); 43 | $this->addDataToController($model, $controllerFilename, 9); 44 | $this->addDataToProvider($model, "$this->module_name_space/$model/Providers/{$model}ServiceProvider.php"); 45 | 46 | if (!$this->option('id-controller')) { 47 | $this->addUseToControllerForRouteModelBinding($model, $controllerFilename); 48 | } 49 | if (File::exists($filename = "$this->module_name_space/$model/Services/{$model}Service.php")) { 50 | $modelPath = config('laravel-crod.modules.model_path', 'Entities'); 51 | $uses = " 52 | use $this->module_name_space\\$model\\$modelPath\\$model; 53 | "; 54 | $this->addDataToService($model, $filename, $uses); 55 | } 56 | if (File::exists($filename = "$this->module_name_space/$model/Repositories/{$model}Repo.php")) { 57 | $this->addDataToRepo($model, $filename, true); 58 | } 59 | 60 | $this->info('Query added successfully'); 61 | } 62 | 63 | /** 64 | * Add data to controller with $id for module. 65 | */ 66 | private function controllerId(): string 67 | { 68 | return QueryModuleData::getControllerIdData( 69 | '// Start code - milwad-dev', 70 | '$request', 71 | '$id' 72 | ); 73 | } 74 | 75 | /** 76 | * Add data to controller with route model binding for module. 77 | */ 78 | private function controllerRouteModelBinding(string $name): string 79 | { 80 | return QueryModuleData::getControllerRouteModelBindingData( 81 | '// Start code - milwad-dev', 82 | '$request', 83 | $name, 84 | strtolower($name) 85 | ); 86 | } 87 | 88 | /** 89 | * Add use to controller route model binding for module. 90 | * 91 | * 92 | * @return void 93 | */ 94 | private function addUseToControllerForRouteModelBinding(string $model, string $filename) 95 | { 96 | $currentController = config('laravel-crod.main_controller', 'App\Http\Controllers\Controller'); 97 | 98 | [$line_i_am_looking_for, $lines] = $this->lookingLinesWithIgnoreLines($filename, 5); 99 | $lines[$line_i_am_looking_for] = "use $this->module_name_space\\$model\Entities\\$model; 100 | use $currentController;"; 101 | file_put_contents($filename, implode("\n", $lines)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Datas/OptionData.php: -------------------------------------------------------------------------------- 1 | DO NOT MAKE ANY CHANGES TO THIS FILE 9 | */ 10 | 11 | use Milwad\LaravelCrod\Facades\LaravelCrodServiceFacade; 12 | 13 | class QueryData 14 | { 15 | /** 16 | * Get model data. 17 | * 18 | * 19 | * @return string 20 | */ 21 | public static function getModelData(mixed $items) 22 | { 23 | return PHP_EOL.' protected $fillable = ['.$items.'];'.PHP_EOL.'}'; 24 | } 25 | 26 | /** 27 | * Get service data. 28 | * 29 | * 30 | * @return string 31 | */ 32 | public static function getServiceData(string $model, string $request, string $id) 33 | { 34 | return " public function store($request) 35 | { 36 | return $model::query()->create(".'$request->all()'."); 37 | } 38 | 39 | public function update($request, $id) 40 | { 41 | return $model::query()->where('id', $id)->update(".'$request->all()'.'); 42 | }'; 43 | } 44 | 45 | /** 46 | * Get use for service. 47 | * 48 | * 49 | * @return string 50 | */ 51 | public static function getUseServiceData(string $model) 52 | { 53 | return " 54 | use App\Models\{$model}; 55 | "; 56 | } 57 | 58 | /** 59 | * Get repo data. 60 | * 61 | * 62 | * @return string 63 | */ 64 | public static function getRepoData(string $model, string $id) 65 | { 66 | return " public function index() 67 | { 68 | return $model::query()->latest(); 69 | } 70 | 71 | public function findById($id) 72 | { 73 | return $model::query()->findOrFail($id); 74 | } 75 | 76 | public function delete($id) 77 | { 78 | return $model::query()->where('id', $id)->delete(); 79 | }"; 80 | } 81 | 82 | /** 83 | * Get repo for data. 84 | * 85 | * 86 | * @return string 87 | */ 88 | public static function getUseRepoData(string $model, bool $isModule) 89 | { 90 | if ($isModule) { 91 | $modulePath = config('laravel-crod.modules.module_namespace', 'Modules'); 92 | $modelPath = config('laravel-crod.modules.model_path', 'Entities'); 93 | 94 | return "\n use $modulePath\\$model\\$modelPath\\$model; \n"; 95 | } 96 | 97 | return "use App\Models\\$model;"; 98 | } 99 | 100 | /** 101 | * Get controller-id data. 102 | * 103 | * 104 | * @return string 105 | */ 106 | public static function getControllerIdData(string $comment, string $request, string $id) 107 | { 108 | return " public function index() 109 | { 110 | $comment 111 | } 112 | 113 | public function create() 114 | { 115 | $comment 116 | } 117 | 118 | public function store(Request $request) 119 | { 120 | $comment 121 | } 122 | 123 | public function show($id) 124 | { 125 | $comment 126 | } 127 | 128 | public function edit($id) 129 | { 130 | $comment 131 | } 132 | 133 | public function update(Request $request, $id) 134 | { 135 | $comment 136 | } 137 | 138 | public function destroy($id) 139 | { 140 | $comment 141 | }"; 142 | } 143 | 144 | /** 145 | * Get controller route model binding. 146 | * 147 | * 148 | * @return string 149 | */ 150 | public static function getControllerRouteModelBinding(string $comment, string $request, string $name, string $lowerName) 151 | { 152 | return " public function index() 153 | { 154 | $comment 155 | } 156 | 157 | public function create() 158 | { 159 | $comment 160 | } 161 | 162 | public function store(Request $request) 163 | { 164 | $comment 165 | } 166 | 167 | public function show($name $$lowerName) 168 | { 169 | $comment 170 | } 171 | 172 | public function edit($name $$lowerName) 173 | { 174 | $comment 175 | } 176 | 177 | public function update(Request $request, $name $$lowerName) 178 | { 179 | $comment 180 | } 181 | 182 | public function destroy($name $$lowerName) 183 | { 184 | $comment 185 | }"; 186 | } 187 | 188 | /** 189 | * Get data for provider. 190 | * 191 | * 192 | * @return string 193 | */ 194 | public static function getProviderData(string $moduleName) 195 | { 196 | $modulePaths = config('laravel-crod.modules', []); 197 | $migrationPath = '/../'.LaravelCrodServiceFacade::changeBackSlashToSlash($modulePaths['migration_path']); 198 | $viewPath = '/../'.LaravelCrodServiceFacade::changeBackSlashToSlash($modulePaths['view_path']); 199 | 200 | return " \$this->loadMigrationsFrom(__DIR__ . '$migrationPath'); 201 | \$this->loadViewsFrom(__DIR__ . '$viewPath', '$moduleName');"; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/Datas/QueryModuleData.php: -------------------------------------------------------------------------------- 1 | DO NOT MAKE ANY CHANGES TO THIS FILE 9 | */ 10 | 11 | class QueryModuleData 12 | { 13 | /** 14 | * Add Controller-ID data. 15 | * 16 | * 17 | * @return string 18 | */ 19 | public static function getControllerIdData(string $comment, string $request, string $id) 20 | { 21 | return " public function index() 22 | { 23 | $comment 24 | } 25 | 26 | public function create() 27 | { 28 | $comment 29 | } 30 | 31 | public function store(Request $request) 32 | { 33 | $comment 34 | } 35 | 36 | public function edit($id) 37 | { 38 | $comment 39 | } 40 | 41 | public function update(Request $request, $id) 42 | { 43 | $comment 44 | } 45 | 46 | public function destroy($id) 47 | { 48 | $comment 49 | }"; 50 | } 51 | 52 | /** 53 | * Add controller route-model-binding data,. 54 | * 55 | * 56 | * @return string 57 | */ 58 | public static function getControllerRouteModelBindingData(string $comment, string $request, string $name, string $lowerName) 59 | { 60 | return " public function index() 61 | { 62 | $comment 63 | } 64 | 65 | public function create() 66 | { 67 | $comment 68 | } 69 | 70 | public function store(Request $request) 71 | { 72 | $comment 73 | } 74 | 75 | public function edit($name $$lowerName) 76 | { 77 | $comment 78 | } 79 | 80 | public function update(Request $request, $name $$lowerName) 81 | { 82 | $comment 83 | } 84 | 85 | public function destroy($name $$lowerName) 86 | { 87 | $comment 88 | }"; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Facades/LaravelCrodServiceFacade.php: -------------------------------------------------------------------------------- 1 | loadCommands(); 20 | $this->publishFiles(); 21 | $this->bindFacades(); 22 | } 23 | 24 | public function loadCommands(): void 25 | { 26 | $this->commands([ 27 | MakeCrudCommand::class, 28 | MakeQueryCommand::class, 29 | MakeCrudModuleCommand::class, 30 | MakeQueryModuleCommand::class, 31 | ]); 32 | } 33 | 34 | /** 35 | * Publish files. 36 | */ 37 | public function publishFiles(): void 38 | { 39 | $this->publishes([ 40 | __DIR__.'/../config/laravel-crod.php' => config_path('laravel-crod.php'), 41 | ], 'laravel-crod-config'); 42 | } 43 | 44 | /** 45 | * Bind facades. 46 | */ 47 | public function bindFacades(): void 48 | { 49 | $this->app->bind('laravel-crod-service', function () { 50 | return new LaravelCrodService(); 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Services/LaravelCrodService.php: -------------------------------------------------------------------------------- 1 | categories - product => products). 9 | * 10 | * 11 | * @return string 12 | */ 13 | public function getCurrentNameWithCheckLatestLetter(string $name, bool $needToLower = true) 14 | { 15 | if (str_ends_with($name, 'y')) { 16 | $name = substr_replace($name, '', -1); 17 | $name .= 'ies'; 18 | } else { 19 | $name .= 's'; 20 | } 21 | 22 | return $needToLower 23 | ? strtolower($name) 24 | : $name; 25 | } 26 | 27 | /** 28 | * Change backslash to slash. 29 | * 30 | * 31 | * @return string 32 | */ 33 | public function changeBackSlashToSlash(string $str) 34 | { 35 | return str_replace('\\', '/', $str); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Stubs/blade.stub: -------------------------------------------------------------------------------- 1 |
2 | {{-- Start write code - Milwad Khosravi --}} 3 |
4 | -------------------------------------------------------------------------------- /src/Stubs/controller.stub: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function definition(): array 15 | { 16 | return [ 17 | // 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Stubs/feature-test.stub: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Stubs/form-request.stub: -------------------------------------------------------------------------------- 1 | |string> 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | // 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Stubs/model.stub: -------------------------------------------------------------------------------- 1 | 2 | {{-- Start write code - Milwad Khosravi --}} 3 | 4 | -------------------------------------------------------------------------------- /src/Stubs/module/controller.stub: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Stubs/module/model.stub: -------------------------------------------------------------------------------- 1 | toBe(3); 7 | }); 8 | 9 | -------------------------------------------------------------------------------- /src/Stubs/module/provider.stub: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | // 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Stubs/module/route.stub: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Stubs/pest.stub: -------------------------------------------------------------------------------- 1 | get('/'); 5 | 6 | $response->assertStatus(200); 7 | }); 8 | -------------------------------------------------------------------------------- /src/Stubs/repository.stub: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Traits/AddDataToRepoTrait.php: -------------------------------------------------------------------------------- 1 | lookingLinesWithIgnoreLines($filename, 6); 18 | $lines[$line_i_am_looking_for] = QueryData::getRepoData($model, '$id'); 19 | 20 | file_put_contents($filename, implode("\n", $lines)); 21 | $this->addUseToRepo($model, $filename, $isModule); 22 | } 23 | 24 | /** 25 | * Add use to repository. 26 | * 27 | * 28 | * @return void 29 | */ 30 | private function addUseToRepo(string $model, string $filename, bool $isModule) 31 | { 32 | [$line_i_am_looking_for, $lines] = $this->lookingLinesWithIgnoreLines($filename, 3); 33 | $lines[$line_i_am_looking_for] = QueryData::getUseRepoData($model, $isModule); 34 | 35 | file_put_contents($filename, implode("\n", $lines)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Traits/AddDataToServiceTrait.php: -------------------------------------------------------------------------------- 1 | lookingLinesWithIgnoreLines($filename, 6); 18 | $lines[$line_i_am_looking_for] = QueryData::getServiceData($model, '$request', '$id'); 19 | 20 | file_put_contents($filename, implode("\n", $lines)); 21 | $this->addUseToService($uses, $filename); 22 | } 23 | 24 | /** 25 | * Add use to Service for module. 26 | * 27 | * 28 | * @return void 29 | */ 30 | private function addUseToService(string $uses, string $filename) 31 | { 32 | [$line_i_am_looking_for, $lines] = $this->lookingLinesWithIgnoreLines($filename, 3); 33 | $lines[$line_i_am_looking_for] = $uses; 34 | 35 | file_put_contents($filename, implode("\n", $lines)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Traits/CommonTrait.php: -------------------------------------------------------------------------------- 1 | choice('Do you want something extra?', OptionData::$options, 0); 15 | } 16 | 17 | /** 18 | * Extra option operation. 19 | */ 20 | public function extraOptionOperation(string $name_uc): void 21 | { 22 | $selectOption = $this->extraOption(); 23 | 24 | if ($selectOption === OptionData::SEEDER_OPTION) { 25 | $this->makeSeeder($name_uc); 26 | $this->extraOptionOperation($name_uc); 27 | } 28 | if ($selectOption === OptionData::FACTORY_OPTION) { 29 | $this->makeFactory($name_uc); 30 | $this->extraOptionOperation($name_uc); 31 | } 32 | if ($selectOption === OptionData::REPOSITORY_OPTION) { 33 | $this->makeRepository($name_uc); 34 | $this->extraOptionOperation($name_uc); 35 | } 36 | if ($selectOption === OptionData::SERVICE_OPTION) { 37 | $this->makeService($name_uc); 38 | $this->extraOptionOperation($name_uc); 39 | } 40 | if ($selectOption === OptionData::TEST_OPTION) { 41 | $this->makeTest($name_uc); 42 | $this->extraOptionOperation($name_uc); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Traits/QueryTrait.php: -------------------------------------------------------------------------------- 1 | lookingLinesWithIgnoreLines($filename, 10); 51 | 52 | $lines[$line_i_am_looking_for] = QueryData::getModelData($items); 53 | 54 | file_put_contents($filename, implode("\n", $lines)); 55 | } 56 | 57 | /** 58 | * Add data to controller. 59 | * 60 | * 61 | * @return void 62 | */ 63 | private function addDataToController(string $model, string $filename, int $line = 8) 64 | { 65 | [$line_i_am_looking_for, $lines] = $this->lookingLinesWithIgnoreLines($filename, $line); 66 | $lines[$line_i_am_looking_for] = $this->option('id-controller') 67 | ? $this->controllerId() 68 | : $this->controllerRouteModelBinding($model); 69 | 70 | file_put_contents($filename, implode("\n", $lines)); 71 | } 72 | 73 | /** 74 | * Add data to provider. 75 | * 76 | * 77 | * @return void 78 | */ 79 | private function addDataToProvider(string $moduleName, string $filename) 80 | { 81 | [$line_i_am_looking_for, $lines] = $this->lookingLinesWithIgnoreLines($filename, 15); 82 | $lines[$line_i_am_looking_for] = QueryData::getProviderData($moduleName); 83 | 84 | file_put_contents($filename, implode("\n", $lines)); 85 | } 86 | 87 | /** 88 | * @param string $filename 89 | * @param int $looking_for 90 | * 91 | * @return array 92 | */ 93 | private function lookingLinesWithIgnoreLines(string $filename, int $looking_for = 8): array 94 | { 95 | return [ 96 | $looking_for, 97 | file($filename, FILE_IGNORE_NEW_LINES), 98 | ]; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Traits/StubTrait.php: -------------------------------------------------------------------------------- 1 | getSourceFilePath($pathSource, $name, $latest, $singular); 15 | $this->makeDirectory(dirname($path)); 16 | $contents = $this->getSourceFile($pathStub, $pathSource, $name); 17 | 18 | if (!$this->files->exists($path)) { 19 | $this->files->put($path, $contents); 20 | $this->info("File : {$path} created"); 21 | } else { 22 | $this->info("File : {$path} already exits"); 23 | } 24 | } 25 | 26 | /** 27 | * Return the stub file path. 28 | * 29 | * 30 | * @return string 31 | */ 32 | private function getStubPath(string $path) 33 | { 34 | return __DIR__.$path; 35 | } 36 | 37 | /** 38 | * Map the stub variables present in stub to its value. 39 | * 40 | * 41 | * @return array 42 | */ 43 | private function getStubVariables(string $namespace, string $name) 44 | { 45 | return [ 46 | 'NAMESPACE' => $namespace, 47 | 'CLASS_NAME' => $this->getSingularClassName($name), 48 | ]; 49 | } 50 | 51 | /** 52 | * Get the stub path and the stub variables. 53 | * 54 | * 55 | * @return array|false|string|string[] 56 | */ 57 | private function getSourceFile(string $path, string $namespace, string $name) 58 | { 59 | return $this->getStubContents( 60 | $this->getStubPath($path), 61 | $this->getStubVariables($namespace, $name) 62 | ); 63 | } 64 | 65 | /** 66 | * Replace the stub variables(key) with the desire value. 67 | * 68 | * @param array $stubVariables 69 | * 70 | * @return array|false|string|string[] 71 | */ 72 | private function getStubContents($stub, $stubVariables = []) 73 | { 74 | $contents = file_get_contents($stub); 75 | 76 | foreach ($stubVariables as $search => $replace) { 77 | $contents = str_replace('$'.$search.'$', $replace, $contents); 78 | } 79 | 80 | return $contents; 81 | } 82 | 83 | /** 84 | * Get the full path of generate class. 85 | * 86 | * 87 | * @return string 88 | */ 89 | private function getSourceFilePath(string $path, string $name, string $latest, bool $singular = true) 90 | { 91 | if (!$singular) { 92 | return base_path($path).'\\'.$name."$latest.php"; 93 | } 94 | 95 | return base_path($path).'\\'.$this->getSingularClassName($name)."$latest.php"; 96 | } 97 | 98 | /** 99 | * Return the singular capitalize name. 100 | * 101 | * 102 | * @return string 103 | */ 104 | private function getSingularClassName(string $name) 105 | { 106 | return ucwords(Pluralizer::singular($name)); 107 | } 108 | 109 | /** 110 | * Build the directory for the class if necessary. 111 | * 112 | * 113 | * @return string 114 | */ 115 | private function makeDirectory(string $path) 116 | { 117 | if (!$this->files->isDirectory($path)) { 118 | $this->files->makeDirectory($path, 0777, true, true); 119 | } 120 | 121 | return $path; 122 | } 123 | } 124 | --------------------------------------------------------------------------------