├── .gitignore ├── config └── config.php ├── src ├── Core │ ├── Commands │ │ ├── stubs │ │ │ ├── enum.stub │ │ │ ├── service.stub │ │ │ ├── trait.stub │ │ │ ├── interface.stub │ │ │ ├── pest.test.unit.stub │ │ │ ├── module │ │ │ │ ├── config │ │ │ │ │ └── app.php │ │ │ │ ├── resources │ │ │ │ │ └── views │ │ │ │ │ │ └── example.blade.php │ │ │ │ ├── lang │ │ │ │ │ └── en │ │ │ │ │ │ └── example.php │ │ │ │ ├── database │ │ │ │ │ └── seeders │ │ │ │ │ │ └── DatabaseSeeder.php │ │ │ │ ├── Providers │ │ │ │ │ ├── BroadcastServiceProvider.php │ │ │ │ │ ├── EventServiceProvider.php │ │ │ │ │ ├── AppServiceProvider.php │ │ │ │ │ └── RouteServiceProvider.php │ │ │ │ └── routes │ │ │ │ │ ├── web.php │ │ │ │ │ ├── channels.php │ │ │ │ │ ├── api.php │ │ │ │ │ └── console.php │ │ │ ├── observer.plain.stub │ │ │ ├── pest.test.stub │ │ │ ├── action.stub │ │ │ ├── class.stub │ │ │ ├── seeder.stub │ │ │ ├── test.unit.stub │ │ │ ├── model.stub │ │ │ ├── policy.plain.stub │ │ │ ├── scope.stub │ │ │ ├── factory.stub │ │ │ ├── rule.stub │ │ │ ├── test.stub │ │ │ ├── provider.stub │ │ │ ├── resource.stub │ │ │ ├── job.stub │ │ │ ├── resource-collection.stub │ │ │ ├── ServiceProvider.php │ │ │ ├── component.stub │ │ │ ├── broadcasting.stub │ │ │ ├── middleware.stub │ │ │ ├── request.stub │ │ │ ├── exception.stub │ │ │ ├── listener.stub │ │ │ ├── resource.jsonable.stub │ │ │ ├── mail.stub │ │ │ ├── mode.translatabled.stub │ │ │ ├── mode.translatable.stub │ │ │ ├── cast.stub │ │ │ ├── job.queued.stub │ │ │ ├── console.stub │ │ │ ├── event.stub │ │ │ ├── request.jsonable.stub │ │ │ ├── observer.stub │ │ │ ├── notification.stub │ │ │ ├── controller.stub │ │ │ └── policy.stub │ │ ├── Delete.php │ │ ├── Discover.php │ │ ├── Migrate.php │ │ ├── MigrateStatus.php │ │ ├── MakeMigration.php │ │ ├── ModulesList.php │ │ ├── MigrateReset.php │ │ ├── MakeCast.php │ │ ├── MakeEvent.php │ │ ├── MakeRule.php │ │ ├── MakeProvider.php │ │ ├── MakeSeeder.php │ │ ├── Test.php │ │ ├── DBSeed.php │ │ ├── MigrateRefresh.php │ │ ├── MakeChannel.php │ │ ├── MakeEnum.php │ │ ├── MakeScope.php │ │ ├── MakeTrait.php │ │ ├── MakeClass.php │ │ ├── MakeAction.php │ │ ├── MakeObserver.php │ │ ├── MakeFactory.php │ │ ├── MakeService.php │ │ ├── MakeMiddleware.php │ │ ├── MakeJob.php │ │ ├── MakeInterface.php │ │ ├── MakeRequest.php │ │ ├── MigrateFresh.php │ │ ├── RouteList.php │ │ ├── MakeCommand.php │ │ ├── MakeResource.php │ │ ├── MakeMail.php │ │ ├── MakeNotification.php │ │ ├── MakeComponent.php │ │ ├── MakeController.php │ │ ├── MakeException.php │ │ ├── MakeListener.php │ │ ├── MakeModel.php │ │ ├── Make.php │ │ ├── MakePolicy.php │ │ └── MakeTest.php │ ├── StreamOutput.php │ ├── ModulesFinder.php │ ├── Command.php │ └── ServiceProvider.php ├── Packages │ └── Translatable │ │ ├── stubs │ │ ├── model.translatabled.stub │ │ └── model.translatable.stub │ │ └── Commands │ │ └── TranslatableMake.php ├── helpers.php └── ModulatorServiceProvider.php ├── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock -------------------------------------------------------------------------------- /config/config.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/module/config/app.php: -------------------------------------------------------------------------------- 1 | '{{ module-name }}', 6 | 'slug' => '{{ module-slug }}', 7 | 8 | ]; 9 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/pest.test.stub: -------------------------------------------------------------------------------- 1 | get('/'); 5 | 6 | $response->assertStatus(200); 7 | }); 8 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/action.stub: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/model.stub: -------------------------------------------------------------------------------- 1 | call([ 17 | // 18 | ]); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/factory.stub: -------------------------------------------------------------------------------- 1 | get('/'); 19 | 20 | $response->assertStatus(200); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/provider.stub: -------------------------------------------------------------------------------- 1 | get('/', function () { 17 | return '{{ module-slug }}'; 18 | }); 19 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/request.stub: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | // }); 19 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/listener.stub: -------------------------------------------------------------------------------- 1 | > 13 | */ 14 | protected $listen = [ 15 | // 16 | ]; 17 | 18 | /** 19 | * Register any events for your application. 20 | * 21 | * @return void 22 | */ 23 | public function boot() 24 | { 25 | // 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/module/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | // return $request->user(); 19 | // }); 20 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/resource.jsonable.stub: -------------------------------------------------------------------------------- 1 | view('view.name'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Core/Commands/Delete.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | File::deleteDirectory($this->getPath('')); 19 | app(ModulesFinder::class)->build(); 20 | 21 | $this->info('Module [ ' . $this->module . ' ] has been deleted!'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/module/routes/console.php: -------------------------------------------------------------------------------- 1 | comment('Moamen Eltouny from Pharaonic.io'); 19 | // })->purpose('Who are you?'); 20 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/mode.translatabled.stub: -------------------------------------------------------------------------------- 1 | $attributes 14 | */ 15 | public function get(Model $model, string $key, mixed $value, array $attributes): mixed 16 | { 17 | return $value; 18 | } 19 | 20 | /** 21 | * Prepare the given value for storage. 22 | * 23 | * @param array $attributes 24 | */ 25 | public function set(Model $model, string $key, mixed $value, array $attributes): mixed 26 | { 27 | return $value; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Packages/Translatable/stubs/model.translatable.stub: -------------------------------------------------------------------------------- 1 | build(); 32 | $this->info('Modules has been discovered!'); 33 | 34 | return 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Core/Commands/Migrate.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CHECK IF MIGRATIONS NOT EXISTS 19 | if (!file_exists($migrations = module_database_path($this->module, 'migrations'))) 20 | File::makeDirectory($migrations, 0777, true, true); 21 | 22 | // Calling 23 | return Artisan::call("migrate --path=" . $this->getShortPath('database/migrations'), [], $this->getOutput()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Core/Commands/MigrateStatus.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CHECK IF MIGRATIONS NOT EXISTS 19 | if (!file_exists($migrations = module_database_path($this->module, 'migrations'))) 20 | File::makeDirectory($migrations, 0777, true, true); 21 | 22 | return Artisan::call("migrate:status --path=" . $this->getShortPath('database/migrations'), [], $this->getOutput()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/console.stub: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CHECK IF MIGRATIONS NOT EXISTS 21 | if (!file_exists($migrations = module_database_path($this->module, 'migrations'))) 22 | File::makeDirectory($migrations, 0777, true, true); 23 | 24 | // Command 25 | $command = 'make:migration ' . $this->argument('migration') . ' --path=' . $this->getShortPath('database/migrations'); 26 | 27 | // Options 28 | if ($create = $this->option('create')) $command .= ' --create=' . $create; 29 | if ($table = $this->option('table')) $command .= ' --table=' . $table; 30 | 31 | // Calling 32 | return Artisan::call($command, [], $this->getOutput()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Commands/ModulesList.php: -------------------------------------------------------------------------------- 1 | error('There are no modules.'); 22 | return false; 23 | } 24 | 25 | for ($i = 0; $i < count($modules); $i++) { 26 | if (file_exists(module_path($modules[$i], 'Providers'))) { 27 | $modules[$i] = $modules[$i]; 28 | } else { 29 | $subModules = []; 30 | foreach(File::directories(module_path($modules[$i])) as $module) { 31 | $subModules[] = $modules[$i] . '/' . basename($module); 32 | } 33 | 34 | array_splice($modules, $i, 1, ...$subModules); 35 | } 36 | } 37 | 38 | $modules = array_map(function ($module) { 39 | return [$module, studlyToSlug($module)]; 40 | }, $modules); 41 | 42 | $this->table(['Name', 'Slug'], $modules); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Core/Commands/MigrateReset.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 18 | 19 | // CHECK IF MIGRATIONS NOT EXISTS 20 | if (!file_exists($path = module_database_path($this->module, 'migrations'))) 21 | File::makeDirectory($path, 0777, true, true); 22 | 23 | $files = array_diff(scandir($path), array('.', '..')); 24 | arsort($files); 25 | 26 | // Calling 27 | $stream = fopen('php://stdout', 'w+'); 28 | $output = new CoreStreamOutput($stream, function ($line) { 29 | return strpos($line, 'not found') === false; 30 | }); 31 | 32 | $command = "migrate:reset --realpath --path=" . $path; 33 | if ($this->option('force')) $command .= ' --force'; 34 | Artisan::call($command, [], $output); 35 | 36 | return 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeCast.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 16 | 17 | // CREATE CASTS DIRECTORY IF NOT FOUND 18 | if (!file_exists($casts = $this->getPath('Casts'))) 19 | File::makeDirectory($casts, 0777, true, true); 20 | 21 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/cast.stub')); 22 | $content = str_replace('{{ namespace }}', $this->getNamespace('Casts'), $content); 23 | 24 | // SAVING CAST 25 | if (file_exists($path = $this->getPath('Casts/' . $this->fullName . '.php'))) { 26 | $this->error('Cast is already exists!'); 27 | return false; 28 | } 29 | 30 | if (!File::isDirectory($dir = dirname($path))) 31 | File::makeDirectory($dir, 0755, true, true); 32 | 33 | if (File::put($path, $content)) { 34 | $this->info('Cast created successfully.'); 35 | } else { 36 | $this->warn('There is something wrong.'); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeEvent.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 16 | 17 | // CREATE EVENTS DIRECTORY IF NOT FOUND 18 | if (!file_exists($events = $this->getPath('Events'))) 19 | File::makeDirectory($events, 0777, true, true); 20 | 21 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/event.stub')); 22 | $content = str_replace('{{ namespace }}', $this->getNamespace('Events'), $content); 23 | 24 | // SAVING EVENT 25 | if (file_exists($path = $this->getPath('Events/' . $this->fullName . '.php'))) { 26 | $this->error('Event is already exists!'); 27 | return false; 28 | } 29 | 30 | if (!File::isDirectory($dir = dirname($path))) 31 | File::makeDirectory($dir, 0755, true, true); 32 | 33 | if (File::put($path, $content)) { 34 | $this->info('Event created successfully.'); 35 | } else { 36 | $this->warn('There is something wrong.'); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/observer.stub: -------------------------------------------------------------------------------- 1 | condition = $condition; 25 | } 26 | 27 | /** 28 | * {@inheritdoc} 29 | */ 30 | protected function doWrite(string $message, bool $newline): void 31 | { 32 | if ($this->condition && !(call_user_func($this->condition, $message))) return; 33 | 34 | parent::doWrite($message, $newline); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeRule.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CREATE RULES DIRECTORY IF NOT FOUND 19 | if (!file_exists($rules = $this->getPath('Rules'))) 20 | File::makeDirectory($rules, 0777, true, true); 21 | 22 | // STUB 23 | $stubContent = file_get_contents(__DIR__ . '/stubs/rule.stub'); 24 | $stubContent = str_replace('{{ class }}', $this->name, $stubContent); 25 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Rules'), $stubContent); 26 | 27 | // SAVING SEEDER 28 | if (file_exists($path = $this->getPath('Rules/' . $this->fullName . '.php'))) { 29 | $this->error('Rule is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $stubContent)) { 37 | $this->info('Rule created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/notification.stub: -------------------------------------------------------------------------------- 1 | line('The introduction to the notification.') 45 | ->action('Notification Action', url('/')) 46 | ->line('Thank you for using our application!'); 47 | } 48 | 49 | /** 50 | * Get the array representation of the notification. 51 | * 52 | * @param mixed $notifiable 53 | * @return array 54 | */ 55 | public function toArray($notifiable) 56 | { 57 | return [ 58 | // 59 | ]; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeProvider.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CREATE PROVIDERS DIRECTORY IF NOT FOUND 19 | if (!file_exists($requests = $this->getPath('Providers'))) 20 | File::makeDirectory($requests, 0777, true, true); 21 | 22 | // PROVIDER NAME 23 | $this->appendName(substr(strtolower($this->name), -8) != 'provider', 'Provider'); 24 | 25 | // STUB 26 | $stubContent = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/provider.stub')); 27 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Providers'), $stubContent); 28 | 29 | // SAVING REQUEST 30 | if (file_exists($path = $this->getPath('Providers/' . $this->fullName . '.php'))) { 31 | $this->error('Provider is already exists!'); 32 | return false; 33 | } 34 | 35 | if (!File::isDirectory($dir = dirname($path))) 36 | File::makeDirectory($dir, 0755, true, true); 37 | 38 | if (File::put($path, $stubContent)) { 39 | $this->info('Provider created successfully.'); 40 | } else { 41 | $this->warn('There is something wrong.'); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeSeeder.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CREATE SEEDERS DIRECTORY IF NOT FOUND 19 | if (!file_exists($seeders = $this->getPath('database/seeders'))) 20 | File::makeDirectory($seeders, 0777, true, true); 21 | 22 | // SEEDER NAME 23 | $this->appendName(substr(strtolower($this->name), -6) != 'seeder', 'Seeder'); 24 | 25 | // STUB 26 | $stubContent = file_get_contents(__DIR__ . '/stubs/seeder.stub'); 27 | $stubContent = str_replace('{{ class }}', $this->name, $stubContent); 28 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('database/seeders'), $stubContent); 29 | 30 | // SAVING SEEDER 31 | if (file_exists($path = $this->getPath('database/seeders/' . $this->fullName . '.php'))) { 32 | $this->error('Seeder is already exists!'); 33 | return false; 34 | } 35 | 36 | if (!File::isDirectory($dir = dirname($path))) 37 | File::makeDirectory($dir, 0755, true, true); 38 | 39 | if (File::put($path, $stubContent)) { 40 | $this->info('Seeder created successfully.'); 41 | } else { 42 | $this->warn('There is something wrong.'); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Core/Commands/Test.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 25 | 26 | // COMMAND 27 | $command = 'php artisan test app/Modules/' . $this->module . '/tests'; 28 | 29 | if ($this->option('list')) { 30 | $command .= ' --list-tests'; 31 | } else { 32 | if ($filter = $this->option('filter')) $command .= ' --filter=' . $filter; 33 | if ($this->option('stop-on-failure')) $command .= ' --stop-on-failure'; 34 | if ($this->option('coverage')) $command .= ' --coverage'; 35 | if ($this->option('profile')) $command .= ' --profile'; 36 | if ($this->option('parallel')) $command .= ' --parallel'; 37 | } 38 | 39 | $process = Process::fromShellCommandline($command); 40 | $process->setPty(true); 41 | $process->run(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Core/Commands/DBSeed.php: -------------------------------------------------------------------------------- 1 | argument('name')) . DIRECTORY_SEPARATOR . 'seeders'; 34 | 35 | if (!file_exists($seeders)) { 36 | $this->error('Seeders directory has not been found.'); 37 | return false; 38 | } 39 | 40 | // Command 41 | $command = "db:seed --class="; 42 | 43 | // Options 44 | $command .= implode('\\\\', [ 45 | '\\App', 46 | 'Modules', 47 | str_replace('/', '\\\\', $this->argument('name')), 48 | 'database', 49 | 'seeders', 50 | $this->option('class') ?? 'DatabaseSeeder' 51 | ]); 52 | 53 | if ($this->option('force')) $command .= ' --force'; 54 | 55 | // Calling 56 | return Artisan::call($command, [], $this->getOutput()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | PHP Version : >= 7.4 5 | Laravel Version : >= 8.0 6 | License 7 |
8 | Source 9 | Packagist Version 10 | Packagist Downloads 11 |

12 | 13 |

Laravel Modulator

14 |
HMVC creating and handling in an easy and simple way.
15 | 16 | 17 | ## Documentation 18 | 19 | You can find the detailed documentation here in [Laravel Modulator Documentation](https://pharaonic.io/packages/laravel/modulator). 20 | 21 | ## Contributing 22 | 23 | Thank you for considering contributing to this package! Be one of Pharaonic team. 24 | 25 | ## License 26 | 27 | This package is an open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). 28 | -------------------------------------------------------------------------------- /src/Core/ModulesFinder.php: -------------------------------------------------------------------------------- 1 | manifestPath = app()->bootstrapPath('cache/modulator-providers.php'); 17 | 18 | if (File::exists($this->manifestPath)) { 19 | $this->cached = true; 20 | $this->list = require($this->manifestPath); 21 | } 22 | } 23 | 24 | private function find() 25 | { 26 | $this->list = []; 27 | $modules = modules(); 28 | 29 | if (count($modules) > 0) { 30 | // CREATE MAIN SERVICE PROVIDER 31 | if (!file_exists($SP = app_path('Modules/ServiceProvider.php'))) { 32 | File::ensureDirectoryExists(module_path()); 33 | File::copy(str_replace('/', DIRECTORY_SEPARATOR, __DIR__ . '/Core/Commands/stubs/ServiceProvider.php'), $SP); 34 | } 35 | 36 | foreach ($modules as $module) { 37 | foreach (getFiles(module_path($module, 'Providers')) as $provider) { 38 | $this->list[] = 'App\Modules\\' . $module . '\Providers\\' . $provider->getFilenameWithoutExtension(); 39 | } 40 | } 41 | } 42 | } 43 | 44 | private function write() 45 | { 46 | if (!is_writable(dirname($this->manifestPath))) { 47 | throw new Exception('The ' . dirname($this->manifestPath) . ' directory must be present and writable.'); 48 | } 49 | 50 | File::put($this->manifestPath, 'list, true) . ';', true); 51 | } 52 | 53 | public function build() 54 | { 55 | $this->find(); 56 | $this->write(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Core/Commands/MigrateRefresh.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 22 | 23 | // CHECK IF MIGRATIONS NOT EXISTS 24 | if (!file_exists($migrations = module_database_path($this->module, 'migrations'))) 25 | File::makeDirectory($migrations, 0777, true, true); 26 | 27 | // Command 28 | $command = "migrate:refresh --path=" . $this->getShortPath('database/migrations'); 29 | 30 | // Options 31 | if ($this->option('force')) $command .= ' --force'; 32 | if ($this->option('seed')) $command .= ' --seed'; 33 | if ($seeder = $this->option('seeder')) $command .= ' --seeder=' . $seeder; 34 | if ($step = $this->option('step')) $command .= ' --step=' . $step; 35 | 36 | // Calling 37 | $stream = fopen('php://stdout', 'w+'); 38 | $output = new CoreStreamOutput($stream, function ($line) { 39 | return strpos($line, 'not found') === false; 40 | }); 41 | 42 | Artisan::call($command, [], $output); 43 | fclose($stream); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeChannel.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CREATE BROADCASTING DIRECTORY IF NOT FOUND 19 | if (!file_exists($broadcasting = $this->getPath('Broadcasting'))) 20 | File::makeDirectory($broadcasting, 0777, true, true); 21 | 22 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/broadcasting.stub')); 23 | $content = str_replace('{{ namespace }}', $this->getNamespace('Broadcasting'), $content); 24 | $model = config('auth.providers.' . config('auth.guards.' . config('auth.defaults.guard') . '.provider') . '.model'); 25 | $content = str_replace('{{ namespacedModel }}', $model, $content); 26 | 27 | $model = explode('\\', $model); 28 | $model = $model[count($model) - 1]; 29 | $content = str_replace('{{ model }}', $model, $content); 30 | $content = str_replace('{{ modelVariable }}', Str::camel($model), $content); 31 | 32 | // SAVING BROADCASTING 33 | if (file_exists($path = $this->getPath('Broadcasting/' . $this->fullName . '.php'))) { 34 | $this->error('Channel is already exists!'); 35 | return false; 36 | } 37 | 38 | if (!File::isDirectory($dir = dirname($path))) 39 | File::makeDirectory($dir, 0755, true, true); 40 | 41 | if (File::put($path, $content)) { 42 | $this->info('Channel created successfully.'); 43 | } else { 44 | $this->warn('There is something wrong.'); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeEnum.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE ENUMS DIRECTORY IF NOT FOUND 21 | if (!file_exists($enums = $this->getPath('Enums'))) 22 | File::makeDirectory($enums, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/enum.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Enums'), $content); 26 | 27 | // SAVING ENUM 28 | if (file_exists($path = $this->getPath('Enums/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Enum is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Enum created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Enums/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeScope.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE SCOPES DIRECTORY IF NOT FOUND 21 | if (!file_exists($scopes = $this->getPath('Scopes'))) 22 | File::makeDirectory($scopes, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/scope.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Scopes'), $content); 26 | 27 | // SAVING SCOPE 28 | if (file_exists($path = $this->getPath('Scopes/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Scope is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Scope created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Scopes/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeTrait.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE TRAITS DIRECTORY IF NOT FOUND 21 | if (!file_exists($traits = $this->getPath('Traits'))) 22 | File::makeDirectory($traits, 0777, true, true); 23 | 24 | $content = str_replace('{{ trait }}', $this->name, file_get_contents(__DIR__ . '/stubs/trait.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Traits'), $content); 26 | 27 | // SAVING TRAIT 28 | if (file_exists($path = $this->getPath('Traits/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Trait is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Trait created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Traits/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeClass.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE CLASSES DIRECTORY IF NOT FOUND 21 | if (!file_exists($classes = $this->getPath('Classes'))) 22 | File::makeDirectory($classes, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/class.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Classes'), $content); 26 | 27 | // SAVING CLASS 28 | if (file_exists($path = $this->getPath('Classes/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Class is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Class created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Classes/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeAction.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE ACTIONS DIRECTORY IF NOT FOUND 21 | if (!file_exists($actions = $this->getPath('Actions'))) 22 | File::makeDirectory($actions, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/action.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Actions'), $content); 26 | 27 | // SAVING action 28 | if (file_exists($path = $this->getPath('Actions/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Action is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Action created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Actions/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeObserver.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 17 | 18 | // CREATE OBSERVERS DIRECTORY IF NOT FOUND 19 | if (!file_exists($observers = $this->getPath('Observers'))) 20 | File::makeDirectory($observers, 0777, true, true); 21 | 22 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/observer' . ($this->option('model') ? null : '.plain') . '.stub')); 23 | $content = str_replace('{{ namespace }}', $this->getNamespace('Observers'), $content); 24 | 25 | if ($this->option('model')) { 26 | $model = $this->option('model'); 27 | $content = str_replace('{{ namespacedModel }}', $model, $content); 28 | 29 | $model = explode('\\', $model); 30 | $model = $model[count($model) - 1]; 31 | $content = str_replace('{{ model }}', $model, $content); 32 | $content = str_replace('{{ modelVariable }}', Str::camel($model), $content); 33 | } 34 | 35 | // SAVING OBSERVER 36 | if (file_exists($path = $this->getPath('Observers/' . $this->fullName . '.php'))) { 37 | $this->error('Observer is already exists!'); 38 | return false; 39 | } 40 | 41 | if (!File::isDirectory($dir = dirname($path))) 42 | File::makeDirectory($dir, 0755, true, true); 43 | 44 | if (File::put($path, $content)) { 45 | $this->info('Observer created successfully.'); 46 | } else { 47 | $this->warn('There is something wrong.'); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeFactory.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 16 | 17 | // CREATE FACTORIES DIRECTORY IF NOT FOUND 18 | if (!file_exists($factories = $this->getPath('database/factories'))) 19 | File::makeDirectory($factories, 0777, true, true); 20 | 21 | // FACTORY NAME 22 | $this->appendName(substr(strtolower($this->name), -7) != 'factory', 'Factory'); 23 | $fullNameWithoutFactory = substr($this->fullName, 0, -7); 24 | $nameWithoutFactory = substr($this->name, 0, -7); 25 | 26 | // STUB 27 | $stubContent = file_get_contents(__DIR__ . '/stubs/factory.stub'); 28 | $stubContent = str_replace('{{ factory }}', $this->name, $stubContent); 29 | $stubContent = str_replace('{{ factoryNamespace }}', $this->getNamespace('database/factories'), $stubContent); 30 | $stubContent = str_replace('{{ namespacedModel }}', $this->getNamespace('Models/' . $fullNameWithoutFactory, false), $stubContent); 31 | $stubContent = str_replace('{{ model }}', $nameWithoutFactory, $stubContent); 32 | 33 | 34 | // SAVING FACTORY 35 | if (file_exists($path = $this->getPath('database/factories/' . $this->fullName . '.php'))) { 36 | $this->error('Factory is already exists!'); 37 | return false; 38 | } 39 | 40 | if (!File::isDirectory($dir = dirname($path))) 41 | File::makeDirectory($dir, 0755, true, true); 42 | 43 | if (File::put($path, $stubContent)) { 44 | $this->info('Factory created successfully.'); 45 | } else { 46 | $this->warn('There is something wrong.'); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeService.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE SERVICES DIRECTORY IF NOT FOUND 21 | if (!file_exists($services = $this->getPath('Services'))) 22 | File::makeDirectory($services, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/service.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Services'), $content); 26 | 27 | // SAVING SERVICE CLASS 28 | if (file_exists($path = $this->getPath('Services/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Service is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Service created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Services/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeMiddleware.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE MIDDLEWARES DIRECTORY IF NOT FOUND 21 | if (!file_exists($mails = $this->getPath('Http/Middleware'))) 22 | File::makeDirectory($mails, 0777, true, true); 23 | 24 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/middleware.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Http/Middleware'), $content); 26 | 27 | // SAVING MIDDLEWARE 28 | if (file_exists($path = $this->getPath('Http/Middleware/' . $this->fullName . '.php'))) { 29 | $this->error('Middleware is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Middleware created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Http/Middleware/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeJob.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 20 | 21 | // CREATE JOBS DIRECTORY IF NOT FOUND 22 | if (!file_exists($jobs = $this->getPath('Jobs'))) 23 | File::makeDirectory($jobs, 0777, true, true); 24 | 25 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/job' . (!$this->option('sync') ? '.queued' : null) . '.stub')); 26 | $content = str_replace('{{ namespace }}', $this->getNamespace('Jobs'), $content); 27 | 28 | // SAVING JOB 29 | if (file_exists($path = $this->getPath('Jobs/' . $this->fullName . '.php'))) { 30 | $this->error('Job is already exists!'); 31 | return false; 32 | } 33 | 34 | if (!File::isDirectory($dir = dirname($path))) 35 | File::makeDirectory($dir, 0755, true, true); 36 | 37 | if (File::put($path, $content)) { 38 | $this->info('Job created successfully.'); 39 | } else { 40 | $this->warn('There is something wrong.'); 41 | } 42 | 43 | // CREATE TEST 44 | if ($this->option('test') || $this->option('pest')) { 45 | $command = 'module:make:test ' . $this->module . ' Jobs/' . $this->fullName; 46 | $command .= $this->option('pest') ? ' --pest' : null; 47 | Artisan::call($command, [], $this->getOutput()); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeInterface.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE INTERFACES DIRECTORY IF NOT FOUND 21 | if (!file_exists($interfaces = $this->getPath('Interfaces'))) 22 | File::makeDirectory($interfaces, 0777, true, true); 23 | 24 | $content = str_replace('{{ interface }}', $this->name, file_get_contents(__DIR__ . '/stubs/interface.stub')); 25 | $content = str_replace('{{ namespace }}', $this->getNamespace('Interfaces'), $content); 26 | 27 | // SAVING INTERFACE 28 | if (file_exists($path = $this->getPath('Interfaces/' . $this->fullName . '.php')) && !$this->option('force')) { 29 | $this->error('Interface is already exists!'); 30 | return false; 31 | } 32 | 33 | if (!File::isDirectory($dir = dirname($path))) 34 | File::makeDirectory($dir, 0755, true, true); 35 | 36 | if (File::put($path, $content)) { 37 | $this->info('Interface created successfully.'); 38 | } else { 39 | $this->warn('There is something wrong.'); 40 | } 41 | 42 | // CREATE TEST 43 | if ($this->option('test') || $this->option('pest')) { 44 | $command = 'module:make:test ' . $this->module . ' Interfaces/' . $this->fullName; 45 | $command .= $this->option('pest') ? ' --pest' : null; 46 | Artisan::call($command, [], $this->getOutput()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeRequest.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE REQUESTS DIRECTORY IF NOT FOUND 21 | if (!file_exists($requests = $this->getPath('Http/Requests'))) 22 | File::makeDirectory($requests, 0777, true, true); 23 | 24 | // Jsonable 25 | if ($this->option('json')) { 26 | if (class_exists(Json::class)) { 27 | return Artisan::call('jsonable:request App/Modules/' . $this->argument('module') . '/Http/Requests/' . $this->argument('name'), [], $this->getOutput()); 28 | } else { 29 | return $this->warn('Jsonable Package has not been found.'); 30 | } 31 | } 32 | 33 | // STUB 34 | $stubContent = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/request.stub')); 35 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Http\Requests'), $stubContent); 36 | 37 | // SAVING REQUEST 38 | if (file_exists($path = $this->getPath('Http/Requests/' . $this->fullName . '.php'))) { 39 | $this->error('Request is already exists!'); 40 | return false; 41 | } 42 | 43 | if (!File::isDirectory($dir = dirname($path))) 44 | File::makeDirectory($dir, 0755, true, true); 45 | 46 | if (File::put($path, $stubContent)) { 47 | $this->info('Request created successfully.'); 48 | } else { 49 | $this->warn('There is something wrong.'); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Commands/MigrateFresh.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 24 | 25 | // CHECK IF MIGRATIONS NOT EXISTS 26 | if (!file_exists($migrations = module_database_path($this->module, 'migrations'))) 27 | File::makeDirectory($migrations, 0777, true, true); 28 | 29 | // Command 30 | $command = "migrate:fresh --path=" . $this->getShortPath('database/migrations'); 31 | 32 | // Options 33 | if ($this->option('drop-views')) $command .= ' --drop-views'; 34 | if ($this->option('drop-types')) $command .= ' --drop-types'; 35 | if ($this->option('force')) $command .= ' --force'; 36 | if ($this->option('seed')) $command .= ' --seed'; 37 | if ($seeder = $this->option('seeder')) $command .= ' --seeder=' . $seeder; 38 | if ($step = $this->option('step')) $command .= ' --step=' . $step; 39 | if ($schema = $this->option('schema-path')) $command .= ' --schema-path=' . $schema; 40 | 41 | // Calling 42 | return Artisan::call($command, [], $this->getOutput()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/controller.stub: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 23 | 24 | $command = "route:list --name=$this->slug"; 25 | 26 | if ($this->option('compact')) { 27 | if (version_compare(app()->version(), '8', '>')) { 28 | $this->warn('Compact option just supported in versions that lower than 9.x'); 29 | return; 30 | } else { 31 | $command .= ' --compact'; 32 | } 33 | } 34 | 35 | if ($this->option('columns')) { 36 | if (version_compare(app()->version(), '8', '>')) { 37 | $this->warn('Columns option just supported in versions that lower than 9.x'); 38 | return; 39 | } else { 40 | $command .= ' --columns'; 41 | } 42 | } 43 | 44 | if ($this->option('reverse')) $command .= ' --reverse'; 45 | if ($this->option('json')) $command .= ' --json'; 46 | if ($method = $this->option('method')) $command .= ' --method=' . $method; 47 | if ($sort = $this->option('sort')) $command .= ' --sort=' . $sort; 48 | 49 | return Artisan::call($command, [], $this->getOutput()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeCommand.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 20 | 21 | // CREATE COMMANDS DIRECTORY IF NOT FOUND 22 | if (!file_exists($commands = $this->getPath('Commands'))) 23 | File::makeDirectory($commands, 0777, true, true); 24 | 25 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/console.stub')); 26 | $content = str_replace('{{ namespace }}', $this->getNamespace('Commands'), $content); 27 | $content = str_replace('{{ command }}', $this->option('command'), $content); 28 | 29 | // SAVING COMMAND 30 | if (file_exists($path = $this->getPath('Commands/' . $this->fullName . '.php')) && !$this->option('force')) { 31 | $this->error('Command is already exists!'); 32 | return false; 33 | } 34 | 35 | if (!File::isDirectory($dir = dirname($path))) 36 | File::makeDirectory($dir, 0755, true, true); 37 | 38 | if (File::put($path, $content)) { 39 | $this->info('Command created successfully.'); 40 | } else { 41 | $this->warn('There is something wrong.'); 42 | } 43 | 44 | 45 | // CREATE TEST 46 | if ($this->option('test') || $this->option('pest')) { 47 | $command = 'module:make:test ' . $this->module . ' Commands/' . $this->fullName; 48 | $command .= $this->option('pest') ? ' --pest' : null; 49 | Artisan::call($command, [], $this->getOutput()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeResource.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 20 | 21 | // CREATE RESOURCES DIRECTORY IF NOT FOUND 22 | if (!file_exists($resources = $this->getPath('Http/Resources'))) 23 | File::makeDirectory($resources, 0777, true, true); 24 | 25 | // Jsonable 26 | if ($this->option('json')) { 27 | if (class_exists(Json::class)) { 28 | return Artisan::call('jsonable:resource App/Modules/' . $this->argument('module') . '/Http/Resources/' . $this->argument('name'), [], $this->getOutput()); 29 | } else { 30 | return $this->warn('Jsonable Package has not been found.'); 31 | } 32 | } 33 | 34 | // STUB 35 | $stubContent = file_get_contents(__DIR__ . '/stubs/resource' . ($this->option('collection') ? '-collection' : null) . '.stub'); 36 | $stubContent = str_replace('{{ class }}', $this->name, $stubContent); 37 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Http/Resources'), $stubContent); 38 | 39 | // SAVING TEST 40 | if (file_exists($path = $this->getPath('Http/Resources/' . $this->fullName . '.php'))) { 41 | $this->error('Resource is already exists!'); 42 | return false; 43 | } 44 | 45 | if (!File::isDirectory($dir = dirname($path))) 46 | File::makeDirectory($dir, 0755, true, true); 47 | 48 | if (File::put($path, $stubContent)) { 49 | $this->info('Resource' . ($this->option('collection') ? ' collection' : null) . ' created successfully.'); 50 | } else { 51 | $this->warn('There is something wrong.'); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeMail.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 21 | 22 | // CREATE MAILS DIRECTORY IF NOT FOUND 23 | if (!file_exists($mails = $this->getPath('Mail'))) 24 | File::makeDirectory($mails, 0777, true, true); 25 | 26 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/mail.stub')); 27 | $content = str_replace('{{ namespace }}', $this->getNamespace('Mail'), $content); 28 | 29 | $markdown = $this->option('markdown'); 30 | if ($markdown != 'false') 31 | $content = str_replace("view('view.name')", "markdown('$markdown')", $content); 32 | 33 | // SAVING MAIL 34 | if (file_exists($path = $this->getPath('Mail/' . $this->fullName . '.php')) && !$this->option('force')) { 35 | $this->error('Mail is already exists!'); 36 | return false; 37 | } 38 | 39 | if (!File::isDirectory($dir = dirname($path))) 40 | File::makeDirectory($dir, 0755, true, true); 41 | 42 | if (File::put($path, $content)) { 43 | $this->info('Mail created successfully.'); 44 | } else { 45 | $this->warn('There is something wrong.'); 46 | } 47 | 48 | // CREATE TEST 49 | if ($this->option('test') || $this->option('pest')) { 50 | $command = 'module:make:test ' . $this->module . ' Mail/' . $this->fullName; 51 | $command .= $this->option('pest') ? ' --pest' : null; 52 | Artisan::call($command, [], $this->getOutput()); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/module/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole(); 27 | $module = studlyToSlug(AppServiceProvider::$module); 28 | 29 | $this->routes(function () use ($isConsole, $module) { 30 | $this->mapApiRoutes($isConsole, $module); 31 | $this->mapWebRoutes($isConsole, $module); 32 | }); 33 | } 34 | 35 | /** 36 | * Load API routes 37 | * 38 | * @param boolean $isConsole 39 | * @param string $module 40 | * @return void 41 | */ 42 | private function mapApiRoutes(bool $isConsole, string $module) 43 | { 44 | $routes = Route::middleware('api') 45 | ->namespace($this->namespace) 46 | ->prefix('api/' . $module) 47 | ->name($module . '.'); 48 | 49 | if ($isConsole && in_array('module:routes', $_SERVER['argv'] ?? [])) { 50 | $routes->name($module . '.'); 51 | } 52 | 53 | $routes->group(module_path(AppServiceProvider::$module, 'routes/api.php')); 54 | } 55 | 56 | /** 57 | * Load Web routes 58 | * 59 | * @param boolean $isConsole 60 | * @param string $module 61 | * @return void 62 | */ 63 | private function mapWebRoutes(bool $isConsole, string $module) 64 | { 65 | $routes = Route::middleware('web') 66 | ->namespace($this->namespace) 67 | ->prefix($module) 68 | ->name($module . '.'); 69 | 70 | if ($isConsole && in_array('module:routes', $_SERVER['argv'] ?? [])) { 71 | $routes->name($module . '.'); 72 | } 73 | 74 | $routes->group(module_path(AppServiceProvider::$module, 'routes/web.php')); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Core/Commands/stubs/policy.stub: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 21 | 22 | // CREATE NOTIFICATIONS DIRECTORY IF NOT FOUND 23 | if (!file_exists($notifications = $this->getPath('Notifications'))) 24 | File::makeDirectory($notifications, 0777, true, true); 25 | 26 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/notification.stub')); 27 | $content = str_replace('{{ namespace }}', $this->getNamespace('Notifications'), $content); 28 | 29 | if ($this->option('markdown')) 30 | $content = str_replace([ 31 | PHP_EOL . " ->line('The introduction to the notification.')", 32 | PHP_EOL . " ->action('Notification Action', url('/'))", 33 | PHP_EOL . " ->line('Thank you for using our application!');" 34 | ], [ 35 | '->markdown(\'' . $this->option('markdown') . '\');', 36 | '', 37 | '' 38 | ], $content); 39 | 40 | 41 | // SAVING NOTIFICATION 42 | if (file_exists($path = $this->getPath('Notifications/' . $this->fullName . '.php')) && !$this->option('force')) { 43 | $this->error('Notification is already exists!'); 44 | return false; 45 | } 46 | 47 | if (!File::isDirectory($dir = dirname($path))) 48 | File::makeDirectory($dir, 0755, true, true); 49 | 50 | if (File::put($path, $content)) { 51 | $this->info('Notification created successfully.'); 52 | } else { 53 | $this->warn('There is something wrong.'); 54 | } 55 | 56 | 57 | // CREATE TEST 58 | if ($this->option('test') || $this->option('pest')) { 59 | $command = 'module:make:test ' . $this->module . ' Notifications/' . $this->fullName; 60 | $command .= $this->option('pest') ? ' --pest' : null; 61 | Artisan::call($command, [], $this->getOutput()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeComponent.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 18 | 19 | // CREATE COMPONENTS DIRECTORY IF NOT FOUND 20 | if (!file_exists($components = $this->getPath('View/Components'))) 21 | File::makeDirectory($components, 0777, true, true); 22 | 23 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/component.stub')); 24 | $content = str_replace('{{ namespace }}', $this->getNamespace('View/Components'), $content); 25 | 26 | if ($this->option('inline')) { 27 | $content = str_replace( 28 | '{{ view }}', 29 | '<<<\'blade\'' . PHP_EOL . '
' . PHP_EOL . '' . PHP_EOL . '
' . PHP_EOL . 'blade', 30 | $content 31 | ); 32 | } else { 33 | $sPath = array_map(function ($dir) { 34 | return studlyToSlug($dir); 35 | }, explode('/', $this->fullName)); 36 | 37 | $view = $this->slug . '::components.' . implode('.', $sPath); 38 | $content = str_replace('{{ view }}', 'view(\'' . $view . '\')', $content); 39 | 40 | } 41 | 42 | // SAVING COMMAND 43 | if (file_exists($path = $this->getPath('View/Components/' . $this->fullName . '.php')) && !$this->option('force')) { 44 | $this->error('Component is already exists!'); 45 | return false; 46 | } 47 | 48 | if (!File::isDirectory($dir = dirname($path))) 49 | File::makeDirectory($dir, 0755, true, true); 50 | 51 | if (File::put($path, $content)) { 52 | $this->info('Component created successfully.'); 53 | } else { 54 | $this->warn('There is something wrong.'); 55 | } 56 | 57 | 58 | // CREATE VIEW OF NON-INLINE 59 | if (!$this->option('inline')) { 60 | $view = module_resource_path($this->module, 'views/components/' . implode('/', $sPath) . '.blade.php'); 61 | 62 | if (!File::isDirectory($dir = dirname($view))) 63 | File::makeDirectory($dir, 0755, true, true); 64 | 65 | if (File::put($view, '
' . PHP_EOL . ' ' . PHP_EOL . '
')) { 66 | $this->info('Component-View created successfully.'); 67 | } else { 68 | $this->warn('There is something wrong.'); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeController.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 22 | 23 | // CREATE CONTROLLERS DIRECTORY IF NOT FOUND 24 | if (!file_exists($controllers = $this->getPath('Http/Controllers'))) 25 | File::makeDirectory($controllers, 0777, true, true); 26 | 27 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/controller.stub')); 28 | $content = str_replace('{{ namespace }}', $this->getNamespace('Http/Controllers'), $content); 29 | 30 | // MODEL 31 | if ($model = $this->option('model')) { 32 | $content = str_replace('{{ namespacedModel }}', $model, $content); 33 | $model = explode('\\', $model); 34 | $model = array_pop($model); 35 | $content = str_replace('{{ model }}', $model, $content); 36 | $content = str_replace('{{ modelVariable }}', Str::camel($model), $content); 37 | } else { 38 | $content = str_replace("\nuse {{ namespacedModel }};", '', $content); 39 | $content = str_replace('\{{ namespacedModel }}', 'int', $content); 40 | $content = str_replace('{{ model }}', 'int', $content); 41 | $content = str_replace('{{ modelVariable }}', 'id', $content); 42 | } 43 | 44 | // SAVING CONTROLLER 45 | if (file_exists($path = $this->getPath('Http/Controllers/' . $this->fullName . '.php')) && !$this->option('force')) { 46 | $this->error('Controller is already exists!'); 47 | return false; 48 | } 49 | 50 | if (!File::isDirectory($dir = dirname($path))) 51 | File::makeDirectory($dir, 0755, true, true); 52 | 53 | if (File::put($path, $content)) { 54 | $this->info('Controller created successfully.'); 55 | } else { 56 | $this->warn('There is something wrong.'); 57 | } 58 | 59 | 60 | // CREATE TEST 61 | if ($this->option('test') || $this->option('pest')) { 62 | if(substr(strtolower($this->fullName), -10) == 'controller') 63 | $this->fullName = substr($this->fullName, 0, -10); 64 | 65 | $command = 'module:make:test ' . $this->module . ' Http/Controllers/' . $this->fullName; 66 | $command .= $this->option('pest') ? ' --pest' : null; 67 | Artisan::call($command, [], $this->getOutput()); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Core/Command.php: -------------------------------------------------------------------------------- 1 | module = $this->argument('module'); 28 | $this->slug = studlyToSlug($this->module); 29 | 30 | if ($this->hasArgument('name')) { 31 | $this->fullName = $this->argument('name'); 32 | $this->sliceName = explode('/', $this->fullName); 33 | $this->name = Str::studly(array_pop($this->sliceName)); 34 | $this->sliceName = implode(DIRECTORY_SEPARATOR, $this->sliceName); 35 | } 36 | } 37 | 38 | /** 39 | * Generate module namespace 40 | * 41 | * @param string|null $ns 42 | * @param boolean $append 43 | * @return string 44 | */ 45 | protected function getNamespace(?string $ns = null, bool $append = true) 46 | { 47 | if ($ns) { 48 | $ns = explode( 49 | '/', 50 | trim($ns, '/') . 51 | ($append ? ($this->sliceName ? '/' . $this->sliceName : null) : null) 52 | ); 53 | $ns = '\\' . implode('\\', $ns); 54 | } 55 | 56 | return \App\Modules::class . '\\' . str_replace('/', '\\', $this->module) . $ns; 57 | } 58 | 59 | /** 60 | * Check Module Existance 61 | * 62 | * @return bool 63 | */ 64 | protected function moduleExists() 65 | { 66 | if (!file_exists(module_path($this->module))) { 67 | $this->error(' Module has not been found. '); 68 | return false; 69 | } 70 | 71 | return true; 72 | } 73 | 74 | /** 75 | * Get Full Path 76 | * 77 | * @param string $path 78 | * @return string 79 | */ 80 | protected function getPath(string $path) 81 | { 82 | return module_path($this->module, $path); 83 | } 84 | 85 | /** 86 | * Get Short Path 87 | * 88 | * @param string $path 89 | * @return string 90 | */ 91 | protected function getShortPath(string $path) 92 | { 93 | $path = 'app/Modules/' . $this->module . '/' . $path; 94 | return str_replace('/', DIRECTORY_SEPARATOR, $path); 95 | } 96 | 97 | /** 98 | * Append a text to the name 99 | * 100 | * @param boolean $condition 101 | * @param string $name 102 | * @return void 103 | */ 104 | protected function appendName(bool $condition, string $text) 105 | { 106 | if ($condition) { 107 | $this->name .= $text; 108 | $this->fullName .= $text; 109 | } 110 | } 111 | 112 | /** 113 | * Execute the console command. 114 | * 115 | * @return int 116 | */ 117 | public function handle() 118 | { 119 | $this->prepare(); 120 | $this->exec(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeException.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 18 | 19 | // CREATE EXCEPTIONS DIRECTORY IF NOT FOUND 20 | if (!file_exists($exceptions = $this->getPath('Exceptions'))) 21 | File::makeDirectory($exceptions, 0777, true, true); 22 | 23 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/exception.stub')); 24 | $content = str_replace('{{ namespace }}', $this->getNamespace('Exceptions'), $content); 25 | 26 | if ($this->option('report')) { 27 | $content = str_replace('{{ REPORT:START }}', '', $content); 28 | $content = str_replace('{{ REPORT:END }}', '', $content); 29 | } else { 30 | $content = $this->deleteStringBetween('{{ REPORT:START }}', '{{ REPORT:END }}', $content); 31 | } 32 | 33 | if ($this->option('render')) { 34 | $content = str_replace('{{ RENDER:START }}', '', $content); 35 | $content = str_replace('{{ RENDER:END }}', '', $content); 36 | } else { 37 | $content = $this->deleteStringBetween('{{ RENDER:START }}', '{{ RENDER:END }}', $content); 38 | } 39 | 40 | if (!$this->option('render') && !$this->option('report')) { 41 | $content = str_replace("{\n}", "{\n //\n}", $content); 42 | } else { 43 | $content = str_replace("}\n\n", "}\n", $content); 44 | $content = str_replace("{\n\n", "{\n", $content); 45 | } 46 | 47 | // SAVING EXCEPTION 48 | if (file_exists($path = $this->getPath('Exceptions/' . $this->fullName . '.php'))) { 49 | $this->error('Exception is already exists!'); 50 | return false; 51 | } 52 | 53 | if (!File::isDirectory($dir = dirname($path))) 54 | File::makeDirectory($dir, 0755, true, true); 55 | 56 | if (File::put($path, $content)) { 57 | $this->info('Exception created successfully.'); 58 | } else { 59 | $this->warn('There is something wrong.'); 60 | } 61 | } 62 | 63 | /** 64 | * Delete text between 2 strings 65 | * 66 | * @param string $beginning 67 | * @param string $end 68 | * @param string $string 69 | * @return string 70 | */ 71 | function deleteStringBetween($beginning, $end, $string) 72 | { 73 | $beginningPos = strpos($string, $beginning); 74 | $endPos = strpos($string, $end); 75 | 76 | if ($beginningPos === false || $endPos === false) 77 | return $string; 78 | 79 | $textToDelete = substr($string, $beginningPos, ($endPos + strlen($end)) - $beginningPos); 80 | 81 | return $this->deleteStringBetween($beginning, $end, str_replace($textToDelete, '', $string)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeListener.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 22 | 23 | // CREATE LISTENERS DIRECTORY IF NOT FOUND 24 | if (!file_exists($listeners = $this->getPath('Listeners'))) 25 | File::makeDirectory($listeners, 0777, true, true); 26 | 27 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/listener.stub')); 28 | $content = str_replace('{{ namespace }}', $this->getNamespace('Listeners'), $content); 29 | 30 | // QUEUED 31 | if ($this->option('queued')) { 32 | $content = str_replace('{{ interface }}', ' implements ShouldQueue', $content); 33 | $content = str_replace('{{ trait }}', 'use InteractsWithQueue;', $content); 34 | } else { 35 | $content = str_replace('{{ interface }}', '', $content); 36 | $content = str_replace(" {{ trait }}\n\n", '', $content); 37 | } 38 | 39 | // EVENT 40 | if ($event = $this->option('event')) { 41 | $content = str_replace('{{ modelNamespace }}', $event, $content); 42 | $content = str_replace("\n" . $event, "\nuse " . $event . ';', $content); 43 | $event = explode('\\', $event); 44 | $event = array_pop($event); 45 | $content = str_replace('{{ model }}', $event, $content); 46 | $content = str_replace('{{ modelVariable }}', Str::camel($event), $content); 47 | } else { 48 | $content = str_replace('{{ modelNamespace }}', 'object', $content); 49 | $content = str_replace("\nobject", '', $content); 50 | $content = str_replace('{{ model }} ', '', $content); 51 | $content = str_replace('{{ modelVariable }}', 'event', $content); 52 | } 53 | 54 | // SAVING LISTENER 55 | if (file_exists($path = $this->getPath('Listeners/' . $this->fullName . '.php'))) { 56 | $this->error('Listener is already exists!'); 57 | return false; 58 | } 59 | 60 | if (!File::isDirectory($dir = dirname($path))) 61 | File::makeDirectory($dir, 0755, true, true); 62 | 63 | if (File::put($path, $content)) { 64 | $this->info('Listener created successfully.'); 65 | } else { 66 | $this->warn('There is something wrong.'); 67 | } 68 | 69 | // CREATE TEST 70 | if ($this->option('test') || $this->option('pest')) { 71 | $command = 'module:make:test ' . $this->module . ' Listeners/' . $this->fullName; 72 | $command .= $this->option('pest') ? ' --pest' : null; 73 | Artisan::call($command, [], $this->getOutput()); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeModel.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 26 | 27 | // CREATE MODELS DIRECTORY IF NOT FOUND 28 | if (!file_exists($controllers = $this->getPath('Models'))) 29 | File::makeDirectory($controllers, 0777, true, true); 30 | 31 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/model.stub')); 32 | $content = str_replace('{{ namespace }}', $this->getNamespace('Models'), $content); 33 | 34 | // SAVING MODEL 35 | if (file_exists($path = $this->getPath('Models/' . $this->fullName . '.php')) && !$this->option('force')) { 36 | $this->error('Model is already exists!'); 37 | return false; 38 | } 39 | 40 | if (!File::isDirectory($dir = dirname($path))) 41 | File::makeDirectory($dir, 0755, true, true); 42 | 43 | if (File::put($path, $content)) { 44 | $this->info('Model created successfully.'); 45 | } else { 46 | $this->warn('There is something wrong.'); 47 | } 48 | 49 | // CREATE MIGRATION 50 | if ($this->option('migration') || $this->option('all')) { 51 | $command = 'module:make:migration ' . $this->module . ' create_' . Str::snake(Str::plural($this->name)) . '_table'; 52 | $command .= $this->option('pest') ? ' --pest' : null; 53 | Artisan::call($command, [], $this->getOutput()); 54 | } 55 | 56 | // CREATE FACTORY 57 | if ($this->option('factory') || $this->option('all')) { 58 | $command = 'module:make:factory ' . $this->module . ' ' . $this->fullName; 59 | Artisan::call($command, [], $this->getOutput()); 60 | } 61 | 62 | // CREATE SEEDER 63 | if ($this->option('seed') || $this->option('all')) { 64 | $command = 'module:make:seeder ' . $this->module . ' ' . $this->fullName; 65 | Artisan::call($command, [], $this->getOutput()); 66 | } 67 | 68 | // CREATE POLICY 69 | if ($this->option('policy') || $this->option('all')) { 70 | $command = 'module:make:policy ' . $this->module . ' ' . $this->fullName; 71 | Artisan::call($command, [], $this->getOutput()); 72 | } 73 | 74 | // CREATE TEST 75 | if ($this->option('test') || $this->option('pest')) { 76 | $command = 'module:make:test ' . $this->module . ' Models/' . $this->fullName; 77 | $command .= $this->option('pest') ? ' --pest' : null; 78 | Artisan::call($command, [], $this->getOutput()); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | isFile(); 29 | }); 30 | } 31 | } 32 | 33 | // Module Path 34 | if (!function_exists('module_path')) { 35 | function module_path(?string $module = null, ?string $extra = null) 36 | { 37 | if (!$module) return app_path('Modules'); 38 | if ($extra) $extra = implode(DIRECTORY_SEPARATOR, explode('/', $extra)); 39 | 40 | // Sub-Module 41 | if (strpos($module, '/') !== false) { 42 | $module = explode('/', $module); 43 | $moduleName = array_shift($module); 44 | 45 | $extra = trim(implode(DIRECTORY_SEPARATOR, $module) . DIRECTORY_SEPARATOR . $extra, '/'); 46 | $module = $moduleName; 47 | unset($moduleName); 48 | } 49 | 50 | return app_path('Modules') . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . $extra; 51 | } 52 | } 53 | 54 | // Get Directories List of a module 55 | if (!function_exists('getModuleDirectories')) { 56 | function getModuleDirectories(string $module) 57 | { 58 | $dir = module_path($module); 59 | if (!File::exists($dir)) return []; 60 | 61 | $mainModulesPath = module_path(); 62 | return array_map(function ($m) use ($mainModulesPath) { 63 | return str_replace($mainModulesPath . '/', '', $m); 64 | }, File::directories($dir)); 65 | } 66 | } 67 | 68 | // Modules List 69 | if (!function_exists('modules')) { 70 | /** 71 | * Get all modules names. 72 | * 73 | * @return array 74 | */ 75 | function modules() 76 | { 77 | if (!file_exists($dir = module_path())) return []; 78 | 79 | $list = []; 80 | foreach (File::directories($dir) as $module) { 81 | $module = str_replace($dir . DIRECTORY_SEPARATOR, '', $module); 82 | if (file_exists(module_path($module, 'Providers'))) { 83 | $list[] = $module; 84 | } else { 85 | $list = [...$list, ...getModuleDirectories($module)]; 86 | } 87 | } 88 | 89 | return $list; 90 | } 91 | } 92 | 93 | // Config Path 94 | if (!function_exists('module_config_path')) { 95 | function module_config_path(string $module, ?string $extra = null) 96 | { 97 | return module_path($module, 'config' . ($extra ? '/' . $extra : null)); 98 | } 99 | } 100 | 101 | // Database Path 102 | if (!function_exists('module_database_path')) { 103 | function module_database_path(string $module, ?string $extra = null) 104 | { 105 | return module_path($module, 'database' . ($extra ? '/' . $extra : null)); 106 | } 107 | } 108 | 109 | // Resources Path 110 | if (!function_exists('module_resource_path')) { 111 | function module_resource_path(string $module, ?string $extra = null) 112 | { 113 | return module_path($module, 'resources' . ($extra ? '/' . $extra : null)); 114 | } 115 | } 116 | 117 | // Convert studly to slug 118 | if (!function_exists('studlyToSlug')) { 119 | function studlyToSlug(string $text) 120 | { 121 | return Str::slug(strtolower(trim(preg_replace('/[A-Z-]/', ' $0', $text)))); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Core/Commands/Make.php: -------------------------------------------------------------------------------- 1 | name = $this->argument('name'); 34 | $this->path = module_path($this->name); 35 | 36 | $this->nameNS = str_replace('/', '\\', $this->name); 37 | $this->name = Str::studly($this->name); 38 | $this->slug = studlyToSlug($this->name); 39 | 40 | // IF EXISTS 41 | if (File::isDirectory($this->path)) 42 | return $this->error(' Module is already exists. '); 43 | 44 | // PREPARE THE MODULE MODULE 45 | $base = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR; 46 | 47 | // CREATE MAIN SERVICE PROVIDER 48 | if (!file_exists($SP = app_path('Modules/ServiceProvider.php'))) { 49 | File::ensureDirectoryExists(module_path()); 50 | File::copy($base . DIRECTORY_SEPARATOR . 'ServiceProvider.php', $SP); 51 | } 52 | 53 | if (file_exists($this->tmp = $base . 'module-tmp')) 54 | File::deleteDirectory($this->tmp); 55 | 56 | if (File::copyDirectory($base . 'module', $this->tmp)) { 57 | $this->comment('Creating a new module [' . $this->name . ']'); 58 | 59 | // CONFIG 60 | $this->inject('config/app.php'); 61 | $this->info('DONE : Config'); 62 | 63 | // DATABSE 64 | $this->inject('database/seeders/DatabaseSeeder.php'); 65 | $this->info('DONE : Database'); 66 | 67 | // PROVIDERS 68 | $this->inject('Providers/AppServiceProvider.php'); 69 | $this->inject('Providers/BroadcastServiceProvider.php'); 70 | $this->inject('Providers/EventServiceProvider.php'); 71 | $this->inject('Providers/RouteServiceProvider.php'); 72 | $this->info('DONE : Providers'); 73 | 74 | // RESOURCES 75 | $this->inject('lang/en/example.php'); 76 | $this->inject('resources/views/example.blade.php'); 77 | $this->info('DONE : Resources'); 78 | 79 | // ROUTES 80 | $this->inject('routes/api.php'); 81 | $this->inject('routes/channels.php'); 82 | $this->inject('routes/console.php'); 83 | $this->inject('routes/web.php'); 84 | $this->info('DONE : Routes'); 85 | $this->newLine(1); 86 | 87 | // COPY TO THE MAIN PATH 88 | File::copyDirectory($this->tmp, $this->path); 89 | $this->info('Module created successfully.'); 90 | 91 | app(ModulesFinder::class)->build(); 92 | 93 | // DELETE TEMP 94 | File::deleteDirectory($this->tmp); 95 | } else { 96 | $this->error(' There\'s something wrong!'); 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | /** 103 | * Inject the data 104 | * 105 | * @param string $path 106 | * @return void 107 | */ 108 | protected function inject(string $path) 109 | { 110 | $path = $this->tmp . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, explode('/', $path)); 111 | $content = file_get_contents($path); 112 | 113 | $content = str_replace('{{ module-name-namespace-double }}', str_replace('\\', '\\\\', $this->nameNS), $content); 114 | $content = str_replace('{{ module-name-namespace }}', $this->nameNS, $content); 115 | $content = str_replace('{{ module-name }}', $this->name, $content); 116 | $content = str_replace('{{ module-slug }}', $this->slug, $content); 117 | 118 | file_put_contents($path, $content); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Core/Commands/MakePolicy.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE POLICIES DIRECTORY IF NOT FOUND 21 | if (!file_exists($policies = $this->getPath('Policies'))) 22 | File::makeDirectory($policies, 0777, true, true); 23 | 24 | // POLICY NAME && GUARD 25 | $guard = $this->option('guard') ?? config('auth.defaults.guard'); 26 | 27 | if (!config('auth.guards.' . $guard)) { 28 | $this->error('Guard [ ' . $guard . ' ] has been not found.'); 29 | return false; 30 | } 31 | 32 | if (!($provider = config('auth.guards.' . $guard . '.provider'))) { 33 | $this->error('Guard\'s Provider [ ' . $guard . ' ] has been not found.'); 34 | return false; 35 | } 36 | 37 | if (!($model = config('auth.providers.' . $provider . '.model', $this->option('model')))) { 38 | $this->error('Guard\'s Provider -> Model [ ' . $guard . ' ] has been not found.'); 39 | return false; 40 | } 41 | 42 | 43 | // GENERATE POLICY 44 | if (!$this->option('model')) 45 | $content = $this->getPlainPolicy($model); 46 | else 47 | $content = $this->getPolicy($model, $this->option('model')); 48 | 49 | // SAVING POLICY 50 | if (file_exists($path = $this->getPath('Policies/' . $this->fullName . '.php'))) { 51 | $this->error('Policy is already exists!'); 52 | return false; 53 | } 54 | 55 | if (!File::isDirectory($dir = dirname($path))) 56 | File::makeDirectory($dir, 0755, true, true); 57 | 58 | if (File::put($path, $content)) { 59 | $this->info('Policy created successfully.'); 60 | } else { 61 | $this->warn('There is something wrong.'); 62 | } 63 | } 64 | 65 | protected function getPlainPolicy(string $model) 66 | { 67 | $stubContent = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/policy.plain.stub')); 68 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Policies'), $stubContent); 69 | $stubContent = str_replace('{{ namespacedUserModel }}', $model, $stubContent); 70 | 71 | return $stubContent; 72 | } 73 | 74 | protected function getPolicy(string $model, string $custom) 75 | { 76 | $stubContent = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/stubs/policy.stub')); 77 | $stubContent = str_replace('{{ namespace }}', $this->getNamespace('Policies'), $stubContent); 78 | $stubContent = str_replace('{{ namespacedUserModel }}', $model, $stubContent); 79 | 80 | $user = explode('\\', $model); 81 | $user = $user[count($user) - 1]; 82 | $stubContent = str_replace('{{ user }}', $user, $stubContent); 83 | 84 | if ($model == $custom) { 85 | $stubContent = str_replace('use {{ namespacedModel }};' . PHP_EOL, '', $stubContent); 86 | $stubContent = str_replace('{{ namespacedModel }}', $model, $stubContent); 87 | $stubContent = str_replace('{{ model }}', $user, $stubContent); 88 | $stubContent = str_replace('{{ modelVariable }}', 'model', $stubContent); 89 | } else { 90 | $stubContent = str_replace('{{ namespacedModel }}', $custom, $stubContent); 91 | 92 | $custom = explode('\\', $custom); 93 | $custom = $custom[count($custom) - 1]; 94 | $stubContent = str_replace('{{ model }}', $custom, $stubContent); 95 | $stubContent = str_replace('{{ modelVariable }}', Str::camel($custom), $stubContent); 96 | } 97 | 98 | return $stubContent; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Core/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadHelpers(); 29 | $this->loadConfig(); 30 | $this->loadViews(); 31 | $this->loadMigrations(); 32 | $this->registerCommands(); 33 | $this->loadTranslations(); 34 | 35 | Factory::guessFactoryNamesUsing(function ($modelName) { 36 | if (str_starts_with($modelName, 'App\Modules')) { 37 | $module = explode('\\', $modelName)[2]; 38 | return 'App\Modules\\' . str_replace('/', '\\', $module) . '\database\factories\\' . class_basename($modelName) . 'Factory'; 39 | } 40 | return Factory::resolveFactoryName($modelName); 41 | }); 42 | } 43 | /** 44 | * Load Module Helpers. 45 | * 46 | * @return void 47 | */ 48 | protected function loadHelpers() 49 | { 50 | if (!static::$module) 51 | return; 52 | 53 | if (file_exists($helpers = module_path(static::$module, 'helpers.php'))) { 54 | require $helpers; 55 | } 56 | } 57 | 58 | /** 59 | * Load Module Configrations. 60 | * 61 | * @return void 62 | */ 63 | protected function loadConfig() 64 | { 65 | if (!static::$module) 66 | return; 67 | 68 | if (file_exists($config = module_config_path(static::$module))) { 69 | foreach (getFiles($config) as $file) { 70 | $this->mergeConfigFrom( 71 | $file, 72 | 'modules.' . studlyToSlug(static::$module) . '.' . str_replace('.php', '', $file->getRelativePathname()) 73 | ); 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * Register all the commands of a single module. 80 | * 81 | * @return void 82 | */ 83 | protected function registerCommands() 84 | { 85 | if (!static::$module) 86 | return; 87 | 88 | if ($this->app->runningInConsole()) { 89 | if (file_exists($commands = module_path(static::$module, 'Commands'))) { 90 | $commandsList = []; 91 | 92 | foreach (getFiles($commands, true) as $file) { 93 | $ns = str_replace([$commands, DIRECTORY_SEPARATOR], ['', '\\'], $file->getPath()); 94 | $module = 'App\Modules\\' . str_replace('/', '\\', static::$module) . '\Commands\\'; 95 | 96 | if (!empty($ns)) { 97 | $module .= ltrim($ns, '\\') . '\\'; 98 | } 99 | 100 | $commandsList[] = $module . str_replace('.php', '', $file->getFileName()); 101 | } 102 | 103 | $this->commands($commandsList); 104 | } 105 | 106 | $console = module_path(static::$module, 'routes/console.php'); 107 | if (file_exists($console)) 108 | require $console; 109 | } 110 | } 111 | 112 | /** 113 | * load all translations of a single module. 114 | * 115 | * @return void 116 | */ 117 | protected function loadTranslations() 118 | { 119 | if (file_exists($dir = module_path(static::$module, 'lang'))) 120 | $this->loadTranslationsFrom($dir, studlyToSlug(static::$module)); 121 | } 122 | 123 | /** 124 | * load all migrations of a single module. 125 | * 126 | * @return void 127 | */ 128 | protected function loadMigrations() 129 | { 130 | if (file_exists($dir = module_path(static::$module, 'database/migrations'))) 131 | $this->loadMigrationsFrom($dir); 132 | } 133 | 134 | /** 135 | * load all views of a single module. 136 | * 137 | * @return void 138 | */ 139 | protected function loadViews() 140 | { 141 | if (file_exists($dir = module_path(static::$module, 'resources/views'))) 142 | $this->loadViewsFrom($dir, studlyToSlug(static::$module)); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/Core/Commands/MakeTest.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 23 | 24 | // APPEND MODULES TESTS TO PHPUNIT.XML 25 | if (file_exists($tests = base_path('phpunit.xml'))) { 26 | $phpunitContent = file_get_contents($tests); 27 | 28 | if (!str_contains($phpunitContent, './app/Modules/*/tests/Feature') || !str_contains($phpunitContent, './app/Modules/*/tests/Unit')) { 29 | $phpunitContent = str_replace( 30 | [ 31 | 'tests/Unit', 32 | 'tests/Feature', 33 | PHP_EOL . ' ./app/Modules/*/tests' 34 | ], 35 | [ 36 | 'tests/Unit' . PHP_EOL . ' ./app/Modules/*/tests/Unit', 37 | 'tests/Feature' . PHP_EOL . ' ./app/Modules/*/tests/Feature', 38 | '', 39 | ], 40 | $phpunitContent 41 | ); 42 | 43 | File::replace($tests, $phpunitContent); 44 | } 45 | } 46 | 47 | if (file_exists($tests = base_path('tests/Pest.php'))) { 48 | $pestContent = file_get_contents($tests); 49 | 50 | if (str_contains($pestContent, "'Feature'") && !str_contains($pestContent, '../app/Modules/*/tests/Feature')) { 51 | $pestContent = str_replace( 52 | "'Feature'", 53 | "'Feature', '../app/Modules/*/tests/Feature'", 54 | $pestContent 55 | ); 56 | } 57 | 58 | if ( 59 | (str_contains($pestContent, "'Unit'") || str_contains($pestContent, '"Unit"')) 60 | && !str_contains($pestContent, '../app/Modules/*/tests/Unit') 61 | ) { 62 | $pestContent = str_replace( 63 | ["'Unit'", '"Unit"'], 64 | "'Unit', '../app/Modules/*/tests/Unit'", 65 | $pestContent 66 | ); 67 | } 68 | 69 | File::replace($tests, $pestContent); 70 | } 71 | 72 | 73 | // CREATE TESTS DIRECTORY IF NOT FOUND 74 | if (!file_exists($tests = module_path($this->module, 'tests'))) { 75 | File::makeDirectory($tests, 0777, true, true); 76 | File::makeDirectory($tests . DIRECTORY_SEPARATOR . 'Feature', 0777, true, true); 77 | File::makeDirectory($tests . DIRECTORY_SEPARATOR . 'Unit', 0777, true, true); 78 | } 79 | 80 | // TEST NAME 81 | $this->appendName(substr(strtolower($this->name), -4) != 'test', 'Test'); 82 | 83 | // STUB 84 | $stubPath = __DIR__ . '/stubs/' . ($this->option('pest') ? 'pest.' : null) . ($this->option('unit') ? 'test.unit' : 'test') . '.stub'; 85 | $stubContent = file_get_contents($stubPath); 86 | 87 | // PREPARE STUB CONTENT 88 | if (strpos($stubContent, 'namespace') !== false) { 89 | $stubContent = str_replace('{{ class }}', $this->name, $stubContent); 90 | $stubContent = str_replace( 91 | '{{ namespace }}', 92 | $this->getNamespace('tests/' . ($this->option('unit') ? 'Unit' : 'Feature')), 93 | $stubContent 94 | ); 95 | } 96 | 97 | // SAVING TEST 98 | if (file_exists($path = $this->getPath('tests/' . ($this->option('unit') ? 'Unit' : 'Feature') . '/' . $this->fullName . '.php'))) { 99 | $this->error('Test is already exists!'); 100 | return false; 101 | } 102 | 103 | if (!File::isDirectory($dir = dirname($path))) 104 | File::makeDirectory($dir, 0755, true, true); 105 | 106 | if (File::put($path, $stubContent)) { 107 | $this->info('Test created successfully.'); 108 | } else { 109 | $this->warn('There is something wrong.'); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Packages/Translatable/Commands/TranslatableMake.php: -------------------------------------------------------------------------------- 1 | moduleExists()) return; 19 | 20 | // CREATE MODELS DIRECTORY IF NOT FOUND 21 | if (!file_exists($models = $this->getPath('Models'))) 22 | File::makeDirectory($models, 0777, true, true); 23 | 24 | $this->generateMainModel(); 25 | sleep(2); 26 | $this->generateTranslatableModel(); 27 | } 28 | 29 | private function generateMainModel() 30 | { 31 | $this->table = Str::snake($this->name); 32 | $this->id = $this->table . '_id'; 33 | $this->table = Str::plural($this->table); 34 | 35 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/../stubs/model.translatable.stub')); 36 | $content = str_replace('{{ namespace }}', $this->getNamespace('Models'), $content); 37 | $content = str_replace('use HasFactory;', 'use HasFactory, Translatable;', $content); 38 | $content = str_replace('{{ table }}', $this->table, $content); 39 | 40 | // SAVING MODEL 41 | if (file_exists($path = $this->getPath('Models/' . $this->fullName . '.php'))) { 42 | $this->error('Model is already exists!'); 43 | return false; 44 | } 45 | 46 | if (!File::isDirectory($dir = dirname($path))) 47 | File::makeDirectory($dir, 0755, true, true); 48 | 49 | if (File::put($path, $content)) { 50 | $this->info('Model created successfully.'); 51 | } else { 52 | $this->warn('There is something wrong.'); 53 | } 54 | 55 | // CREATE MIGRATION 56 | if ($this->option('migration')) { 57 | $command = 'module:make:migration ' . $this->module . ' create_' . $this->table . '_table'; 58 | Artisan::call($command, [], $this->getOutput()); 59 | } 60 | } 61 | 62 | private function generateTranslatableModel() 63 | { 64 | $this->mainTable = $this->table; 65 | $this->table = Str::snake(Str::plural($this->name . 'Translations')); 66 | $this->name .= 'Translation'; 67 | $this->fullName .= 'Translation'; 68 | 69 | $content = str_replace('{{ class }}', $this->name, file_get_contents(__DIR__ . '/../stubs/model.translatabled.stub')); 70 | $content = str_replace('{{ namespace }}', $this->getNamespace('Models'), $content); 71 | $content = str_replace('{{ table }}', $this->table, $content); 72 | $content = str_replace('{{ id }}', $this->id, $content); 73 | 74 | // SAVING TRANSLATABLE-MODEL 75 | if (file_exists($path = $this->getPath('Models/' . $this->fullName . '.php'))) { 76 | $this->error('Translatable-Model is already exists!'); 77 | return false; 78 | } 79 | 80 | if (!File::isDirectory($dir = dirname($path))) 81 | File::makeDirectory($dir, 0755, true, true); 82 | 83 | if (File::put($path, $content)) { 84 | $this->info('Translatable-Model created successfully.'); 85 | } else { 86 | $this->warn('There is something wrong.'); 87 | } 88 | 89 | // CREATE MIGRATION 90 | if ($this->option('migration')) { 91 | $command = 'module:make:migration ' . $this->module . ' create_' . $this->table . '_table'; 92 | Artisan::call($command, [], $this->getOutput()); 93 | 94 | $file = File::glob(module_database_path($this->module, 'migrations/*create_' . $this->table . '_table.php')); 95 | if (!empty($file)) { 96 | $file = $file[0]; 97 | $content = File::get($file); 98 | $hasId = strpos($content, '$table->id()') !== false; 99 | 100 | $content = str_replace( 101 | '$table->timestamps();', 102 | PHP_EOL . ' $table->string(\'locale\')->index();' . PHP_EOL . 103 | ' $table->unsigned' . ($hasId ? 'Big' : '') . 'Integer(\'' . $this->id . '\');' . PHP_EOL . 104 | ' $table->unique([\'' . $this->id . '\', \'locale\']);' . PHP_EOL . 105 | ' $table->foreign(\'' . $this->id . '\')->references(\'id\')->on(\'' . $this->mainTable . '\')->onDelete(\'cascade\');', 106 | $content 107 | ); 108 | File::put($file, $content); 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/ModulatorServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom(__DIR__ . '/../config/config.php', 'modulator'); 67 | 68 | // Providers 69 | $this->app->singleton(ModulesFinder::class); 70 | $this->registerProviders(); 71 | } 72 | 73 | /** 74 | * Bootstrap services. 75 | * 76 | * @return void 77 | */ 78 | public function boot() 79 | { 80 | // Console 81 | if ($this->app->runningInConsole()) 82 | $this->console(); 83 | } 84 | 85 | /** 86 | * Publish Config + Register Commands 87 | * 88 | * @return void 89 | */ 90 | public function console() 91 | { 92 | // Config 93 | $this->publishes([ 94 | __DIR__ . '/../config/config.php' => config_path('modulator.php'), 95 | ], ['config', 'pharaonic', 'modulator']); 96 | 97 | 98 | // Commands (Modulator) 99 | $this->commands([ 100 | DBSeed::class, 101 | Make::class, 102 | Delete::class, 103 | Discover::class, 104 | MakeAction::class, 105 | MakeCast::class, 106 | MakeChannel::class, 107 | MakeCommand::class, 108 | MakeComponent::class, 109 | MakeClass::class, 110 | MakeController::class, 111 | MakeEnum::class, 112 | MakeEvent::class, 113 | MakeException::class, 114 | MakeFactory::class, 115 | MakeInterface::class, 116 | MakeJob::class, 117 | MakeListener::class, 118 | MakeMail::class, 119 | MakeMiddleware::class, 120 | MakeMigration::class, 121 | MakeModel::class, 122 | MakeNotification::class, 123 | MakeObserver::class, 124 | MakePolicy::class, 125 | MakeProvider::class, 126 | MakeRequest::class, 127 | MakeResource::class, 128 | MakeRule::class, 129 | MakeScope::class, 130 | MakeSeeder::class, 131 | MakeService::class, 132 | MakeTest::class, 133 | MakeTrait::class, 134 | Migrate::class, 135 | MigrateFresh::class, 136 | MigrateRefresh::class, 137 | MigrateReset::class, 138 | MigrateStatus::class, 139 | ModulesList::class, 140 | RouteList::class, 141 | Test::class 142 | ]); 143 | 144 | // Load External Package's Commands 145 | $this->registerPackagesCommands(); 146 | } 147 | 148 | /** 149 | * Register providers list 150 | * 151 | * @return void 152 | */ 153 | protected function registerProviders() 154 | { 155 | $finder = app(ModulesFinder::class); 156 | 157 | // Cache all current providers 158 | if (!$finder->cached) { 159 | $finder->build(); 160 | } 161 | 162 | $output = new ConsoleOutput(); 163 | 164 | // Register the exists providers 165 | foreach ($finder->list as $provider) { 166 | try { 167 | if (class_exists($provider)) { 168 | $this->app->register($provider); 169 | } 170 | } catch (\Exception $e) { 171 | $output->writeln("Failed to register provider: {$provider}, you need to run module:discover again."); 172 | } 173 | } 174 | } 175 | 176 | /** 177 | * Register all external packages CLI commands. 178 | * 179 | * @return void 180 | */ 181 | protected function registerPackagesCommands() 182 | { 183 | // Translatable Package 184 | if (trait_exists('Pharaonic\Laravel\Translatable\Translatable')) { 185 | $this->commands(TranslatableMake::class); 186 | } 187 | } 188 | } 189 | --------------------------------------------------------------------------------