├── README.md
├── composer.json
├── config
└── module_manager.php
├── helpers
├── file.php
└── helpers.php
├── resources
└── stubs
│ ├── .gitkeep
│ ├── _folder-structure
│ ├── config
│ │ └── .gitkeep
│ ├── database
│ │ ├── .gitkeep
│ │ ├── migrations
│ │ │ └── .gitkeep
│ │ └── seeds
│ │ │ └── .gitkeep
│ ├── helpers
│ │ ├── .gitkeep
│ │ └── helpers.php
│ ├── module.json
│ ├── resources
│ │ ├── .gitkeep
│ │ ├── assets
│ │ │ ├── js
│ │ │ │ └── .gitkeep
│ │ │ └── sass
│ │ │ │ └── .gitkeep
│ │ ├── lang
│ │ │ └── .gitkeep
│ │ └── views
│ │ │ └── .gitkeep
│ ├── routes
│ │ ├── api.php
│ │ └── web.php
│ └── src
│ │ ├── Http
│ │ ├── .gitkeep
│ │ └── Controllers
│ │ │ └── .gitkeep
│ │ ├── Models
│ │ └── .gitkeep
│ │ └── Providers
│ │ ├── BootstrapModuleServiceProvider.php
│ │ ├── InstallModuleServiceProvider.php
│ │ ├── ModuleProvider.php
│ │ ├── RepositoryServiceProvider.php
│ │ ├── RouteServiceProvider.php
│ │ └── UninstallModuleServiceProvider.php
│ ├── console
│ └── command.stub
│ ├── controllers
│ ├── controller.resource.stub
│ └── controller.stub
│ ├── facades
│ └── facade.stub
│ ├── middleware
│ └── middleware.stub
│ ├── models
│ ├── model.contract.stub
│ └── model.stub
│ ├── providers
│ └── provider.stub
│ ├── repositories
│ ├── repository.cache-decorator.stub
│ ├── repository.contract.stub
│ ├── repository.no-cache.stub
│ └── repository.stub
│ ├── requests
│ └── request.stub
│ ├── seeds
│ └── seeder.stub
│ ├── services
│ └── service.stub
│ └── support
│ └── support.stub
├── src
├── Console
│ ├── Commands
│ │ ├── DisableModuleCommand.php
│ │ ├── EnableModuleCommand.php
│ │ ├── InstallModuleCommand.php
│ │ ├── ModuleSeedCommand.php
│ │ ├── RouteListCommand.php
│ │ └── UninstallModuleCommand.php
│ ├── Generators
│ │ ├── AbstractGenerator.php
│ │ ├── MakeCommand.php
│ │ ├── MakeController.php
│ │ ├── MakeFacade.php
│ │ ├── MakeMiddleware.php
│ │ ├── MakeMigration.php
│ │ ├── MakeModel.php
│ │ ├── MakeModule.php
│ │ ├── MakeProvider.php
│ │ ├── MakeRepository.php
│ │ ├── MakeRequest.php
│ │ ├── MakeSeeder.php
│ │ ├── MakeService.php
│ │ ├── MakeSupport.php
│ │ └── MakeView.php
│ ├── Migrations
│ │ ├── ModuleMigrateCommand.php
│ │ └── RollbackCommand.php
│ └── ModuleInfoTrait.php
├── Events
│ ├── ModuleDisabled.php
│ ├── ModuleEnabled.php
│ └── RemovedModule.php
├── Providers
│ ├── ConsoleServiceProvider.php
│ ├── LoadModulesServiceProvider.php
│ └── ModuleProvider.php
├── Services
│ └── ModuleMigrator.php
└── Support
│ ├── Facades
│ └── ModulesManagementFacade.php
│ └── ModulesManagement.php
└── tests
└── Unit
└── ModuleManagerTest.php
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Module Manager
2 | - [Introduction](#introduction)
3 | - [Installation](#installation)
4 | - [Folder Structure](#folder-structure)
5 | - Uses
6 | - [Configuration](#configuration)
7 | - [Available Commands](#available-commands)
8 | - [Loading Component](#loading-component)
9 | - [Loading View](#loading-view)
10 | - [Loading Translation](#loading-translation)
11 | - [Loading Config File](#loading-config-file)
12 | - [Register Middleware](#register-middleware)
13 |
14 | # Introduction
15 | When you work on small project, you will feel laravel default structure
16 | is enough. When your project grows up, you will think to divide
17 | your app into modules where each module will contain all of it resources
18 | such as Controllers, Models, Views, Migrations, Config etc. This `laravel-module-manager`
19 | package will help you to manage laravel modular application easily.
20 |
21 | ### Installation
22 |
23 | - laravel 5.4 or 5.5
24 |
25 | composer require mrabbani/laravel-module-manager
26 |
27 | - Laravel 5.3, Add the following line to your `composer.json` file and run `composer install` in your terminal.
28 |
29 | "mrabbani/laravel-module-manager": "^1.4"
30 |
31 | If you are using *Laravel<5.5* you have to add module manager service provider to `config/app.php` file
32 |
33 | `Mrabbani\ModuleManager\Providers\ModuleProvider::class,`
34 |
35 | To create new module run the bellow command:
36 |
37 | php artisan module:create name-of-your-module
38 | php artisan module:install {module_alias_name}
39 |
40 | ### Folder Structure
41 | If your module name is `module1` the module structure will be
42 |
43 | 
44 |
45 | ### Configuration
46 |
47 | By default, all of your module will be placed inside `modules` directory
48 | into your application's base directory. If you want to change publish
49 | `module_manager` config file by
50 |
51 | `php artisan vendor:publish`
52 |
53 | Now you can change the default *modules* directory by changing
54 | `module_directory` value of `config/module_manager.php` file.
55 |
56 | ### Available Commands
57 |
58 | To see all module related commands run `php artisan` into terminal.
59 | Available commands are:
60 |
61 | - `php artisan module:create {alias}`
62 | - `php artisan module:make:controller {alias} {ControllerName}`
63 | - `php artisan module:make:controller {alias} {ControllerName} --resource`
64 | - `php artisan module:make:command {alias} {CommandName}`
65 | - `php artisan module:make:facade {alias} {FacadeName}`
66 | - `php artisan module:make:middleware {alias} {MiddlewareName}`
67 | - `php artisan module:make:migration {alias} {migration_name} --create --table=table_name`
68 | - `php artisan module:make:migration {alias} {migration_name} --table=table_name`
69 | - `php artisan module:make:model {alias} {ModelName}`
70 | - `php artisan module:make:provider {alias} {ProviderName}`
71 | - `php artisan module:make:request {alias} {RequestName}`
72 | - `php artisan module:make:service {alias} {ServiceClassName}`
73 | - `php artisan module:make:support {alias} {SupportClassName}`
74 | - `php artisan module:make:seeder {alias} {SeederClassName}`
75 | - `php artisan module:db:seed {alias}`
76 | - `php artisan module:db:seed {alias} --class={SeederClassName}`
77 | - `php artisan module:migrate {alias}`
78 | - `php artisan module:migrate:rollback {alias}`
79 | - `php artisan module:routes`
80 | - `php artisan module:install {alias}`
81 | - `php artisan module:uninstall {alias}`
82 | - `php artisan module:enable {alias}`
83 | - `php artisan module:disable {alias}`
84 |
85 | > 'alias' is your module's alias name. you can find module's alias name in `module.json` file of module directory
86 |
87 | You must install your module to activate
88 |
89 | ``php artisan module:install {alias}``
90 |
91 | ### Loading Component
92 | You have to load views, config and translation by following [laravel package](https://laravel.com/docs/5.3/packages#resources)
93 |
94 | ##### Loading View
95 |
96 | view(module_alias::view_file)
97 |
98 | you may load the **module1** module's `index.blade.php` view like so:
99 |
100 | view('module1::index');
101 |
102 |
103 | ##### Loading Translation
104 |
105 | you may load the **module1** module's `welcome` line from the `messages` file like so:
106 |
107 | trans('module1::messages.welcome');
108 | ##### Loading Config File
109 |
110 | you may load the **module1** module's `welcome` line from the `messages` file like so:
111 |
112 | `config('messages.welcome');`
113 |
114 |
115 | You have to merge the configurations, use the `mergeConfigFrom` method within your `ModuleServiceProvider` provider's `register` method:
116 |
117 | public function register()
118 | {
119 | $this->mergeConfigFrom(
120 | __DIR__.'/../../config/messages.php', 'messages'
121 | );
122 | }
123 | ##### Register Middleware
124 |
125 | You should create a `MiddlewareServiceProvider` provider to register your middleware dynamically.
126 |
127 |
128 | ```
129 |
130 | use Illuminate\Support\ServiceProvider;
131 |
132 | class MiddlewareServiceProvider extends ServiceProvider
133 | {
134 | /**
135 | * Register any application services.
136 | *
137 | * @return void
138 | */
139 | public function register()
140 | {
141 | /**
142 | * @var Router $router
143 | */
144 | $router = $this->app['router'];
145 |
146 | $router->aliasMiddleware('middleware-shortname', MiddlewareClassName::class);
147 | }
148 | }
149 | ```
150 |
151 | >**You should register all of your module's custom provider in *ModuleServiceProvider* provider's *register* method instead application's *config/app.php* file.**
152 |
153 |
154 | #### Credit
155 | [WebEd](https://github.com/sgsoft-studio/webed)
156 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mrabbani/laravel-module-manager",
3 | "description": "Laravel Module Management",
4 | "type": "laravel",
5 | "authors": [
6 | {
7 | "name": "mrabbani",
8 | "email": "mahbub.rucse@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "php": "^7.1.3",
13 | "illuminate/console": "5.5.*|5.6.*",
14 | "illuminate/database": "5.5.*|5.6.*"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "Mrabbani\\ModuleManager\\": "src/"
19 | }
20 | },
21 | "autoload-dev": {
22 | "psr-4": {
23 | "Mrabbani\\Tests\\": "tests/"
24 | }
25 | },
26 | "extra": {
27 | "laravel": {
28 | "providers": [
29 | "Mrabbani\\ModuleManager\\Providers\\ModuleProvider"
30 | ]
31 | }
32 | },
33 |
34 | "license": "MIT"
35 | }
36 |
--------------------------------------------------------------------------------
/config/module_manager.php:
--------------------------------------------------------------------------------
1 | 'modules',
10 | 'plugin_directory' => 'modules',
11 |
12 | ];
--------------------------------------------------------------------------------
/helpers/file.php:
--------------------------------------------------------------------------------
1 | $file,
69 | 'type' => $type,
70 | ]);
71 | }
72 | }
73 | return $modulesArr;
74 | }
75 | }
76 |
77 | if (!function_exists('get_module_information')) {
78 | /**
79 | * @param $alias
80 | * @return mixed
81 | */
82 | function get_module_information($alias)
83 | {
84 | return collect(get_all_module_information())
85 | ->where('alias', '=', $alias)
86 | ->first();
87 | }
88 | }
89 |
90 |
91 | if (!function_exists('get_all_module_aliases')) {
92 |
93 | /**
94 | * @return array
95 | */
96 | function get_all_module_aliases()
97 | {
98 | return collect(get_all_module_information())
99 | ->pluck('alias')->unique()->all();
100 | }
101 | }
102 |
103 |
104 | if (!function_exists('get_modules_by_type')) {
105 | /**
106 | * @param $type
107 | * @return mixed
108 | */
109 | function get_modules_by_type($type)
110 | {
111 | return collect(get_all_module_information())
112 | ->where('type', '=', $type)
113 | ->first();
114 | }
115 | }
116 |
117 | if (!function_exists('save_module_information')) {
118 | /**
119 | * @param $alias
120 | * @param array $data
121 | * @return bool
122 | */
123 | function save_module_information($alias, array $data)
124 | {
125 | $module = is_array($alias) ? $alias : get_module_information($alias);
126 | if (!$module) {
127 | return false;
128 | }
129 | $editableFields = [
130 | 'name', 'author', 'description', 'image', 'version', 'enabled', 'installed'
131 | ];
132 |
133 | $count = 0;
134 | foreach ($data as $key => $item) {
135 | if (in_array($key, $editableFields)) {
136 | $module[$key] = $item;
137 | $count++;
138 | }
139 | }
140 | if (\File::exists(array_get($module, 'file'))) {
141 | $file = $module['file'];
142 | unset($module['file']);
143 | if (array_key_exists('type', $module)) {
144 | unset($module['type']);
145 | }
146 | \File::put($file, json_encode_pretify($module));
147 | }
148 |
149 | if ($count > 0) {
150 | return true;
151 | }
152 | return false;
153 | }
154 | }
155 |
156 |
157 | if (!function_exists('json_encode_pretify')) {
158 |
159 | /**
160 | * @param array $data
161 | * @return string
162 | */
163 | function json_encode_pretify(array $data)
164 | {
165 | return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
166 | }
167 | }
--------------------------------------------------------------------------------
/resources/stubs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/config/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/config/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/database/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/database/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/database/migrations/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/database/seeds/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/database/seeds/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/helpers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/helpers/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/helpers/helpers.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/helpers/helpers.php
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/module.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/resources/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/resources/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/resources/assets/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/resources/assets/js/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/resources/assets/sass/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/resources/assets/sass/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/resources/lang/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/resources/lang/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/resources/views/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrabbani/laravel_module_manager/c4aa574d7b57fab808b72c4b183c32170ee4ae20/resources/stubs/_folder-structure/resources/views/.gitkeep
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/routes/api.php:
--------------------------------------------------------------------------------
1 | booted(function () {
17 | $this->booted();
18 | });
19 | }
20 |
21 | /**
22 | * Register the application services.
23 | *
24 | * @return void
25 | */
26 | public function register()
27 | {
28 |
29 | }
30 |
31 | private function booted()
32 | {
33 | /**
34 | * Register dynamic menu or what you want when
35 | * bootstrap your module
36 | */
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/src/Providers/InstallModuleServiceProvider.php:
--------------------------------------------------------------------------------
1 | booted(function () {
21 | $this->booted();
22 | });
23 | }
24 |
25 | /**
26 | * Register the application services.
27 | *
28 | * @return void
29 | */
30 | public function register()
31 | {
32 |
33 | }
34 |
35 | private function booted()
36 | {
37 | //Resolve your module dependency
38 |
39 | $this->createSchema();
40 | }
41 |
42 | private function createSchema()
43 | {
44 | \Artisan::call('module:migrate', ['alias' => $this->moduleAlias]);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/src/Providers/ModuleProvider.php:
--------------------------------------------------------------------------------
1 | loadViewsFrom(__DIR__ . '/../../resources/views', 'DummyAlias');
16 | /*Load translations*/
17 | $this->loadTranslationsFrom(__DIR__ . '/../../resources/lang', 'DummyAlias');
18 | /*Load migrations*/
19 | $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations');
20 |
21 | $this->publishes([
22 | __DIR__ . '/../../resources/assets' => resource_path('assets'),
23 | __DIR__ . '/../../resources/public' => public_path(),
24 | ], 'assets');
25 | $this->publishes([
26 | __DIR__ . '/../../resources/views' => config('view.paths')[0] . '/vendor/DummyAlias',
27 | ], 'views');
28 | $this->publishes([
29 | __DIR__ . '/../../resources/lang' => base_path('resources/lang/vendor/DummyAlias'),
30 | ], 'lang');
31 | $this->publishes([
32 | __DIR__ . '/../../database' => base_path('database'),
33 | ], 'migrations');
34 | }
35 |
36 | /**
37 | * Register the application services.
38 | *
39 | * @return void
40 | */
41 | public function register()
42 | {
43 | //Load helpers
44 | $this->loadHelpers();
45 |
46 | $this->app->register(RouteServiceProvider::class);
47 | $this->app->register(RepositoryServiceProvider::class);
48 | $this->app->register(BootstrapModuleServiceProvider::class);
49 | }
50 |
51 | protected function loadHelpers()
52 | {
53 | $helpers = $this->app['files']->glob(__DIR__ . '/../../helpers/*.php');
54 | foreach ($helpers as $helper) {
55 | require_once $helper;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/src/Providers/RepositoryServiceProvider.php:
--------------------------------------------------------------------------------
1 | mapApiRoutes();
31 |
32 | $this->mapWebRoutes();
33 |
34 | //
35 | }
36 |
37 | /**
38 | * Define the "web" routes for the application.
39 | *
40 | * These routes all receive session state, CSRF protection, etc.
41 | *
42 | * @return void
43 | */
44 | protected function mapWebRoutes()
45 | {
46 | Route::group([
47 | 'middleware' => 'web',
48 | 'namespace' => $this->namespace,
49 | ], function ($router) {
50 | require __DIR__ . '/../../routes/web.php';
51 | });
52 | }
53 |
54 | /**
55 | * Define the "api" routes for the application.
56 | *
57 | * These routes are typically stateless.
58 | *
59 | * @return void
60 | */
61 | protected function mapApiRoutes()
62 | {
63 | Route::group([
64 | 'middleware' => 'api',
65 | 'namespace' => $this->namespace,
66 | 'prefix' => 'api'
67 | ], function ($router) {
68 | require __DIR__ . '/../../routes/api.php';
69 | });
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/resources/stubs/_folder-structure/src/Providers/UninstallModuleServiceProvider.php:
--------------------------------------------------------------------------------
1 | booted(function () {
19 | $this->booted();
20 | });
21 | }
22 |
23 | /**
24 | * Register the application services.
25 | *
26 | * @return void
27 | */
28 | public function register()
29 | {
30 |
31 | }
32 |
33 | private function booted()
34 | {
35 | $this->dropSchema();
36 | }
37 |
38 | private function dropSchema()
39 | {
40 | //If you want to rollback your module migration
41 | // uncomment bellow statement
42 |
43 | // \Artisan::call('module:migrate:rollback', ['alias' => $this->moduleAlias]);
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/resources/stubs/console/command.stub:
--------------------------------------------------------------------------------
1 | booted(function () {
15 | $this->booted();
16 | });
17 | }
18 |
19 | /**
20 | * Register any application services.
21 | *
22 | * @return void
23 | */
24 | public function register()
25 | {
26 |
27 | }
28 |
29 | /**
30 | * Callback when app booted
31 | *
32 | * @return void
33 | */
34 | private function booted()
35 | {
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/resources/stubs/repositories/repository.cache-decorator.stub:
--------------------------------------------------------------------------------
1 | composer = $composer;
43 | $this->composer->setWorkingPath(base_path());
44 | }
45 |
46 | /**
47 | * Execute the console command.
48 | */
49 | public function handle()
50 | {
51 | $this->getInformation();
52 |
53 | $count = 0;
54 |
55 | $plugins = get_modules_by_type('plugins');
56 |
57 | if(!$this->container['alias']) {
58 | foreach ($plugins as $plugin) {
59 | \ModulesManagement::disableModule(array_get($plugin, 'alias'));
60 | $count++;
61 | }
62 | } else {
63 | $plugins = $plugins->where('alias', '=', $this->container['alias']);
64 | foreach ($plugins as $plugin) {
65 | \ModulesManagement::disableModule(array_get($plugin, 'alias'));
66 | $count++;
67 | }
68 | }
69 |
70 | echo PHP_EOL;
71 |
72 | \ModulesManagement::refreshComposerAutoload();
73 |
74 | $this->info("\n$count module(s) disabled successfully.");
75 | }
76 |
77 | protected function getInformation()
78 | {
79 | if($this->option('all')) {
80 | $this->container['alias'] = null;
81 | } else {
82 | $this->container['alias'] = $this->ask('Plugin alias');
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Console/Commands/EnableModuleCommand.php:
--------------------------------------------------------------------------------
1 | composer = $composer;
42 | $this->composer->setWorkingPath(base_path());
43 | }
44 |
45 | /**
46 | * Execute the console command.
47 | */
48 | public function handle()
49 | {
50 | $this->getInformation();
51 |
52 | $count = 0;
53 |
54 | $plugins = get_modules_by_type('plugins');
55 |
56 | if(!$this->container['alias']) {
57 | foreach ($plugins as $plugin) {
58 | \ModulesManagement::enableModule(array_get($plugin, 'alias'));
59 | $count++;
60 | }
61 | } else {
62 | $plugins = $plugins->where('alias', '=', $this->container['alias']);
63 | foreach ($plugins as $plugin) {
64 | \ModulesManagement::enableModule(array_get($plugin, 'alias'));
65 | $count++;
66 | }
67 | }
68 |
69 | echo PHP_EOL;
70 |
71 | \ModulesManagement::refreshComposerAutoload();
72 |
73 | $this->info("\n$count module(s) enabled successfully.");
74 | }
75 |
76 | protected function getInformation()
77 | {
78 | if($this->option('all')) {
79 | $this->container['alias'] = null;
80 | } else {
81 | $this->container['alias'] = $this->ask('Plugin alias');
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Console/Commands/InstallModuleCommand.php:
--------------------------------------------------------------------------------
1 | app = app();
46 | }
47 |
48 | /**
49 | * Execute the console command.
50 | */
51 | public function handle()
52 | {
53 | /**
54 | * Migrate tables
55 | */
56 | \ModulesManagement::enableModule($this->argument('alias'));
57 | \ModulesManagement::modifyModuleAutoload($this->argument('alias'));
58 |
59 | $this->line('Migrate database...');
60 | \Artisan::call('module:migrate', ['alias' => $this->argument('alias')]);
61 | $this->line('Install module dependencies...');
62 | $this->registerInstallModuleService();
63 |
64 | $this->info("\nModule " . $this->argument('alias') . " installed.");
65 | }
66 |
67 | protected function registerInstallModuleService()
68 | {
69 |
70 | $module = get_module_information($this->argument('alias'));
71 | $namespace = str_replace('\\\\', '\\', array_get($module, 'namespace', '') . '\Providers\InstallModuleServiceProvider');
72 | if(class_exists($namespace)) {
73 | $this->app->register($namespace);
74 | }
75 | save_module_information($module, [
76 | 'installed' => true
77 | ]);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Console/Commands/ModuleSeedCommand.php:
--------------------------------------------------------------------------------
1 | loadSeederClass();
33 | $this->runSeeder();
34 | }
35 |
36 | /**
37 | * Load classes from plugin's database/seeds directory
38 | *
39 | * @return void
40 | */
41 |
42 | protected function loadSeederClass()
43 | {
44 | $path = $this->getPath();
45 | $seederClasses = \File::glob($path . '*.php');
46 | foreach ($seederClasses as $className) {
47 | require_once $className;
48 | }
49 | }
50 |
51 |
52 |
53 | /**
54 | * Get the path of seeder classes
55 | *
56 | * @return string
57 | */
58 | protected function getPath()
59 | {
60 | $path = $this->getModuleInfo('module-path') . 'database/seeds/';
61 |
62 | return $path;
63 | }
64 |
65 | /**
66 | * Run the database seeder command.
67 | *
68 | * @param string $database
69 | * @return void
70 | */
71 | protected function runSeeder()
72 | {
73 | $database = $this->option('database');
74 |
75 | $alias = $this->argument('alias');
76 |
77 | $className = $this->option('class') ?: studly_case(preg_replace('/\-/', '_', $alias)) . 'TableSeeder';
78 |
79 | $this->call('db:seed', [
80 | '--database' => $database,
81 | '--class' => $className,
82 | '--force' => $this->option('force'),
83 | ]);
84 | }
85 | }
--------------------------------------------------------------------------------
/src/Console/Commands/RouteListCommand.php:
--------------------------------------------------------------------------------
1 | router = $router;
76 | $this->routes = $router->getRoutes();
77 | }
78 |
79 | /**
80 | * Prompt for module's alias name
81 | *
82 | */
83 | public function handle()
84 | {
85 | $this->module = $this->ask('Module alias name?', 'all');
86 | $this->setModulesNamespace();
87 | $this->fire();
88 | }
89 |
90 | /**
91 | * Set all available module's root namespace to $this->modulesNamespace
92 | *
93 | */
94 | public function setModulesNamespace()
95 | {
96 | if($this->module !== 'all') {
97 | $modules[] = get_module_information($this->module);
98 |
99 | } else {
100 | $modules = get_all_module_information();
101 | }
102 | if(! count($modules)){
103 | $this->error('Module does not exist');
104 | die();
105 | }
106 |
107 | $this->modulesNamespace = collect($modules)->pluck('namespace');
108 | }
109 |
110 | /**
111 | * check route's action namespace is belongs to module's namespace
112 | *
113 | * @param $namespace
114 | * @return bool
115 | */
116 | public function isBelongsToModule($namespace)
117 | {
118 |
119 | foreach ($this->modulesNamespace as $moduleNamespace) {
120 | if((strpos($namespace, $moduleNamespace)) === 0){
121 | return true;
122 | }
123 | }
124 | return false;
125 | }
126 |
127 | /**
128 | * Execute the console command.
129 | *
130 | * @return void
131 | */
132 | public function fire()
133 | {
134 | if (count($this->routes) == 0) {
135 | return $this->error("Your application doesn't have any routes.");
136 | }
137 |
138 | $this->displayRoutes($this->getRoutes());
139 | }
140 |
141 | /**
142 | * Compile the routes into a displayable format.
143 | *
144 | * @return array
145 | */
146 | protected function getRoutes()
147 | {
148 | $routes = collect($this->routes)->map(function ($route) {
149 | return $this->getRouteInformation($route);
150 | })->all();
151 |
152 | if ($sort = $this->option('sort')) {
153 | $routes = $this->sortRoutes($sort, $routes);
154 | }
155 |
156 | if ($this->option('reverse')) {
157 | $routes = array_reverse($routes);
158 | }
159 |
160 | return array_filter($routes);
161 | }
162 |
163 | /**
164 | * Get the route information for a given route.
165 | *
166 | * @param \Illuminate\Routing\Route $route
167 | * @return array
168 | */
169 | protected function getRouteInformation(Route $route)
170 | {
171 | return $this->filterRoute([
172 | 'host' => $route->domain(),
173 | 'method' => implode('|', $route->methods()),
174 | 'uri' => $route->uri(),
175 | 'name' => $route->getName(),
176 | 'action' => $route->getActionName(),
177 | 'middleware' => $this->getMiddleware($route),
178 | 'namespace' => $route->getAction()['namespace']
179 | ]);
180 | }
181 |
182 | /**
183 | * Sort the routes by a given element.
184 | *
185 | * @param string $sort
186 | * @param array $routes
187 | * @return array
188 | */
189 | protected function sortRoutes($sort, $routes)
190 | {
191 | return Arr::sort($routes, function ($route) use ($sort) {
192 | return $route[$sort];
193 | });
194 | }
195 |
196 | /**
197 | * Display the route information on the console.
198 | *
199 | * @param array $routes
200 | * @return void
201 | */
202 | protected function displayRoutes(array $routes)
203 | {
204 | $this->table($this->headers, $routes);
205 | }
206 |
207 | /**
208 | * Get before filters.
209 | *
210 | * @param \Illuminate\Routing\Route $route
211 | * @return string
212 | */
213 | protected function getMiddleware($route)
214 | {
215 | return collect($route->gatherMiddleware())->map(function ($middleware) {
216 | return $middleware instanceof Closure ? 'Closure' : $middleware;
217 | })->implode(',');
218 | }
219 |
220 | /**
221 | * Filter the route by URI and / or name.
222 | *
223 | * @param array $route
224 | * @return array|null
225 | */
226 | protected function filterRoute(array $route)
227 | {
228 | if($this->isBelongsToModule($route['namespace'])) {
229 | return $route;
230 | }
231 | }
232 |
233 | /**
234 | * Get the console command options.
235 | *
236 | * @return array
237 | */
238 | protected function getOptions()
239 | {
240 | return [
241 | ['method', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by method.'],
242 |
243 | ['name', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by name.'],
244 |
245 | ['path', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by path.'],
246 |
247 | ['reverse', 'r', InputOption::VALUE_NONE, 'Reverse the ordering of the routes.'],
248 |
249 | ['sort', null, InputOption::VALUE_OPTIONAL, 'The column (host, method, uri, name, action, middleware) to sort by.', 'uri'],
250 | ];
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/src/Console/Commands/UninstallModuleCommand.php:
--------------------------------------------------------------------------------
1 | app = app();
46 | }
47 |
48 | /**
49 | * Execute the console command.
50 | */
51 | public function handle()
52 | {
53 | /**
54 | * Migrate tables
55 | */
56 | $this->line('Uninstall module dependencies...');
57 | $this->registerUninstallModuleService();
58 |
59 | $this->info("\nModule " . $this->argument('alias') . " uninstalled.");
60 | }
61 |
62 | protected function registerUninstallModuleService()
63 | {
64 |
65 | $module = get_module_information($this->argument('alias'));
66 | $namespace = str_replace('\\\\', '\\', array_get($module, 'namespace', '') . '\Providers\UninstallModuleServiceProvider');
67 | if(class_exists($namespace)) {
68 | $this->app->register($namespace);
69 |
70 | }
71 | save_module_information($module, [
72 | 'installed' => true
73 | ]);
74 | \ModulesManagement::disableModule($this->argument('alias'));
75 | \ModulesManagement::modifyModuleAutoload($this->argument('alias'), true);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Console/Generators/AbstractGenerator.php:
--------------------------------------------------------------------------------
1 | getDefaultNamespace($name);
22 | }
23 |
24 | /**
25 | * Get the destination class path.
26 | *
27 | * @param string $name
28 | * @return string
29 | */
30 | protected function getPath($name)
31 | {
32 | $path = $this->getModuleInfo('module-path') . 'src/' . str_replace('\\', '/', $name) . '.php';
33 |
34 | return $path;
35 | }
36 |
37 | /**
38 | * Get the full namespace name for a given class.
39 | *
40 | * @param string $name
41 | * @return string
42 | */
43 | protected function getNamespace($name)
44 | {
45 | $namespace = trim(implode('\\', array_slice(explode('\\', $this->getModuleInfo('namespace') . '\\' . str_replace('/', '\\', $name)), 0, -1)), '\\');
46 | return $namespace;
47 | }
48 |
49 | /**
50 | * Replace the class name for the given stub.
51 | *
52 | * @param string $stub
53 | * @param string $name
54 | * @return string
55 | */
56 | protected function replaceClass($stub, $name)
57 | {
58 | $class = class_basename($name);
59 |
60 | return str_replace('DummyClass', $class, $stub);
61 | }
62 |
63 | /**
64 | * Replace the namespace for the given stub.
65 | *
66 | * @param string $stub
67 | * @param string $name
68 | * @return $this
69 | */
70 | protected function replaceNamespace(&$stub, $name)
71 | {
72 | $stub = str_replace(
73 | 'DummyNamespace', $this->getNamespace($name), $stub
74 | );
75 |
76 | $stub = str_replace(
77 | 'DummyRootNamespace', $this->laravel->getNamespace(), $stub
78 | );
79 |
80 | if (method_exists($this, 'replaceParameters')) {
81 | $this->replaceParameters($stub);
82 | }
83 |
84 | return $this;
85 | }
86 | protected function qualifyClass($name)
87 | {
88 | $rootNamespace = $this->rootNamespace();
89 |
90 | return $this->getDefaultNamespace(trim($rootNamespace, '\\'));
91 |
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeCommand.php:
--------------------------------------------------------------------------------
1 | argument('name');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeController.php:
--------------------------------------------------------------------------------
1 | option('resource')) {
37 | return __DIR__ . '/../../../resources/stubs/controllers/controller.resource.stub';
38 | }
39 |
40 | return __DIR__ . '/../../../resources/stubs/controllers/controller.stub';
41 | }
42 |
43 | protected function getDefaultNamespace($rootNamespace)
44 | {
45 | // ($this->getNamespace($this->argument('alias')));
46 | return 'Http\\Controllers\\' . $this->argument('name');
47 | }
48 |
49 | protected function replaceParameters(&$stub)
50 | {
51 | $stub = str_replace([
52 | '{alias}',
53 | ], [
54 | $this->argument('alias'),
55 | ], $stub);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeFacade.php:
--------------------------------------------------------------------------------
1 | argument('name');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeMiddleware.php:
--------------------------------------------------------------------------------
1 | argument('name');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeMigration.php:
--------------------------------------------------------------------------------
1 | creator = $creator;
59 | $this->composer = $composer;
60 | $this->composer->setWorkingPath(base_path());
61 | }
62 |
63 | public function handle()
64 | {
65 | // It's possible for the developer to specify the tables to modify in this
66 | // schema operation. The developer may also specify if this table needs
67 | // to be freshly created so we can create the appropriate migrations.
68 | $name = trim($this->argument('name'));
69 |
70 | $table = $this->option('table');
71 |
72 | $create = $this->option('create') ?: false;
73 |
74 | if (! $table && is_string($create)) {
75 | $table = $create;
76 |
77 | $create = true;
78 | }
79 |
80 | // Now we are ready to write the migration out to disk. Once we've written
81 | // the migration out, we will dump-autoload for the entire framework to
82 | // make sure that the migrations are registered by the class loaders.
83 | $this->writeMigration($name, $table, $create);
84 | }
85 |
86 | /**
87 | * Write the migration file to disk.
88 | *
89 | * @param string $name
90 | * @param string $table
91 | * @param bool $create
92 | * @return string
93 | */
94 | protected function writeMigration($name, $table, $create)
95 | {
96 | $path = $this->getMigrationPath();
97 |
98 | $file = pathinfo($this->creator->create($name, $path, $table, $create), PATHINFO_FILENAME);
99 |
100 | return $this->line("Created Migration: {$file}");
101 | }
102 |
103 | /**
104 | * Get the path to the migration directory.
105 | *
106 | * @return string
107 | */
108 | protected function getMigrationPath()
109 | {
110 | $module = get_module_information($this->argument('alias'));
111 | $baseDir = get_base_folder(array_get($module, 'file'));
112 | $path = $baseDir . 'database/migrations';
113 | return $path;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeModel.php:
--------------------------------------------------------------------------------
1 | getNameInput();
40 |
41 | $name = $this->parseName($nameInput);
42 |
43 | $path = $this->getPath($name);
44 |
45 | if ($this->alreadyExists($nameInput)) {
46 | $this->error($this->type . ' already exists!');
47 |
48 | return false;
49 | }
50 |
51 | $this->makeDirectory($path);
52 |
53 | $this->files->put($path, $this->buildClass($name));
54 |
55 | /**
56 | * Create model contract
57 | */
58 |
59 | if($this->option('with-contract')) {
60 | $this->buildContract = true;
61 |
62 | $contractName = 'Contracts/' . get_file_name($path, '.php');
63 | $contractPath = get_base_folder($path) . $contractName . 'ModelContract.php';
64 |
65 | $this->makeDirectory($contractPath);
66 | $this->files->put($contractPath, $this->buildClass('Models\\' . $contractName));
67 | }
68 |
69 |
70 | $this->info($this->type . ' created successfully.');
71 | }
72 |
73 | /**
74 | * Get the stub file for the generator.
75 | *
76 | * @return string
77 | */
78 | protected function getStub()
79 | {
80 | if ($this->buildContract === true) {
81 | return __DIR__ . '/../../../resources/stubs/models/model.contract.stub';
82 | }
83 | return __DIR__ . '/../../../resources/stubs/models/model.stub';
84 | }
85 |
86 | protected function getDefaultNamespace($rootNamespace)
87 | {
88 | if ($this->buildContract === true) {
89 | return 'Models\\Contracts\\' . $this->argument('name');
90 | }
91 | return 'Models\\' . $this->argument('name');
92 | }
93 |
94 | protected function replaceParameters(&$stub)
95 | {
96 | $stub = str_replace([
97 | '{table}',
98 | ], [
99 | snake_case(str_plural($this->argument('name'))),
100 | ], $stub);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeModule.php:
--------------------------------------------------------------------------------
1 | 'Module',
39 | 'plugin' => 'Plugins',
40 | ];
41 |
42 | protected $moduleType;
43 |
44 | protected $moduleFolderName;
45 |
46 | /**
47 | * Create a new command instance.
48 | *
49 | * @return void
50 | */
51 | public function __construct(Filesystem $filesystem)
52 | {
53 | parent::__construct();
54 |
55 | $this->files = $filesystem;
56 | }
57 |
58 | /**
59 | * Execute the console command.
60 | */
61 | public function handle()
62 | {
63 | $this->moduleType = 'module'; //$this->ask('Your modular type. Eccepted: module,plugin. Other types will return "module".', 'module');
64 | if (!in_array($this->moduleType, array_keys($this->acceptedTypes))) {
65 | $this->moduleType = 'module';
66 | }
67 |
68 | $this->container['alias'] = snake_case($this->argument('alias'));
69 |
70 | $this->step1();
71 | }
72 |
73 | private function step1()
74 | {
75 | $this->moduleFolderName = $this->ask('Module folder name:', $this->container['alias']);
76 | $this->container['name'] = $this->ask('Name of module:', config('app.name') . ' '. str_slug($this->container['alias']));
77 | $this->container['author'] = $this->ask('Author of module:');
78 | $this->container['description'] = $this->ask('Description of module:', $this->container['name']);
79 | $this->container['namespace'] = $this->ask('Namespace of module:', $this->laravel->getNamespace() . $this->acceptedTypes[$this->moduleType] . '\\' . studly_case($this->container['alias']));
80 | $this->container['version'] = $this->ask('Module version.', '1.0');
81 | $this->container['autoload'] = $this->ask('Autoloading type.', 'psr-4');
82 |
83 | $this->step2();
84 | }
85 |
86 | private function step2()
87 | {
88 | $this->generatingModule();
89 |
90 | $this->info("\nYour module generated successfully.");
91 | }
92 |
93 | private function generatingModule()
94 | {
95 | $pathType = $this->makeModuleFolder();
96 | $directory = $pathType($this->moduleFolderName);
97 | $source = __DIR__ . '/../../../resources/stubs/_folder-structure';
98 |
99 | /**
100 | * Make directory
101 | */
102 | $this->files->makeDirectory($directory);
103 | $this->files->copyDirectory($source, $directory, null);
104 |
105 | /**
106 | * Replace files placeholder
107 | */
108 | $files = $this->files->allFiles($directory);
109 | foreach ($files as $file) {
110 | $contents = $this->replacePlaceholders($file->getContents());
111 | $filePath = $pathType($this->moduleFolderName . '/' . $file->getRelativePathname());
112 |
113 | $this->files->put($filePath, $contents);
114 | }
115 |
116 | /**
117 | * Modify the module.json information
118 | */
119 | \File::put($directory . '/module.json', json_encode_pretify($this->container));
120 | }
121 |
122 | private function makeModuleFolder()
123 | {
124 | switch ($this->moduleType) {
125 | case 'module':
126 | if (!$this->files->isDirectory(module_base_path())) {
127 | $this->files->makeDirectory(module_base_path());
128 | }
129 | return 'module_base_path';
130 | break;
131 | case 'plugin':
132 | default:
133 | if (!$this->files->isDirectory(plugins_base_path())) {
134 | $this->files->makeDirectory(plugins_base_path());
135 | }
136 | return 'plugins_base_path';
137 | break;
138 | }
139 | }
140 |
141 | protected function replacePlaceholders($contents)
142 | {
143 | $find = [
144 | 'DummyNamespace',
145 | 'DummyAlias',
146 | 'DummyName',
147 | ];
148 |
149 | $replace = [
150 | $this->container['namespace'],
151 | $this->container['alias'],
152 | $this->container['name'],
153 | ];
154 |
155 | return str_replace($find, $replace, $contents);
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeProvider.php:
--------------------------------------------------------------------------------
1 | argument('name');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeRepository.php:
--------------------------------------------------------------------------------
1 | getNameInput();
40 |
41 | $name = $this->parseName($nameInput);
42 |
43 | $path = $this->getPath($name);
44 |
45 | if ($this->alreadyExists($nameInput)) {
46 | $this->error($this->type . ' already exists!');
47 |
48 | return false;
49 | }
50 |
51 | /**
52 | * Make repository
53 | */
54 | $this->makeDirectory($path);
55 | $this->files->put($path, $this->buildClass($name));
56 |
57 | /**
58 | * Make cache decorator
59 | */
60 | $this->buildStep = 'make-cache-decorator';
61 | $pathCacheDecorator = $this->getPath($name . 'CacheDecorator');
62 | $this->makeDirectory($pathCacheDecorator);
63 | $this->files->put($pathCacheDecorator, $this->buildClass($name));
64 |
65 | /**
66 | * Create model contract
67 | */
68 | $this->buildStep = 'make-contract';
69 | $contractName = 'Contracts/' . get_file_name($path, '.php');
70 | $contractPath = get_base_folder($path) . $contractName . 'Contract.php';
71 |
72 | $this->makeDirectory($contractPath);
73 |
74 | $this->files->put($contractPath, $this->buildClass('Repositories\\' . $contractName));
75 |
76 | $this->info($this->type . ' created successfully.');
77 | }
78 |
79 | /**
80 | * Get the stub file for the generator.
81 | *
82 | * @return string
83 | */
84 | protected function getStub()
85 | {
86 | if ($this->buildStep === 'make-contract') {
87 | return __DIR__ . '/../../../resources/stubs/repositories/repository.contract.stub';
88 | }
89 | if ($this->buildStep === 'make-cache-decorator' && !$this->option('no-cache')) {
90 | return __DIR__ . '/../../../resources/stubs/repositories/repository.cache-decorator.stub';
91 | }
92 | if ($this->option('no-cache')) {
93 | return __DIR__ . '/../../../resources/stubs/repositories/repository.no-cache.stub';
94 | }
95 | return __DIR__ . '/../../../resources/stubs/repositories/repository.stub';
96 | }
97 |
98 | protected function getDefaultNamespace($rootNamespace)
99 | {
100 | if ($this->buildStep === 'make-contract') {
101 | return 'Repositories\\Contracts\\' . $this->argument('name');
102 | }
103 | return 'Repositories\\' . $this->argument('name');
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeRequest.php:
--------------------------------------------------------------------------------
1 | argument('name');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeSeeder.php:
--------------------------------------------------------------------------------
1 | createModuleTableSeederIfNotExist();
40 | $nameInput = $this->getNameInput();
41 |
42 | if ($this->alreadyExists($nameInput)) {
43 | $this->error($this->type . ' already exists!');
44 |
45 | return false;
46 | }
47 |
48 | $this->createSeederClass($nameInput);
49 |
50 | $this->info($this->type . ' created successfully.');
51 | }
52 |
53 | protected function createModuleTableSeederIfNotExist()
54 | {
55 | $moduleSeederClass = studly_case(preg_replace('/\-/', '_', $this->argument('alias'))) . 'TableSeeder';
56 |
57 | if ($this->alreadyExists($moduleSeederClass)) {
58 |
59 | return false;
60 | }
61 |
62 | $this->createSeederClass($moduleSeederClass);
63 | }
64 |
65 |
66 | protected function createSeederClass($nameInput)
67 | {
68 |
69 | $name = $this->parseName($nameInput);
70 |
71 | $path = $this->getPath($name);
72 |
73 | $this->makeDirectory($path);
74 |
75 | $this->files->put($path, $this->buildClass($name));
76 |
77 | }
78 | /**
79 | * Get the destination class path.
80 | *
81 | * @param string $name
82 | * @return string
83 | */
84 | protected function getPath($name)
85 | {
86 | $path = $this->getModuleInfo('module-path') . 'database/seeds/' . str_replace('\\', '/', $name) . '.php';
87 |
88 | return $path;
89 | }
90 |
91 | protected function replaceParameters(&$stub)
92 | {
93 | $stub = str_replace([
94 | '{alias}',
95 | ], [
96 | $this->argument('alias'),
97 | ], $stub);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeService.php:
--------------------------------------------------------------------------------
1 | argument('name');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeSupport.php:
--------------------------------------------------------------------------------
1 | argument('name');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Console/Generators/MakeView.php:
--------------------------------------------------------------------------------
1 | option('layout') === '2columns') {
37 | return __DIR__ . '/../../../resources/stubs/views/view-2columns.stub';
38 | }
39 | return __DIR__ . '/../../../resources/stubs/views/view.stub';
40 | }
41 |
42 | /**
43 | * Execute the console command.
44 | *
45 | * @return bool|null
46 | */
47 | public function handle()
48 | {
49 | $nameInput = $this->getNameInput();
50 |
51 | $name = $this->parseName($nameInput);
52 |
53 | $path = $this->getPath($name);
54 |
55 | if ($this->alreadyExists($nameInput)) {
56 | $this->error($this->type . ' already exists!');
57 |
58 | return false;
59 | }
60 |
61 | $this->makeDirectory($path);
62 |
63 | $this->files->put($path, $this->buildClass($name));
64 |
65 | $this->info($this->type . ' created successfully.');
66 | }
67 |
68 | /**
69 | * Get the destination class path.
70 | *
71 | * @param string $name
72 | * @return string
73 | */
74 | protected function getPath($name)
75 | {
76 | $path = $this->getModuleInfo('module-path') . 'resources/views/' . str_replace('\\', '/', $name) . '.blade.php';
77 |
78 | return $path;
79 | }
80 |
81 | protected function replaceParameters(&$stub)
82 | {
83 | $stub = str_replace([
84 | '{alias}',
85 | ], [
86 | $this->argument('alias'),
87 | ], $stub);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Console/Migrations/ModuleMigrateCommand.php:
--------------------------------------------------------------------------------
1 | getMigrationIfo();
29 | foreach($requestedMigrations as $migration) {
30 | $this->info($migration['alias']. ' module migrating');
31 | \Artisan::call('migrate', ['--path' => $migration['path']]);
32 | $this->info($migration['alias']. ' module migrated');
33 | }
34 | }
35 |
36 | /**
37 | * return alias name and database migration path by module
38 | *
39 | * @return array
40 | * @throws \Exception
41 | */
42 | protected function getMigrationIfo()
43 | {
44 | $info = [];
45 | $migrationDirectory = 'database' . DIRECTORY_SEPARATOR . 'migrations';
46 | $alias = $this->argument('alias');
47 | $allAlias = get_all_module_aliases();
48 | if ($alias === 'all') {
49 | foreach($allAlias as $alias) {
50 | $info[] = [
51 | 'alias' => $alias,
52 | 'path' => module_relative_path($alias) . $migrationDirectory
53 | ];
54 | }
55 |
56 | return $info;
57 | }
58 | if (!in_array($alias, $allAlias)) {
59 | throw new \Exception($alias .' module not found');
60 | }
61 | $info[] = [
62 | 'alias' => $alias,
63 | 'path' => module_relative_path($alias) . $migrationDirectory
64 | ];
65 |
66 | return $info;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Console/Migrations/RollbackCommand.php:
--------------------------------------------------------------------------------
1 | migrator = $migrator;
50 | }
51 |
52 | /**
53 | * Execute the console command.
54 | *
55 | * @return void
56 | */
57 | public function handle()
58 | {
59 | if (! $this->confirmToProceed()) {
60 | return;
61 | }
62 |
63 | $migrationPath = base_path().'/'. module_relative_path($this->argument('alias')).'database/migrations';
64 | $this->migrator->setConnection($this->option('database'));
65 | $this->migrator->rollback(
66 | [$migrationPath], ['pretend' => $this->option('pretend'), 'step' => (int) $this->option('step')]
67 | );
68 |
69 | // Once the migrator has run we will grab the note output and send it out to
70 | // the console screen, since the migrator itself functions without having
71 | // any instances of the OutputInterface contract passed into the class.
72 | foreach ($this->migrator->getNotes() as $note) {
73 | $this->output->writeln($note);
74 | }
75 | }
76 |
77 | /**
78 | * Get the console command options.
79 | *
80 | * @return array
81 | */
82 | protected function getOptions()
83 | {
84 | return [
85 | ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],
86 |
87 | ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
88 |
89 | ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],
90 |
91 | ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],
92 |
93 | ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted.'],
94 | ];
95 | }
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/src/Console/ModuleInfoTrait.php:
--------------------------------------------------------------------------------
1 | argument('alias');
41 |
42 | $module = get_module_information($alias);
43 |
44 | if(!$module) {
45 | $this->error('Module not exists');
46 | die();
47 | }
48 |
49 | $moduleRootFolder = $this->resolveModuleRootFolder($module);
50 |
51 | return $this->moduleInformation = array_merge($module, [
52 | 'module-path' => $moduleRootFolder . basename(str_replace('/module.json', '', $module['file'])) . '/'
53 | ]);
54 | }
55 |
56 | /**
57 | * Get module information by key
58 | * @param $key
59 | * @return array|mixed
60 | */
61 | protected function getModuleInfo($key = null)
62 | {
63 | if (!$this->moduleInformation) {
64 | $this->getCurrentModule();
65 | }
66 | if (!$key) {
67 | return $this->moduleInformation;
68 | }
69 | return array_get($this->moduleInformation, $key, null);
70 | }
71 | }
--------------------------------------------------------------------------------
/src/Events/ModuleDisabled.php:
--------------------------------------------------------------------------------
1 | module = $module;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Events/ModuleEnabled.php:
--------------------------------------------------------------------------------
1 | module = $module;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Events/RemovedModule.php:
--------------------------------------------------------------------------------
1 | module = $module;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Providers/ConsoleServiceProvider.php:
--------------------------------------------------------------------------------
1 | generatorCommands();
31 | $this->migrationCommands();
32 | $this->otherCommands();
33 | }
34 |
35 | /**
36 | * register generator commands
37 | */
38 | private function generatorCommands()
39 | {
40 | $generators = [
41 | 'module_manager.console.generator.make-module' => \Mrabbani\ModuleManager\Console\Generators\MakeModule::class,
42 | 'module_manager.console.generator.make-provider' => \Mrabbani\ModuleManager\Console\Generators\MakeProvider::class,
43 | 'module_manager.console.generator.make-controller' => \Mrabbani\ModuleManager\Console\Generators\MakeController::class,
44 | 'module_manager.console.generator.make-middleware' => \Mrabbani\ModuleManager\Console\Generators\MakeMiddleware::class,
45 | 'module_manager.console.generator.make-request' => \Mrabbani\ModuleManager\Console\Generators\MakeRequest::class,
46 | 'module_manager.console.generator.make-model' => \Mrabbani\ModuleManager\Console\Generators\MakeModel::class,
47 | // 'module_manager.console.generator.make-repository' => \Mrabbani\ModuleManager\Console\Generators\MakeRepository::class,
48 | 'module_manager.console.generator.make-facade' => \Mrabbani\ModuleManager\Console\Generators\MakeFacade::class,
49 | 'module_manager.console.generator.make-service' => \Mrabbani\ModuleManager\Console\Generators\MakeService::class,
50 | 'module_manager.console.generator.make-support' => \Mrabbani\ModuleManager\Console\Generators\MakeSupport::class,
51 | // 'module_manager.console.generator.make-view' => \Mrabbani\ModuleManager\Console\Generators\MakeView::class,
52 | 'module_manager.console.generator.make-migration' => \Mrabbani\ModuleManager\Console\Generators\MakeMigration::class,
53 | 'module_manager.console.generator.make-command' => \Mrabbani\ModuleManager\Console\Generators\MakeCommand::class,
54 | 'module_manager.console.generator.make-seeder' => \Mrabbani\ModuleManager\Console\Generators\MakeSeeder::class,
55 | ];
56 | foreach ($generators as $slug => $class) {
57 | $this->app->singleton($slug, function ($app) use ($slug, $class) {
58 | return $app[$class];
59 | });
60 |
61 | $this->commands($slug);
62 | }
63 | }
64 |
65 | /**
66 | * register database migrate related command
67 | */
68 | private function migrationCommands()
69 | {
70 | $this->registerModuleMigrator();
71 | $this->registerMigrateCommand();
72 | }
73 |
74 | private function registerMigrateCommand()
75 | {
76 | $commands = [
77 | 'module_manager.console.command.module-migrate' => \Mrabbani\ModuleManager\Console\Migrations\ModuleMigrateCommand::class
78 | ];
79 | foreach ($commands as $slug => $class) {
80 | $this->app->singleton($slug, function ($app) use ($slug, $class) {
81 | return $app[$class];
82 | });
83 |
84 | $this->commands($slug);
85 | }
86 | $this->registerRollbackCommand();
87 |
88 | }
89 | private function otherCommands()
90 | {
91 | $commands = [
92 | 'module_manager.console.command.module-install' => \Mrabbani\ModuleManager\Console\Commands\InstallModuleCommand::class,
93 | 'module_manager.console.command.module-uninstall' => \Mrabbani\ModuleManager\Console\Commands\UninstallModuleCommand::class,
94 | 'module_manager.console.command.disable-module' => \Mrabbani\ModuleManager\Console\Commands\DisableModuleCommand::class,
95 | 'module_manager.console.command.enable-module' => \Mrabbani\ModuleManager\Console\Commands\EnableModuleCommand::class,
96 | 'module_manager.console.command.module-route-list' => \Mrabbani\ModuleManager\Console\Commands\RouteListCommand::class,
97 | 'module_manager.console.command.module-db-seed' => \Mrabbani\ModuleManager\Console\Commands\ModuleSeedCommand::class,
98 | ];
99 | foreach ($commands as $slug => $class) {
100 | $this->app->singleton($slug, function ($app) use ($slug, $class) {
101 | return $app[$class];
102 | });
103 |
104 | $this->commands($slug);
105 | }
106 | }
107 | /**
108 | * Register the "rollback" migration command.
109 | *
110 | * @return void
111 | */
112 | protected function registerRollbackCommand()
113 | {
114 | $this->app->singleton('module_manager.console.command.migration-rollback', function ($app) {
115 | return new \Mrabbani\ModuleManager\Console\Migrations\RollbackCommand($app['module.migrator']);
116 | });
117 | $this->commands('module_manager.console.command.migration-rollback');
118 | }
119 |
120 |
121 | protected function registerModuleMigrator()
122 | {
123 | // The migrator is responsible for actually running and rollback the migration
124 | // files in the application. We'll pass in our database connection resolver
125 | // so the migrator can resolve any of these connections when it needs to.
126 | $this->app->singleton('module.migrator', function ($app) {
127 |
128 | return new ModuleMigrator($app);
129 | });
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/Providers/LoadModulesServiceProvider.php:
--------------------------------------------------------------------------------
1 | modules = get_all_module_information();
19 |
20 | foreach ($this->modules as $module) {
21 | $needToBootstrap = false;
22 | if (array_get($module, 'installed', null) === true) {
23 | $needToBootstrap = true;
24 | }
25 | if ($needToBootstrap) {
26 | /**
27 | * Register module
28 | */
29 | $moduleProvider = $module['namespace'] . '\Providers\ModuleProvider';
30 |
31 | if (class_exists($moduleProvider)) {
32 | $this->app->register($moduleProvider);
33 | } else {
34 | $this->notLoadedModules[] = $moduleProvider;
35 | }
36 | }
37 | }
38 | }
39 |
40 | public function boot()
41 | {
42 | app()->booted(function () {
43 | $this->booted();
44 | });
45 | }
46 |
47 | private function booted()
48 | {
49 | \ModulesManagement::setModules($this->modules);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Providers/ModuleProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
16 | __DIR__ . '/../../config' => base_path('config'),
17 | ], 'config');
18 | }
19 |
20 | /**
21 | * Register the application services.
22 | *
23 | * @return void
24 | */
25 | public function register()
26 | {
27 | //Load config
28 | $this->mergeConfigFrom(
29 | __DIR__.'/../../config/module_manager.php', 'module_manager'
30 | );
31 |
32 | //Load helpers
33 | $this->loadHelpers();
34 |
35 | $this->app->register(ConsoleServiceProvider::class);
36 | $this->app->register(LoadModulesServiceProvider::class);
37 |
38 | //Register related facades
39 | $loader = \Illuminate\Foundation\AliasLoader::getInstance();
40 | $loader->alias('ModulesManagement', ModulesManagementFacade::class);
41 | }
42 |
43 | protected function loadHelpers()
44 | {
45 | $helpers = $this->app['files']->glob(__DIR__ . '/../../helpers/*.php');
46 | foreach ($helpers as $helper) {
47 | require_once $helper;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Services/ModuleMigrator.php:
--------------------------------------------------------------------------------
1 | notes = [];
28 |
29 | $rolledBack = [];
30 |
31 |
32 | // We want to pull in the last batch of migrations that ran on the previous
33 | // migration operation. We'll then reverse those migrations and run each
34 | // of them "down" to reverse the last migration "operation" which ran.
35 | if (($steps = Arr::get($options, 'step', 0)) > 0) {
36 | $migrations = $this->repository->getMigrations($steps);
37 | } else {
38 | $migrations = $this->repository->getLast();
39 | }
40 |
41 | $count = count($migrations);
42 |
43 | $files = $this->getMigrationFiles($paths);
44 |
45 | if ($count === 0) {
46 | $this->note('Nothing to rollback.');
47 | } else {
48 | // Next we will run through all of the migrations and call the "down" method
49 | // which will reverse each migration in order. This getLast method on the
50 | // repository already returns these migration's names in reverse order.
51 | $this->requireFiles($files);
52 |
53 | foreach ($migrations as $migration) {
54 | $migration = (object) $migration;
55 | if(! isset($files[$migration->migration])) {
56 | continue;
57 | }
58 |
59 | $rolledBack[] = $files[$migration->migration];
60 |
61 | $this->runDown(
62 | $files[$migration->migration],
63 | $migration, Arr::get($options, 'pretend', false)
64 | );
65 | }
66 | }
67 |
68 | return $rolledBack;
69 | }
70 |
71 | }
--------------------------------------------------------------------------------
/src/Support/Facades/ModulesManagementFacade.php:
--------------------------------------------------------------------------------
1 | composer = $composer;
22 | $this->composer->setWorkingPath(base_path());
23 | }
24 |
25 | /**
26 | * @param array $modules
27 | * @return $this
28 | */
29 | public function setModules(array $modules)
30 | {
31 | $this->modules = $modules;
32 |
33 | return $this;
34 | }
35 |
36 | /**
37 | * @param null|string $alias
38 | * @return mixed|null
39 | */
40 | public function getModule($alias = null)
41 | {
42 | if(! count($this->modules)) {
43 | return get_module_information($alias);
44 | }
45 |
46 | if (!$alias) {
47 | return $this->modules;
48 | }
49 | foreach ($this->modules as $module) {
50 | if (array_get($module, 'alias') === $alias) {
51 | return $module;
52 | }
53 | }
54 | return null;
55 | }
56 |
57 | /**
58 | * @param string $alias
59 | * @param array $data
60 | * @param Closure|null $callback
61 | * @return $this
62 | */
63 | public function modifyModule($alias, array $data, \Closure $callback = null)
64 | {
65 | $currentModule = $this->getModule($alias);
66 | if (!$currentModule) {
67 | throw new \RuntimeException('Module not found: ' . $alias);
68 | }
69 |
70 | $file = $currentModule['file'];
71 | unset($currentModule['file']);
72 | unset($currentModule['type']);
73 |
74 | File::put($file, json_encode_pretify(array_merge($currentModule, $data)));
75 |
76 | if ($callback) {
77 | call_user_func($callback);
78 | }
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * @param $alias
85 | * @param bool|true $withEvent
86 | * @return $this
87 | */
88 | public function enableModule($alias, $withEvent = true)
89 | {
90 | $this->modifyModule($alias, ['enabled' => true], function () use ($alias, $withEvent) {
91 | if ($withEvent) {
92 | event(new ModuleEnabled($alias));
93 | }
94 | });
95 | // $result = $this->modifyModuleAutoload($alias);
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * @param string $alias
102 | * @return ModulesManagement
103 | */
104 | public function disableModule($alias, $withEvent = true)
105 | {
106 | $this->modifyModule($alias, ['enabled' => false], function () use ($alias, $withEvent) {
107 | if ($withEvent) {
108 | event(new ModuleDisabled($alias));
109 | }
110 | });
111 |
112 | // $result = $this->modifyModuleAutoload($alias, true);
113 |
114 | return $this;
115 | }
116 |
117 | /**
118 | * Determine when module is activated
119 | * @param string $moduleName
120 | * @param \Closure|null $trueCallback
121 | * @param \Closure|null $falseCallback
122 | * @return bool
123 | */
124 | public function isActivated($moduleName, Closure $trueCallback = null, Closure $falseCallback = null)
125 | {
126 | $module = $this->getModule($moduleName);
127 | if ($module && isset($module['enabled']) && $module['enabled']) {
128 | if ($trueCallback) {
129 | call_user_func($trueCallback);
130 | }
131 | return true;
132 | }
133 | if ($falseCallback) {
134 | call_user_func($falseCallback);
135 | }
136 | return false;
137 | }
138 |
139 | /**
140 | * @param string $type
141 | * @param null|int $page
142 | * @param int $perPage
143 | * @return \Illuminate\Support\Collection
144 | */
145 | public function export($type = 'base', $page = null, $perPage = 10)
146 | {
147 | $modules = collect($this->modules)
148 | ->where('type', '=', $type);
149 |
150 | if ($page) {
151 | $modules = $modules->forPage($page, $perPage);
152 | }
153 |
154 | return $modules;
155 | }
156 |
157 | /**
158 | * Modify the composer autoload information
159 | * @param $alias
160 | * @param bool $isDisabled
161 | * @return $this
162 | */
163 | public function modifyModuleAutoload($alias, $isDisabled = false)
164 | {
165 | $module = $this->getModule($alias);
166 | if (!$module) {
167 | return $this;
168 | }
169 | $moduleAutoloadType = array_get($module, 'autoload', 'psr-4');
170 | $relativePath = str_replace(base_path() . DIRECTORY_SEPARATOR, '', str_replace('module.json', '', array_get($module, 'file', ''))) . 'src';
171 |
172 | $moduleNamespace = array_get($module, 'namespace');
173 |
174 | if (!$moduleNamespace) {
175 | return $this;
176 | }
177 |
178 | if (substr($moduleNamespace, -1) !== '\\') {
179 | $moduleNamespace .= '\\';
180 | }
181 |
182 | /**
183 | * Composer information
184 | */
185 | $composerContent = json_decode(File::get(base_path('composer.json')), true);
186 | $autoload = array_get($composerContent, 'autoload', []);
187 |
188 | if (!array_get($autoload, $moduleAutoloadType)) {
189 | $autoload[$moduleAutoloadType] = [];
190 | }
191 |
192 | if ($isDisabled === true) {
193 | if (isset($autoload[$moduleAutoloadType][$moduleNamespace])) {
194 | unset($autoload[$moduleAutoloadType][$moduleNamespace]);
195 | }
196 | } else {
197 | if ($moduleAutoloadType === 'classmap') {
198 | $autoload[$moduleAutoloadType][] = $relativePath;
199 | } else {
200 | $autoload[$moduleAutoloadType][$moduleNamespace] = $relativePath;
201 | }
202 | }
203 | $composerContent['autoload'] = $autoload;
204 |
205 | /**
206 | * Save file
207 | */
208 | File::put(base_path('composer.json'), json_encode_pretify($composerContent));
209 | $this->refreshComposerAutoload();
210 |
211 |
212 | return $this;
213 | }
214 |
215 | /**
216 | * Run command composer dump-autoload
217 | * @return $this
218 | */
219 | public function refreshComposerAutoload()
220 | {
221 | $this->composer->dumpAutoloads();
222 |
223 | return $this;
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/tests/Unit/ModuleManagerTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
22 | }
23 |
24 | public function testAvailableCommands()
25 | {
26 | // Artisan::call('module:create', ['alias'=> $this->module, "\n","\n", 'Mahbub' ]);
27 | Artisan::call('module:make:controller', ['alias'=> $this->module, 'name'=> 'TestController']);
28 | Artisan::call('module:make:command', ['alias'=> $this->module, 'name'=> 'TestCommand']);
29 | Artisan::call('module:make:facade', ['alias'=> $this->module, 'name'=> 'TestFacade']);
30 | Artisan::call('module:make:middleware', ['alias'=> $this->module, 'name'=> 'TestMiddleware']);
31 | Artisan::call('module:make:migration', ['alias'=> $this->module, 'name' => 'create_test_table' , '--table'=>'tests']);
32 | Artisan::call('module:make:model',['alias'=> $this->module, 'name'=> 'TestModel']);
33 | Artisan::call('module:make:provider',['alias'=> $this->module, 'name'=> 'TestProvider']);
34 | Artisan::call('module:make:request',['alias'=> $this->module, 'name'=> 'TestRequest']);
35 | Artisan::call('module:make:service',['alias'=> $this->module, 'name'=> 'TestService']);
36 | Artisan::call('module:migrate',['alias'=> $this->module]);
37 | Artisan::call('module:migrate:rollback',['alias'=> $this->module]);
38 | Artisan::call('module:install',['alias'=> $this->module]);
39 | Artisan::call('module:uninstall',['alias'=> $this->module]);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------