From 6d1357618526a61d3b8267edf42d51ad485eeb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Kv=C3=A1=C4=8Dek?= Date: Mon, 14 Mar 2016 13:14:01 +0100 Subject: [PATCH] FEATURE: use module_settings field instaed of config(). This way should be more reliable, because config() is available only after publishing module, however I can't publish module when it does not have config (module.json). In this way I can select all modules from database and generate module.json for each of them. --- app/Handlers/Contracts/AppHandler.php | 7 ++++ app/Handlers/Handler.php | 60 +++++++++++++-------------- app/Models/Module.php | 43 ++++++++++++++++--- app/Providers/ModuleManager.php | 23 ++++++++-- 4 files changed, 94 insertions(+), 39 deletions(-) diff --git a/app/Handlers/Contracts/AppHandler.php b/app/Handlers/Contracts/AppHandler.php index 26a9324e..5512f6d3 100644 --- a/app/Handlers/Contracts/AppHandler.php +++ b/app/Handlers/Contracts/AppHandler.php @@ -87,4 +87,11 @@ interface AppHandler * @param User $user model of logged user */ public static function registerAdminMenu(User $user); + + /** + * Install module + * + * @return mixed + */ + public static function install(); } \ No newline at end of file diff --git a/app/Handlers/Handler.php b/app/Handlers/Handler.php index 56f78074..b3ebca89 100644 --- a/app/Handlers/Handler.php +++ b/app/Handlers/Handler.php @@ -65,16 +65,6 @@ abstract class Handler implements AppHandler // create instance of main menu \Menu::create('mainMenu', function ($menu) { - /** - * @var $menu \Pingpong\Menus\MenuBuilder - */ - - // create menu entries - - /* - * WARNING: MenuBuilder::route() does not seem to work, - * nor route() helper function. We need to use action() helper instaed. - */ $menu->route('admin.dashboard', trans('admin/mainMenu.dashboard'), [], 10, ['icon' => 'fa fa-dashboard']); $menu->dropdown(trans('admin/mainMenu.userManagement'), function ($sub) { $sub->route('users.new', trans('admin/mainMenu.newUser'), [], 10, ['icon' => 'fa fa-user-plus']); @@ -82,26 +72,32 @@ abstract class Handler implements AppHandler $sub->route('users.overview', trans('admin/mainMenu.usersOverview'), [], 30, ['icon' => 'fa fa-users']); }, 20, ['icon' => 'fa fa-users']); $menu->dropdown(trans('admin/mainMenu.contentPages'), function ($sub) { + $modules = ModuleNamesWithIds::getWithTranslations(); - $sub->dropdown(trans('admin/mainMenu.newContentPage'), function ($sub) { - $i = 1; - $modules = ModuleNamesWithIds::getWithTranslations(); - foreach ($modules as $module => $name) { - $sub->route('content.new', trans($name), ['moduleId' => $module], $i++); - } - }, 10, ['icon' => 'fa fa-plus']); + if (!empty($modules)) { + $sub->dropdown(trans('admin/mainMenu.newContentPage'), function ($sub) use ($modules) { + $i = 1; + foreach ($modules as $module => $name) { + $sub->route('content.new', trans($name), ['moduleId' => $module], $i++); + } + }, 10, ['icon' => 'fa fa-plus']); + } $sub->route('content.overview', trans('admin/mainMenu.contentPageOverview'), [], 20, ['icon' => 'fa fa-list']); }, 15, ['icon' => 'fa fa-database']); $menu->route('upload.overview', trans('admin/mainMenu.fileManager'), [], 30, ['icon' => 'fa fa-folder']); $menu->dropdown(trans('admin/mainMenu.widgets'), function ($sub) { // create list of all widget types - $sub->dropdown(trans('admin/mainMenu.newWidget'), function ($sub) { - $i = 1; - foreach (WidgetTypes::getWithTranslations() as $type => $name) { - $sub->route('widgets.new', $name, ['type' => $type], $i++); - } - }, 10, ['icon' => 'fa fa-plus']); + $widgets = WidgetTypes::getWithTranslations(); + + if (!empty($widgets)) { + $sub->dropdown(trans('admin/mainMenu.newWidget'), function ($sub) use ($widgets) { + $i = 1; + foreach ($widgets as $type => $name) { + $sub->route('widgets.new', $name, ['type' => $type], $i++); + } + }, 10, ['icon' => 'fa fa-plus']); + } $sub->route('widgets.overview', trans('admin/mainMenu.widgetsOverview'), [], 20, ['icon' => 'fa fa-list']); @@ -111,13 +107,17 @@ abstract class Handler implements AppHandler $sub->route('widgetareas.overview', trans('admin/mainMenu.widgetAreaOverview'), [], 2, ['icon' => 'fa fa-list']); }, 50, ['icon' => 'fa fa-object-group']); }, 28, ['icon' => 'fa fa-gears']); - $menu->dropdown(trans('admin/mainMenu.templates'), function ($sub) { - $i = 1; - $templatePaths = TemplatePathsHumanReadableRootOnly::getWithTranslations(); - foreach ($templatePaths as $id => $name) { - $sub->route('templates.overview', $name, ['id' => $id], $i++); - } - }, 29, ['icon' => 'fa fa-folder-open']); + + $templatePaths = TemplatePathsHumanReadableRootOnly::getWithTranslations(); + + if (!empty($templatePaths)) { + $menu->dropdown(trans('admin/mainMenu.templates'), function ($sub) use ($templatePaths) { + $i = 1; + foreach ($templatePaths as $id => $name) { + $sub->route('templates.overview', $name, ['id' => $id], $i++); + } + }, 29, ['icon' => 'fa fa-folder-open']); + } $menu->dropdown(trans('admin/mainMenu.customFields'), function ($sub) { $sub->route('customfields.new', trans('admin/mainMenu.customFieldsNew'), [], 10, ['icon' => 'fa fa-code']); $sub->route('customfields.overview', trans('admin/mainMenu.customFieldsOverview'), [], 50, ['icon' => 'fa fa-code-fork']); diff --git a/app/Models/Module.php b/app/Models/Module.php index 36fd14eb..162e61d9 100644 --- a/app/Models/Module.php +++ b/app/Models/Module.php @@ -3,23 +3,56 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\App; /** * Class Module */ class Module extends Model { - public $timestamps = false; - protected $fillable = [ 'handler', 'name', 'description', - 'alias' + 'alias', + 'module_settings', + 'enabled' ]; - protected $guarded = []; - + /** + * Create new module in database + * + * @param $name + * @param $alias + * @param string $description + * @param null $handler + * @param array $settings + * + * @return Module + * @throws \ErrorException + */ + public static function install($name, $alias, $description, $handler, $settings) + { + // check if user does not want to install module in runtime + if (!App::runningInConsole()) { + throw new \ErrorException('Modules can be installed only via Artisan!'); + } + + // insert module into database + $module = Module::create([ + 'name' => $name, + 'description' => $description, + 'handler' => $handler, + 'alias' => $alias, + 'module_settings' => json_encode($settings), + 'enabled' => 1 + ]); + + // install something module-specific + call_user_func([$handler, 'install']); + + return $module; + } } \ No newline at end of file diff --git a/app/Providers/ModuleManager.php b/app/Providers/ModuleManager.php index ee10cce5..bb8c73db 100644 --- a/app/Providers/ModuleManager.php +++ b/app/Providers/ModuleManager.php @@ -43,16 +43,31 @@ class ModuleManager extends ServiceProvider */ private function createModulesJson(Module $module) { - $data = config($module->alias); - $data['active'] = $module->enabled; + $config = json_decode($module->module_settings); + + if (is_null($config)) { + return; + } // path to module.json - $path = config('modules.paths.modules') . DIRECTORY_SEPARATOR . $data['name'] . DIRECTORY_SEPARATOR . 'module.json'; + $path = config('modules.paths.modules') . DIRECTORY_SEPARATOR . $config->staticName . DIRECTORY_SEPARATOR . 'module.json'; + // check if module config is writable if (!is_writable($path)) { - throw new \ErrorException('Cannot write to ' . $path . '. Module ' . $data['name'] . ' cannot be enabled.'); + return; } + // set enabled/disabled status for this module + $data = new \stdClass(); + $data->name = $config->staticName; + $data->description = $module->description; + $data->alias = $module->alias; + $data->providers = $config->providers; + $data->aliases = $config->aliases; + $data->order = $config->order; + $data->files = $config->files; + $data->active = $module->enabled; + // create file file_put_contents($path, json_encode($data)); }