diff --git a/app/Classes/Repositories/PageRepository.php b/app/Classes/Repositories/PageRepository.php
index eeb4aa48..ff419984 100644
--- a/app/Classes/Repositories/PageRepository.php
+++ b/app/Classes/Repositories/PageRepository.php
@@ -10,8 +10,8 @@
use App\Model\Page;
use Illuminate\Support\Collection;
-use App\Plugins\Pages\Model\PageTypes;
-use App\Plugins\Pages\Model\PageOptions;
+use App\Modules\Pages\Model\PageTypes;
+use App\Modules\Pages\Model\PageOptions;
use Illuminate\Database\Eloquent\Builder;
/**
@@ -53,9 +53,9 @@ public function allNormalPages()
*
* @return $collection
*/
- public function allPluginPages()
+ public function allModulePages()
{
- $bitmask = PageTypes::TYPE_PLUGIN;
+ $bitmask = PageTypes::TYPE_MODULE;
return $this->model->whereRaw('`type` & '.$bitmask.'='.$bitmask)->get();
}
diff --git a/app/Console/Commands/JuneUpdateOne.php b/app/Console/Commands/JuneUpdateOne.php
index a90dfd4a..2d7760fa 100644
--- a/app/Console/Commands/JuneUpdateOne.php
+++ b/app/Console/Commands/JuneUpdateOne.php
@@ -4,8 +4,8 @@
use App\Model\Page;
use Illuminate\Console\Command;
-use App\Plugins\Pages\Model\PageTypes;
-use App\Plugins\Pages\Model\PageOptions;
+use App\Modules\Pages\Model\PageTypes;
+use App\Modules\Pages\Model\PageOptions;
use App\Classes\Repositories\PageRepository;
class JuneUpdateOne extends Command
@@ -59,9 +59,6 @@ public function handle()
if (! $page->editable && ! $page->special) {
$page->type = (PageTypes::TYPE_FRAMEWORK | PageTypes::TYPE_STANDARD);
$page->option = PageOptions::OPTION_PUBLIC | PageOptions::OPTION_SITEMAP;
- } elseif ($page->plugin) {
- $page->type = PageTypes::TYPE_PLUGIN;
- $page->option = PageOptions::OPTION_DEFAULT;
} elseif ($page->identifier == 'newsletter.success') {
$page->type = PageTypes::TYPE_PLUGIN;
$page->option = PageOptions::OPTION_PUBLIC;
diff --git a/app/Helpers/Global.php b/app/Helpers/Global.php
index ee26b3e7..900a1c0f 100644
--- a/app/Helpers/Global.php
+++ b/app/Helpers/Global.php
@@ -149,3 +149,11 @@ function formSelect($value, $matches)
{
return $value == $matches ? 'selected' : '';
}
+
+ /**
+ * @return \App\Modules\ModuleManager
+ */
+ function modules()
+ {
+ return app(\App\Modules\ModuleManager::class);
+ }
diff --git a/app/Model/Article.php b/app/Model/Article.php
index 4c103096..7a09bc1a 100644
--- a/app/Model/Article.php
+++ b/app/Model/Article.php
@@ -218,7 +218,7 @@ public function getPageAttribute()
*/
public function path()
{
- return url($this->page->path().'/'.$this->category->slug.'/'.$this->slug);
+ return url(config('modules.articles.route').'/'.$this->category->slug.'/'.$this->slug);
}
/**
diff --git a/app/Model/Page.php b/app/Model/Page.php
index 253e5512..f6b28053 100644
--- a/app/Model/Page.php
+++ b/app/Model/Page.php
@@ -6,10 +6,11 @@
use Laravel\Scout\Searchable;
use App\Model\Concerns\Publishers;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\DB;
use App\Classes\Interfaces\Linkable;
use App\Model\Concerns\ActivityFeed;
-use App\Plugins\Pages\Model\PageTypes;
-use App\Plugins\Pages\Model\PageOptions;
+use App\Modules\Pages\Model\PageTypes;
+use App\Modules\Pages\Model\PageOptions;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -31,6 +32,7 @@
* @property string $heading
* @property string $description
* @property string $keywords
+ * @property string $module
* @property int $views
* @property int $type
* @property int $option
@@ -266,7 +268,7 @@ public function getKeywordsAttribute()
/**
* Return the status if the page has the options specified.
*
- * @param PageOptions $options Values of the required options
+ * @param string $options Values of the required options
*
* @return bool the returned condition
*/
@@ -278,7 +280,7 @@ public function hasOption($options)
$constant = constant(sprintf('%s::OPTION_%s', PageOptions::class, strtoupper($option)));
if ($this->option & $constant) {
- return $constant;
+ return true;
}
}
@@ -288,7 +290,7 @@ public function hasOption($options)
/**
* Return if the current page type matches the condition giving.
*
- * @param PageTypes $type The type required for the condition
+ * @param string $type The type required for the condition
*
* @return bool The condition of the function.
*/
@@ -298,4 +300,29 @@ public function isType(string $type)
return $this->type & $constant;
}
+
+ /**
+ * Toggle the disability of all the module pages.
+ * (Enable, Disable);.
+ *
+ * If one page fails, do not toggle.
+ *
+ * @param string $module
+ *
+ * @return mixed
+ */
+ public static function toggleModuleDisability(string $module, bool $active)
+ {
+ DB::transaction(function () use ($module, $active) {
+ if ($active == true) {
+ foreach (self::whereModule($module)->get() as $page) {
+ $page->update(['option' => $page->option & ~PageOptions::OPTION_DISABLED]);
+ }
+ } else {
+ foreach (self::whereModule($module)->get() as $page) {
+ $page->update(['option' => $page->option | PageOptions::OPTION_DISABLED]);
+ }
+ }
+ });
+ }
}
diff --git a/app/Model/Plugin.php b/app/Model/Plugin.php
deleted file mode 100644
index 172a40e5..00000000
--- a/app/Model/Plugin.php
+++ /dev/null
@@ -1,299 +0,0 @@
- 'boolean', 'required' => 'boolean'];
-
- /**
- * Undocumented function.
- *
- * @return void
- */
- public function getRouteKeyName()
- {
- return 'name';
- }
-
- /**
- * Toggle the enabled status of the plugin.
- *
- * @return bool
- */
- public function toggle()
- {
- return $this->update(['enabled' => ! $this->enabled]);
- }
-
- /**
- * Return the namespace path to the controller of the plugin.
- *
- * @return string
- */
- public function getControllerAttribute()
- {
- return app()->make(sprintf("App\Plugins\%s\%sController", $this->name, $this->name));
- }
-
- /**
- * Call the install method on the plugins controller.
- *
- * @param string $plugin_name The plugin name to install
- * @return Plugin The model instance of the installed plugin
- */
- public static function install(string $plugin_name)
- {
- $plugin = self::whereName($plugin_name)->first();
-
- $plugin->update(['enabled' => true]);
-
- $plugin->controller->install();
-
- return $plugin;
- }
-
- /**
- * @deprecated
- * @return PluginHandler
- */
- protected function getHandlerAttribute()
- {
- return app(sprintf("%s\%sController", $this->dirNamespace(), ucfirst($this->name)));
- }
-
- /**
- * ==========================================================.
- *
- * GET THE ATTRIBUTES OF THE MODEL
- *
- * ==========================================================
- */
- public function icon()
- {
- return $this->controller->icon();
- }
-
- public function name()
- {
- return $this->name;
- }
-
- public function version()
- {
- return $this->controller->version();
- }
-
- public function isEnabled()
- {
- return $this->getAttribute('enabled') == true;
- }
-
- public function isDisabled()
- {
- return $this->getAttribute('enabled') == false;
- }
-
- public function isFrontEnd()
- {
- return $this->getAttribute('is_frontend');
- }
-
- public function isBackEnd()
- {
- return $this->getAttribute('is_backend');
- }
-
- public function getCreatedAt()
- {
- return $this->getAttribute('created_at');
- }
-
- public function getUpdatedAt()
- {
- return $this->getAttribute('updated_at');
- }
-
- public function setEnabled($boolean)
- {
- if ($boolean == true) {
- return $this->enable();
- }
-
- return $this->disable();
- }
-
- /**
- * Enable the product.
- *
- * @return $this
- */
- public function enable()
- {
- $this->setAttribute('enabled', true);
-
- return $this;
- }
-
- /**
- * Disable the product.
- *
- * @return $this
- */
- public function disable()
- {
- $this->setAttribute('enabled', false);
-
- return $this;
- }
-
- public function setInstalled(bool $boolean)
- {
- $this->setAttribute('installed', $boolean ? 1 : 0);
-
- return $this;
- }
-
- /**
- * @return mixed
- */
- public function isInstalled()
- {
- return $this->getAttribute('installed') ? true : false;
- }
-
- public function setName($string)
- {
- $this->setAttribute('name', $string);
-
- return $this;
- }
-
- public function setVersion($integer)
- {
- $this->setAttribute('version', $integer);
-
- return $this;
- }
-
- public function setIcon($string)
- {
- $this->setAttribute('icon', $string);
-
- return $this;
- }
-
- public function adminUrl()
- {
- if ($this->isBackEnd()) {
- return route("admin.{$this->name}.index");
- }
-
- throw new \Exception('This is not a backend enabled plugin and should not be used here.');
- }
-
- public function userUrl()
- {
- if ($this->isFrontEnd()) {
- return url($this->name());
- }
-
- throw new \Exception('This is not a frontend enabled plugin and should not be used here.');
- }
-
- public function isHidden()
- {
- return $this->getAttribute('hidden') ? true : false;
- }
-
- public function setHide(bool $boolean)
- {
- $this->setAttribute('hidden', $boolean ? 1 : 0);
-
- return $this;
- }
-
- public function setRequired($boolean)
- {
- $this->setAttribute('required', $boolean);
-
- return $this;
- }
-
- public function setFrontEnd($boolean)
- {
- $this->setAttribute('is_frontend', $boolean);
-
- return $this;
- }
-
- public function setBackEnd($boolean)
- {
- $this->setAttribute('is_backend', $boolean);
-
- return $this;
- }
-
- /**
- * @return \Illuminate\Database\Eloquent\Relations\HasMany
- */
- public function options()
- {
- return $this->hasMany(PluginOption::class, 'plugin_id', 'id');
- }
-
- public function option($key)
- {
- return $this->options->where('key', $key)->first()->value();
- }
-
- public function feeds()
- {
- return $this->hasMany(PluginFeed::class, 'plugin_id', 'id');
- }
-}
diff --git a/app/Plugins/Articles/BackendController.php b/app/Modules/Articles/BackendController.php
similarity index 96%
rename from app/Plugins/Articles/BackendController.php
rename to app/Modules/Articles/BackendController.php
index e442d49f..b894085d 100644
--- a/app/Plugins/Articles/BackendController.php
+++ b/app/Modules/Articles/BackendController.php
@@ -1,25 +1,19 @@
uses('BackendController@categories')->name('admin.articles.categories.index');
Route::post('admin/articles/categories')->uses('BackendController@categories_store')->name('admin.articles.categories.store');
-
Route::resource('admin/articles', 'BackendController', ['as' => 'admin']);
diff --git a/app/Modules/Articles/Routes/frontend.php b/app/Modules/Articles/Routes/frontend.php
new file mode 100644
index 00000000..738bb112
--- /dev/null
+++ b/app/Modules/Articles/Routes/frontend.php
@@ -0,0 +1,26 @@
+uses('FrontendController@allArticles')->name('articles.all');
+ Route::get(config('modules.articles.route').'/search')->uses('FrontendController@searchArticles')->name('search.articles');
+ Route::get(config('modules.articles.route').'/{category}')->uses('FrontendController@categoryArticles')->name('category.articles');
+ Route::get(config('modules.articles.route').'/creator/{account}')->uses('FrontendController@allCreatorsArticles')->name('creator.articles');
+ Route::get(config('modules.articles.route').'/{category}/{article}')->uses('FrontendController@viewArticle')->name('article.view');
diff --git a/app/Modules/Configs/Blade/index.blade.php b/app/Modules/Configs/Blade/index.blade.php
new file mode 100644
index 00000000..32ce310d
--- /dev/null
+++ b/app/Modules/Configs/Blade/index.blade.php
@@ -0,0 +1,192 @@
+@extends('dashboard::frame')
+
+@section('title')
+ Settings
+@endsection
+
+@section('information')
+ Your application can be modified with straight forward, powerful options that you can change to match your needs.
+@endsection
+
+@section('content')
+
+
+
+
+
+
+@endsection
diff --git a/app/Modules/Configs/Controller.php b/app/Modules/Configs/Controller.php
new file mode 100644
index 00000000..c8645f60
--- /dev/null
+++ b/app/Modules/Configs/Controller.php
@@ -0,0 +1,55 @@
+middleware(['role:administrator']);
+ }
+
+ /**
+ * Settings are already loaded within the application
+ * best to use the loaded settings from that instead.
+ *
+ * Helper function (Settings())
+ *
+ * @return mixed
+ */
+ public function index()
+ {
+ return $this->make('index');
+ }
+
+ /**
+ * Save the changes for settings.
+ *
+ * @param Request $request
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function update(Request $request)
+ {
+ foreach ($request['setting'] as $key => $value) {
+ Configuration::set($key, $value);
+ }
+
+ return redirect()->intended(route('admin.settings.index'));
+ }
+}
diff --git a/app/Plugins/Products/Routes/backend.php b/app/Modules/Configs/Routes/backend.php
similarity index 59%
rename from app/Plugins/Products/Routes/backend.php
rename to app/Modules/Configs/Routes/backend.php
index e95d6a45..33979e66 100644
--- a/app/Plugins/Products/Routes/backend.php
+++ b/app/Modules/Configs/Routes/backend.php
@@ -15,10 +15,8 @@
// Get Requests.
// ==================================================================================
- Route::get('/admin/products/index', 'BackendController@index')->name('admin.products.index');
+ Route::get('/admin/settings')->uses('Controller@index')->name('admin.settings.index');
- /*
- * Login for plugins.
- */
- Route::get('/admin/products/install/{plugin}')->uses('BackendController@install')->name('products.install');
- Route::get('/admin/products/uninstall/{plugin}')->uses('BackendController@uninstall')->name('products.uninstall');
+ // Post Requests.
+ // ==================================================================================
+ Route::post('/admin/settings/update')->uses('Controller@update')->name('admin.settings.update');
diff --git a/app/Plugins/Menus/Routes/frontend.php b/app/Modules/Configs/Routes/frontend.php
similarity index 100%
rename from app/Plugins/Menus/Routes/frontend.php
rename to app/Modules/Configs/Routes/frontend.php
diff --git a/app/Modules/ModuleManager.php b/app/Modules/ModuleManager.php
new file mode 100644
index 00000000..dfd66cbb
--- /dev/null
+++ b/app/Modules/ModuleManager.php
@@ -0,0 +1,132 @@
+repository = $repository;
+ }
+
+ /**
+ * Enable a module using the modules.php configuration.
+ *
+ * @param string $module
+ *
+ * @return void
+ *
+ * @throws ModuleNotFoundException
+ */
+ public function enable(string $module)
+ {
+ $this->repository->set("{$module}.enabled", true)->save();
+
+ $this->updatePageBelongingTo($module, $this->repository->get("{$module}.enabled"));
+ }
+
+ /**
+ * @param string $module
+ * @return void
+ * @throws ModuleNotFoundException
+ */
+ public function disable(string $module)
+ {
+ $this->repository->set("{$module}.enabled", false)->save();
+
+ $this->updatePageBelongingTo($module, $this->repository->get("{$module}.enabled"));
+ }
+
+ /**
+ * Toggle the status of a module in the configuration.
+ *
+ * @param string $module
+ *
+ * @return $this
+ * @throws \App\Modules\ModuleNotFoundException
+ */
+ public function toggle(string $module)
+ {
+ $this->repository->set("{$module}.enabled", ! $this->repository->get("{$module}.enabled"))->save();
+
+ $this->updatePageBelongingTo($module, $this->repository->get("{$module}.enabled"));
+ }
+
+ /**
+ * Get the status of a module from the module repository, including the new values if it was set.
+ *
+ * @param string $module
+ *
+ * @return mixed
+ */
+ public function status(string $module)
+ {
+ return $this->repository->get("{$module}.enabled");
+ }
+
+ /**
+ * Update the route of a module configuration.
+ *
+ * @param string $module
+ * @param string $newRoute
+ *
+ * @return bool
+ * @throws ModuleNotFoundException
+ */
+ public function route(string $module, string $newRoute)
+ {
+ return $this->repository->set("{$module}.route", $newRoute)->save();
+ }
+
+ /**
+ * Return the array collection of all enabled modules.
+ *
+ * @return array
+ */
+ public function getActive()
+ {
+ return array_where($this->repository->all(), function ($value) {
+ return $value['enabled'] == true;
+ });
+ }
+
+ /**
+ * Return the array collection of all disabled modules.
+ *
+ * @return array
+ */
+ public function getInactive()
+ {
+ return array_where($this->repository->all(), function ($value) {
+ return $value['enabled'] == false;
+ });
+ }
+
+ /**
+ * Sync the module pages to load with the condig status.
+ *
+ * @param $module
+ * @param bool $status
+ *
+ * @return void
+ */
+ private function updatePageBelongingTo($module, bool $status)
+ {
+ Page::toggleModuleDisability($module, $status);
+ }
+}
diff --git a/app/Modules/ModuleNotFoundException.php b/app/Modules/ModuleNotFoundException.php
new file mode 100644
index 00000000..eda19389
--- /dev/null
+++ b/app/Modules/ModuleNotFoundException.php
@@ -0,0 +1,10 @@
+module = $module;
+ }
+
+ /**
+ * Handle pages that have been updated.
+ *
+ * @param Page $page
+ *
+ * @return void
+ * @throws ModuleNotFoundException
+ */
+ public function updated(Page $page)
+ {
+ $this->updateModuleRoute($page);
+ }
+
+ /**
+ * Handle pages that have been created.
+ *
+ * @param Page $page
+ *
+ * @throws ModuleNotFoundException
+ */
+ public function created(Page $page)
+ {
+ $this->updateModuleRoute($page);
+ }
+
+ /**
+ * Check if the page is type router.
+ *
+ * @param Page $page
+ *
+ * @return int
+ */
+ private function isTypeRouter(Page $page): int
+ {
+ return $page->type & PageTypes::TYPE_ROUTER;
+ }
+
+ /**
+ * Update the modules route on the configuration file.
+ *
+ * @param Page $page
+ * @throws ModuleNotFoundException
+ */
+ public function updateModuleRoute(Page $page)
+ {
+ if ($this->isTypeRouter($page)) {
+ $this->module->route($page->module, $page->slug);
+ }
+ }
+}
diff --git a/app/Modules/ModuleServiceProvider.php b/app/Modules/ModuleServiceProvider.php
new file mode 100644
index 00000000..dfef2407
--- /dev/null
+++ b/app/Modules/ModuleServiceProvider.php
@@ -0,0 +1,60 @@
+app->singleton(ModuleManager::class, function () {
+ return new ModuleManager(app(ModuleRepository::class));
+ });
+ }
+
+ /**
+ * Register the route mapping of the modules.
+ *
+ * @return void.
+ */
+ public static function map()
+ {
+ foreach (config('modules') as $key => $module) {
+ $namespace = sprintf('App\Modules\%s', $module['title']);
+
+ if (config("modules.{$key}.enabled")) {
+ $backendRoute = base_path(sprintf('app/Modules/%s/Routes/backend.php', $module['title']));
+ if (file_exists($backendRoute)) {
+ Route::middleware(['web', 'auth', 'gateway'])->namespace($namespace)->group($backendRoute);
+ }
+
+ $frontendRoute = base_path(sprintf('app/Modules/%s/Routes/frontend.php', $module['title']));
+ if (file_exists($frontendRoute)) {
+ Route::middleware(['web'])->namespace($namespace)->group($frontendRoute);
+ }
+ }
+ }
+ }
+}
diff --git a/app/Plugins/Menus/BackendController.php b/app/Modules/Navigation/BackendController.php
similarity index 96%
rename from app/Plugins/Menus/BackendController.php
rename to app/Modules/Navigation/BackendController.php
index 0879d518..626effe0 100644
--- a/app/Plugins/Menus/BackendController.php
+++ b/app/Modules/Navigation/BackendController.php
@@ -6,13 +6,13 @@
* Time: 14:55.
*/
-namespace App\Plugins\Menus;
+namespace App\Modules\Navigation;
use DB;
use App\Model\Link;
use App\Model\Menu;
use Illuminate\Http\Request;
-use App\Plugins\PluginEngine;
+use App\Modules\ModuleEngine;
use Illuminate\Validation\Rule;
use App\Classes\Repositories\LinkRepository;
use App\Classes\Repositories\MenuRepository;
@@ -21,7 +21,7 @@
/**
* Class Controller.
*/
-class BackendController extends PluginEngine
+class BackendController extends ModuleEngine
{
/**
* @var MenuRepository
@@ -89,7 +89,7 @@ public function store(Request $request, Menu $menu)
$this->save($request, $menu);
- return redirect()->route('admin.menus.index');
+ return redirect()->route('admin.navigation.index');
}
/**
@@ -131,7 +131,7 @@ public function update(Request $request, $id)
$this->save($request, $menu);
- return redirect(route('admin.menus.index'));
+ return redirect(route('admin.navigation.index'));
}
/**
@@ -156,7 +156,7 @@ public function destroy($id)
$menu->delete();
- return redirect(route('admin.menus.index'));
+ return redirect(route('admin.navigation.index'));
}
/**
diff --git a/app/Plugins/Menus/Blade/create.blade.php b/app/Modules/Navigation/Blade/create.blade.php
similarity index 96%
rename from app/Plugins/Menus/Blade/create.blade.php
rename to app/Modules/Navigation/Blade/create.blade.php
index bf990fe6..207f82b0 100644
--- a/app/Plugins/Menus/Blade/create.blade.php
+++ b/app/Modules/Navigation/Blade/create.blade.php
@@ -12,7 +12,7 @@
@include('dashboard::structure.validation')
-
@@ -70,8 +70,8 @@
diff --git a/app/Modules/Navigation/FrontendController.php b/app/Modules/Navigation/FrontendController.php
new file mode 100644
index 00000000..93f82db6
--- /dev/null
+++ b/app/Modules/Navigation/FrontendController.php
@@ -0,0 +1,11 @@
+ 'admin']);
+ Route::resource('admin/navigation', 'BackendController', ['as' => 'admin']);
// Ajax reorder.
- Route::post('/admin/menus/reorder/')->uses('BackendController@reorder')->name('admin.menus.reorder');
+ Route::post('/admin/menus/reorder/')->uses('BackendController@reorder')->name('admin.navigation.reorder');
// Allows groupings on the index.
- Route::get('/admin/menus/group/{group_id}')->uses('BackendController@index')->name('admin.menus.group');
+ Route::get('/admin/menus/group/{group_id}')->uses('BackendController@index')->name('admin.navigation.group');
// Post Requests.
// ==================================================================================
diff --git a/app/Plugins/Products/Routes/frontend.php b/app/Modules/Navigation/Routes/frontend.php
similarity index 100%
rename from app/Plugins/Products/Routes/frontend.php
rename to app/Modules/Navigation/Routes/frontend.php
diff --git a/app/Plugins/Newsletters/BackendController.php b/app/Modules/Newsletters/BackendController.php
similarity index 86%
rename from app/Plugins/Newsletters/BackendController.php
rename to app/Modules/Newsletters/BackendController.php
index 0c1389c8..7b19361b 100644
--- a/app/Plugins/Newsletters/BackendController.php
+++ b/app/Modules/Newsletters/BackendController.php
@@ -1,21 +1,15 @@
uses('App\Plugins\Newsletters\FrontendController@joinNewsletter')->name('newsletter.join');
+ Route::post('/newsletter/join')->uses('FrontendController@joinNewsletter')->name('newsletter.join');
- Route::get('/newsletter/complete')->uses('App\Plugins\Newsletters\FrontendController@completedNewsletter')->name('newsletter.complete');
- Route::get('/newsletter/failure')->uses('App\Plugins\Newsletters\FrontendController@completedNewsletter')->name('newsletter.failure');
+ Route::get('/newsletter/complete')->uses('FrontendController@completedNewsletter')->name('newsletter.complete');
+ Route::get('/newsletter/failure')->uses('FrontendController@completedNewsletter')->name('newsletter.failure');
diff --git a/app/Plugins/Pages/BackendController.php b/app/Modules/Pages/BackendController.php
similarity index 95%
rename from app/Plugins/Pages/BackendController.php
rename to app/Modules/Pages/BackendController.php
index 86343ee3..2f86f57f 100644
--- a/app/Plugins/Pages/BackendController.php
+++ b/app/Modules/Pages/BackendController.php
@@ -6,21 +6,20 @@
* Time: 20:30.
*/
-namespace App\Plugins\Pages;
+namespace App\Modules\Pages;
-use App\Model\Link;
use App\Model\Page;
use Illuminate\Http\Request;
-use App\Plugins\PluginEngine;
+use App\Modules\ModuleEngine;
use Illuminate\Validation\Rule;
-use App\Plugins\Pages\Model\PageTypes;
-use App\Plugins\Pages\Model\PageOptions;
+use App\Modules\Pages\Model\PageTypes;
+use App\Modules\Pages\Model\PageOptions;
use App\Classes\Repositories\PageRepository;
/**
* Class Controller.
*/
-class BackendController extends PluginEngine
+class BackendController extends ModuleEngine
{
/**
* @var PageRepository
@@ -46,7 +45,7 @@ public function index()
public function indexPlugin()
{
- return $this->make('index')->with('pages', $this->repository->allPluginPages());
+ return $this->make('index')->with('pages', $this->repository->allModulePages());
}
/**
diff --git a/app/Plugins/Pages/Blade/create.blade.php b/app/Modules/Pages/Blade/create.blade.php
similarity index 100%
rename from app/Plugins/Pages/Blade/create.blade.php
rename to app/Modules/Pages/Blade/create.blade.php
diff --git a/app/Plugins/Pages/Blade/edit.blade.php b/app/Modules/Pages/Blade/edit.blade.php
similarity index 100%
rename from app/Plugins/Pages/Blade/edit.blade.php
rename to app/Modules/Pages/Blade/edit.blade.php
diff --git a/app/Plugins/Pages/Blade/index.blade.php b/app/Modules/Pages/Blade/index.blade.php
similarity index 98%
rename from app/Plugins/Pages/Blade/index.blade.php
rename to app/Modules/Pages/Blade/index.blade.php
index 33d22af8..d608b83a 100644
--- a/app/Plugins/Pages/Blade/index.blade.php
+++ b/app/Modules/Pages/Blade/index.blade.php
@@ -1,7 +1,5 @@
@extends('dashboard::frame')
-
-
@section('title')
Website Pages
@endsection
diff --git a/app/Modules/Pages/FrontendController.php b/app/Modules/Pages/FrontendController.php
new file mode 100644
index 00000000..e6a74c27
--- /dev/null
+++ b/app/Modules/Pages/FrontendController.php
@@ -0,0 +1,80 @@
+currentPage = $pages->whereName(currentURI());
+ }
+
+ /**
+ * Redirects must use a controller to handle the parameter, as they require a specified target.
+ * @return mixed
+ */
+ public function redirect()
+ {
+ return redirect($this->currentPage->redirect->to(), 302);
+ }
+
+ /**
+ * Standard page views are once that use the URL as the designated target.
+ *
+ * @return mixed
+ * @throws \Exception
+ * @internal param FrontPageLoader $pageLoader
+ */
+ public function index()
+ {
+ IncrementViews::dispatch($this->currentPage);
+
+ return Frontpage::build($this->currentPage);
+ }
+
+ /**
+ * The sitemap function allows plugins to quickly and effectively
+ * create and store new content for the SEO Sitemap Controller.
+ *
+ * @param SitemapGenerator $sitemap
+ * @return SitemapGenerator
+ */
+ public function sitemap(SitemapGenerator $sitemap)
+ {
+ /** @var PageRepository $repository */
+ $repository = app(PageRepository::class);
+
+ /** @var Page $page */
+ foreach ($repository->whereSitemap() as $page) {
+ $sitemap->store(url($page->route()), $page->updated_at, 'bi-weekly', '1.0');
+ }
+
+ return $sitemap;
+ }
+}
diff --git a/app/Plugins/Pages/Model/PageOptions.php b/app/Modules/Pages/Model/PageOptions.php
similarity index 88%
rename from app/Plugins/Pages/Model/PageOptions.php
rename to app/Modules/Pages/Model/PageOptions.php
index 159953ea..9a7609fe 100644
--- a/app/Plugins/Pages/Model/PageOptions.php
+++ b/app/Modules/Pages/Model/PageOptions.php
@@ -1,6 +1,6 @@
frontendPageCollection() as $page) {
- if (! $page->redirect && ! $page->plugin) {
- Route::get($page->route())->uses('App\Http\Controllers\PageController@index');
+ if (! $page->redirect && ! $page->module) {
+ Route::get($page->route())->uses('FrontendController@index');
}
}
diff --git a/app/Modules/Products/BackendController.php b/app/Modules/Products/BackendController.php
new file mode 100644
index 00000000..7dd0d92d
--- /dev/null
+++ b/app/Modules/Products/BackendController.php
@@ -0,0 +1,45 @@
+middleware(['role:developer']);
+ }
+
+ /**
+ * Display a list of products available and disable, enable option for super admins.
+ */
+ public function index()
+ {
+ return $this->make('index');
+ }
+
+ /**
+ * Toggle the enable or disable of a module.
+ *
+ * @param string $module
+ * @param ModuleManager $modules
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ *
+ * @throws \App\Modules\ModuleNotFoundException
+ */
+ public function toggle(string $module, ModuleManager $modules)
+ {
+ $modules->toggle(strtolower($module));
+
+ return response()->redirectToRoute('admin.products.index');
+ }
+}
diff --git a/app/Modules/Products/Blade/index.blade.php b/app/Modules/Products/Blade/index.blade.php
new file mode 100644
index 00000000..c728bd20
--- /dev/null
+++ b/app/Modules/Products/Blade/index.blade.php
@@ -0,0 +1,56 @@
+@extends('dashboard::frame')
+
+@section('title')
+ Product Overview
+@endsection
+
+@section('information')
+ Products are interfaces which can be switched on and off, allowing complete control of your system.
+@endsection
+
+@section('content')
+
+
+
+ @foreach(config('modules') as $module)
+
+
+
+
+ {{ ucwords($module['title']) }}
+
+
+ Version {{ $module['version'] }}
+
+
+
+
+
+
+ @if (account()->hasRole($module['role']))
+ @if ($module['enabled'] == true)
+ - Uninstall
+ @else
+ - Install
+ @endif
+ @else
+ @if ($module['enabled'])
+ - Currently Active
+ @else
+ - Disabled
+ @endif
+ @endif
+
+
+
+
+
+ {!! css()->status->check($module['enabled']) !!}
+
+
+
+ @endforeach
+
+
+
+@endsection
\ No newline at end of file
diff --git a/app/Modules/Products/Routes/backend.php b/app/Modules/Products/Routes/backend.php
new file mode 100644
index 00000000..f3f790a4
--- /dev/null
+++ b/app/Modules/Products/Routes/backend.php
@@ -0,0 +1,19 @@
+name('admin.products.index');
+ Route::get('/admin/products/{module}/toggle', 'BackendController@toggle')->name('admin.products.toggle');
diff --git a/app/Plugins/Redirects/BackendController.php b/app/Modules/Redirects/BackendController.php
similarity index 95%
rename from app/Plugins/Redirects/BackendController.php
rename to app/Modules/Redirects/BackendController.php
index b3ed8ddc..8f755dc0 100644
--- a/app/Plugins/Redirects/BackendController.php
+++ b/app/Modules/Redirects/BackendController.php
@@ -1,24 +1,17 @@
sitemap = $sitemap;
-
- $this->plugins = $plugins;
- }
-
- /**
- * @return View
- * @internal param PluginRepository $plugins
- */
- public function iframe()
- {
- // this is located on the dashboard.
- // set it up as a dashboard controller.
- $dashboard = app(DashboardController::class);
-
- $this->loadPluginSitemaps($this->plugins->allWhereActive());
- // get and create an array of all the sitemaps to be loaded
- // send to the view for display.
-
- return $this->make('index')->with('sitemaps', $this->sitemap->generateArray());
- }
-
- /**
- * @param PluginRepository $plugins
- * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
- */
- public function all()
- {
- $this->loadPluginSitemaps($this->plugins->allWhereActive());
-
- return response($this->sitemap->generateXML(), 200, ['Content-Type' => 'text/xml;charset=utf-8']);
- }
-
- private function loadPluginSitemaps(Collection $plugins)
- {
-
- /** @var Plugin $plugin */
- foreach ($plugins as $plugin) {
- $classDir = 'App\Plugins\\'.ucfirst($plugin->name).'\\FrontendController';
-
- if (class_exists($classDir)) {
- $class = app($classDir);
-
- if ($class instanceof Sitemap) {
- $this->sitemap($class);
- }
- }
- }
- }
-
- /**
- * Get the plugin sitemap function and its contents.
- *
- * @param Sitemap $plugin
- * @return bool|mixed
- */
- private function sitemap(Sitemap $plugin)
- {
- return $plugin->sitemap($this->sitemap);
}
}
diff --git a/app/Modules/Sitemap/Routes/backend.php b/app/Modules/Sitemap/Routes/backend.php
index ddab0be9..acb65b02 100644
--- a/app/Modules/Sitemap/Routes/backend.php
+++ b/app/Modules/Sitemap/Routes/backend.php
@@ -15,7 +15,7 @@
// Get Requests.
// ==================================================================================
- Route::get('/admin/sitemap')->uses('Controller@iframe')->name('sitemap.iframe');
+ //Route::get('/admin/sitemap')->uses('Controller@sitemap')->name('sitemap.xml');
// Post Requests.
// ==================================================================================
diff --git a/app/Modules/Sitemap/Routes/frontend.php b/app/Modules/Sitemap/Routes/frontend.php
index 5254a718..962988fd 100644
--- a/app/Modules/Sitemap/Routes/frontend.php
+++ b/app/Modules/Sitemap/Routes/frontend.php
@@ -15,7 +15,7 @@
// Get Requests.
// ==================================================================================
- Route::get('/sitemap.xml')->uses('App\Modules\Sitemap\Controller@all')->name('sitemap');
+ //Route::get('/sitemap.xml')->uses('Controller@all')->name('sitemap');
// Post Requests.
// ==================================================================================
diff --git a/app/Plugins/Articles/ArticlesController.php b/app/Plugins/Articles/ArticlesController.php
deleted file mode 100644
index 4de5d925..00000000
--- a/app/Plugins/Articles/ArticlesController.php
+++ /dev/null
@@ -1,76 +0,0 @@
- 'Articles',
- 'identifier' => 'articles',
- 'slug' => 'articles',
- 'type' => PageTypes::TYPE_PLUGIN,
- 'option' => PageOptions::OPTION_PUBLIC,
- ]);
-
- return $page;
- }
-
- /**
- * The steps required for this plugin product to fully
- * remove itself from the webservice.
- *
- * @return bool
- * @throws \Exception
- */
- public function uninstall()
- {
- /** @var PageRepository $repository */
- $pages = app(PageRepository::class);
-
- /** @var Page $page */
- $page = $pages->whereIdentifier('articles');
-
- // status of the operation.
- return $page->forceDelete();
- }
-}
diff --git a/app/Plugins/Articles/Routes/frontend.php b/app/Plugins/Articles/Routes/frontend.php
deleted file mode 100644
index 52717cd3..00000000
--- a/app/Plugins/Articles/Routes/frontend.php
+++ /dev/null
@@ -1,29 +0,0 @@
-path())->uses('App\Plugins\Articles\FrontendController@allArticles')->name('articles.all');
- Route::get($page->path().'/search')->uses('App\Plugins\Articles\FrontendController@searchArticles')->name('search.articles');
- Route::get($page->path().'/{category}')->uses('App\Plugins\Articles\FrontendController@categoryArticles')->name('category.articles');
- Route::get($page->path().'/creator/{account}')->uses('App\Plugins\Articles\FrontendController@allCreatorsArticles')->name('creator.articles');
- Route::get($page->path().'/{category}/{article}')->uses('App\Plugins\Articles\FrontendController@viewArticle')->name('article.view');
diff --git a/app/Plugins/Menus/FrontendController.php b/app/Plugins/Menus/FrontendController.php
deleted file mode 100644
index 9623c6cf..00000000
--- a/app/Plugins/Menus/FrontendController.php
+++ /dev/null
@@ -1,19 +0,0 @@
-whereSitemap() as $page) {
- $sitemap->store(url($page->route()), $page->updated_at, 'bi-weekly', '1.0');
- }
-
- return $sitemap;
- }
-}
diff --git a/app/Plugins/Pages/PagesController.php b/app/Plugins/Pages/PagesController.php
deleted file mode 100644
index 5d650211..00000000
--- a/app/Plugins/Pages/PagesController.php
+++ /dev/null
@@ -1,33 +0,0 @@
-make(sprintf('plugins::%s.Blade.%s', $this->pluginName(), $blade_template));
- }
-
- /**
- * Get the module name by checking the class name location.
- *
- * @todo class_basname() ?
- *
- * @return mixed
- */
- protected function pluginName()
- {
- if ($this->pluginName) {
- return $this->pluginName;
- }
-
- return $this->pluginName = explode('\\', get_class($this))[2];
- }
-
- /**
- * Redirect to a plugin view location.
- * For ajax return calls.
- *
- * @param $blade_template
- * @return \Illuminate\Http\RedirectResponse
- */
- protected function redirect($blade_template)
- {
- return redirect()->intended($this->pluginName().'::'.$blade_template);
- }
-
- /**
- * @todo what does this do and document it.
- *
- * @return Plugin|array|\stdClass
- */
- protected function pluginData()
- {
- return (new PluginRepository(new Plugin))->whereName($this->pluginName());
- }
-}
diff --git a/app/Plugins/PluginHandler.php b/app/Plugins/PluginHandler.php
deleted file mode 100644
index dc9018f7..00000000
--- a/app/Plugins/PluginHandler.php
+++ /dev/null
@@ -1,29 +0,0 @@
-plugins = $plugins;
-
- $this->middleware(['role:developer']);
- }
-
- /**
- * Display a list of products available and disable, enable option for super admins.
- */
- public function index()
- {
- return $this->make('index')->with('products', $this->plugins->all());
- }
-
- /**
- * Steps required for the application install.
- * Usually defined for logging & new sql entries.
- *
- * @param string $plugin_name
- * @return mixed
- */
- public function install(Plugin $plugin)
- {
- if ($plugin->controller instanceof Installable) {
- $plugin->controller->install();
-
- $plugin->toggle();
-
- return response()->redirectToRoute('admin.products.index');
- }
-
- throw new PluginNotInstanceOfInstallable;
- }
-
- /**
- * Steps required for the application uninstall.
- * Usually defined for logging & new sql entries.
- *
- * @param string $plugin_name
- * @return mixed
- */
- public function uninstall(Plugin $plugin)
- {
- if ($plugin->controller instanceof Installable) {
- $plugin->controller->uninstall();
-
- $plugin->toggle();
-
- return response()->redirectToRoute('admin.products.index');
- }
-
- throw new PluginNotInstanceOfInstallable;
- }
-}
diff --git a/app/Plugins/Products/Blade/index.blade.php b/app/Plugins/Products/Blade/index.blade.php
deleted file mode 100644
index d0c93cef..00000000
--- a/app/Plugins/Products/Blade/index.blade.php
+++ /dev/null
@@ -1,68 +0,0 @@
-@extends('dashboard::frame')
-
-@section('title')
- Product Overview
-@endsection
-
-@section('information')
- Products are interfaces which can be switched on and off, allowing complete control of your system.
-@endsection
-
-@section('content')
-
-
-
-
-
- @foreach($products as $product)
-
-
-
-
- {{ ucfirst($product->name()) }}
-
-
- Version {{ $product->version() }}
-
-
-
-
-
-
- @role('developer')
- @if($product->required == false)
- @if ($product->enabled)
- - Uninstall
- @else
- - Install
- @endif
- @else
- - Framework Requirement
- @endif
- @else
- @if ($product->enabled)
- - Currently Active
- @else
- - Disabled
- @endif
- @endrole
-
- {{--- {!! css()->status->installed($product->isEnabled()) !!}
--}}
- {{--- {!! css()->link->edit(route('admin.pages.edit', ["name"=>$page->slug])) !!}
--}}
- {{--- {!! css()->status->sitemap($page->sitemap) !!}
--}}
- {{--- {!! css()->status->status($page->enabled) !!}
--}}
- {{--- {!! css()->link->view(makeUrl($page)) !!}
--}}
-
-
-
-
-
- {!! css()->status->check($product->enabled) !!}
-
-
-
- @endforeach
-
-
-
-@endsection
\ No newline at end of file
diff --git a/app/Plugins/Products/Exceptions/PluginNotInstanceOfInstallable.php b/app/Plugins/Products/Exceptions/PluginNotInstanceOfInstallable.php
deleted file mode 100644
index 99638d22..00000000
--- a/app/Plugins/Products/Exceptions/PluginNotInstanceOfInstallable.php
+++ /dev/null
@@ -1,10 +0,0 @@
-bootBladeDirectives();
-
Schema::defaultStringLength(191);
}
@@ -29,16 +26,4 @@ public function register()
{
//
}
-
- /**
- * Boot blade directives.
- *
- * @return void
- */
- private function bootBladeDirectives()
- {
- Blade::if('role', function ($role) {
- return account()->hasRole($role);
- });
- }
}
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
index 2c948711..9a0847d9 100644
--- a/app/Providers/RouteServiceProvider.php
+++ b/app/Providers/RouteServiceProvider.php
@@ -2,8 +2,8 @@
namespace App\Providers;
-use App\Model\Plugin;
use Illuminate\Support\Facades\Route;
+use App\Modules\ModuleServiceProvider;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
/**
@@ -20,16 +20,6 @@ class RouteServiceProvider extends ServiceProvider
*/
protected $namespace = 'App\Http\Controllers';
- /**
- * Define your route model bindings, pattern filters, etc.
- *
- * @return void
- */
- public function boot()
- {
- parent::boot();
- }
-
/**
* Define the routes for the application.
*
@@ -37,99 +27,10 @@ public function boot()
*/
public function map()
{
- $this->mapApiRoutes();
-
- $this->mapWebRoutes();
-
- $this->mapPluginRoutes();
-
- $this->mapModulesRoutes();
-
- $this->mapVendorRoutes();
- }
-
- /**
- * Define the "web" routes for the application.
- *
- * These routes all receive session state, CSRF protection, etc.
- *
- * @return void
- */
- protected function mapWebRoutes()
- {
- $tom = [];
-
- Route::middleware('web')->namespace($this->namespace)->group(base_path('routes/web.php'));
- }
+ ModuleServiceProvider::map();
- /**
- * Define the "api" routes for the application.
- *
- * These routes are typically stateless.
- *
- * @return void
- */
- protected function mapApiRoutes()
- {
- Route::prefix('api')->middleware('api')->namespace($this->namespace)->group(base_path('routes/api.php'));
- }
+ Route::middleware('web')->group(base_path('routes/web.php'));
- /**
- * Define the backend routes for the application.
- *
- * Plugins have dynamic creation of web vs admin.
- *
- * "
- * @return void
- */
- protected function mapPluginRoutes()
- {
- /** @var Plugin $plugin */
- foreach (plugins()->enabled() as $plugin) {
- $plugin_name = ucfirst($plugin->name());
-
- $namespace = sprintf('App\Plugins\%s', $plugin_name);
-
- $frontendRoute = base_path(sprintf('app/Plugins/%s/Routes/frontend.php', $plugin_name));
- Route::middleware(['web'])->group($frontendRoute);
-
- $backendRoute = base_path(sprintf('app/Plugins/%s/Routes/backend.php', $plugin_name));
- Route::middleware(['web', 'auth', 'gateway'])->namespace($namespace)->group($backendRoute);
- }
- }
-
- /**
- * Define the backend routes for the application.0.
- *
- * Modules are loaded as modularity.
- *
- * @return void
- */
- protected function mapModulesRoutes()
- {
- foreach (config('modules') as $module) {
- $module_name = ucfirst($module['title']);
-
- $namespace = sprintf('App\Modules\%s', $module['title']);
-
- $backendRoute = base_path(sprintf('app/Modules/%s/Routes/backend.php', $module_name));
-
- $frontendRoute = base_path(sprintf('app/Modules/%s/Routes/frontend.php', $module_name));
-
- // Frontend are routes that can be accessed by visitors.
- Route::middleware(['web'])->group($frontendRoute);
-
- // Backend are routes that can only be accessed to those with access.
- Route::middleware(['web', 'auth', 'gateway'])->namespace($namespace)->group($backendRoute);
- }
- }
-
- /**
- * Third party routes sometimes require auth, and sometimes not, but since we dont
- * define a namespace, its best have it in its seperate folder for simplicity.
- */
- protected function mapVendorRoutes()
- {
Route::middleware('web')->group(base_path('routes/vendor.php'));
}
}
diff --git a/composer.json b/composer.json
index 18014b4c..bfa16a3d 100644
--- a/composer.json
+++ b/composer.json
@@ -9,6 +9,7 @@
"barryvdh/laravel-elfinder": "0.3.12",
"doctrine/dbal": "2.7.1",
"fideloper/proxy": "^4.0",
+ "larapack/config-writer": "1.*",
"laravel/framework": "5.6.*",
"laravel/scout": "^4.0",
"laravel/tinker": "^1.0",
diff --git a/composer.lock b/composer.lock
index 52ea9c07..e4d51ef5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "fd8abe0eec4a907e7ac2a50b67ec43da",
+ "content-hash": "7c022288640d73a9f4e3d3b06b707d22",
"packages": [
{
"name": "anahkiasen/underscore-php",
@@ -1108,6 +1108,41 @@
],
"time": "2015-04-20T18:58:01+00:00"
},
+ {
+ "name": "larapack/config-writer",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/larapack/config-writer.git",
+ "reference": "b36a716833240fe9e8b4b4d007b68ef9e91a1124"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/larapack/config-writer/zipball/b36a716833240fe9e8b4b4d007b68ef9e91a1124",
+ "reference": "b36a716833240fe9e8b4b4d007b68ef9e91a1124",
+ "shasum": ""
+ },
+ "type": "package",
+ "autoload": {
+ "psr-4": {
+ "": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Save changes to the configuration file in script.",
+ "keywords": [
+ "config",
+ "larapack",
+ "laravel",
+ "package",
+ "save",
+ "writer"
+ ],
+ "time": "2016-04-28T12:45:27+00:00"
+ },
{
"name": "laravel/framework",
"version": "v5.6.26",
diff --git a/config/app.php b/config/app.php
index 353fd7bd..c3b9acc1 100644
--- a/config/app.php
+++ b/config/app.php
@@ -176,14 +176,11 @@
/*
* Application Service Providers...
*/
+ App\Modules\ModuleServiceProvider::class,
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
- // App\Providers\BroadcastServiceProvider::class,
+ App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
-
- /*
- * Webshelf Service Providers...
- */
App\Providers\ConfigurationServiceProvider::class,
App\Providers\ComposerServiceProvider::class,
App\Providers\InstanceServiceProvider::class,
@@ -212,7 +209,7 @@
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
- 'Config' => Illuminate\Support\Facades\Config::class,
+ 'Config' => Larapack\ConfigWriter\Facade::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
diff --git a/config/modules.php b/config/modules.php
index b703c169..3b2ec063 100644
--- a/config/modules.php
+++ b/config/modules.php
@@ -2,47 +2,104 @@
return [
- /*
- |--------------------------------------------------------------------------
- | Core application menus that are used on the dashboard menu.
- |--------------------------------------------------------------------------
- |
- | From here you can enable or disable a menu and edit the configuration
- | this will allow the changes to be worked all throughout the dashboard.
- */
-
- [
+ 'products' => [
+ 'title' => 'Products',
+ 'enabled' => true,
+ 'icon' => 'fas fa-box',
+ 'version' => 1.0,
+ 'url' => 'admin/products',
+ 'role' => 'publisher',
+ ],
+
+ 'navigation' => [
+ 'title' => 'Navigation',
+ 'enabled' => true,
+ 'icon' => 'fas fa-compass',
+ 'version' => 1.0,
+ 'url' => 'admin/navigation',
+ 'role' => 'publisher',
+ ],
+
+ 'pages' => [
+ 'title' => 'Pages',
+ 'enabled' => true,
+ 'icon' => 'fab fa-readme',
+ 'version' => 1.0,
+ 'url' => 'admin/pages',
+ 'role' => 'publisher',
+ ],
+
+ 'redirects' => [
+ 'title' => 'Redirects',
+ 'enabled' => false,
+ 'icon' => 'fas fa-exchange-alt',
+ 'version' => 1.0,
+ 'url' => 'admin/redirects',
+ 'role' => 'publisher',
+ ],
+
+ 'articles' => [
+ 'title' => 'Articles',
+ 'enabled' => true,
+ 'icon' => 'fas fa-glasses',
+ 'version' => 1.0,
+ 'url' => 'admin/articles',
+ 'role' => 'publisher',
+ 'route' => 'articles',
+ ],
+
+ 'newsletters' => [
+ 'title' => 'Newsletters',
+ 'enabled' => false,
+ 'icon' => 'fa-book',
+ 'version' => 1.0,
+ 'url' => 'admin/newsletter',
+ 'role' => 'publisher',
+ ],
+
+ 'settings' => [
'title' => 'Settings',
+ 'enabled' => true,
'icon' => 'fas fa-wrench',
+ 'version' => 1.0,
'url' => 'admin/settings',
'role' => 'administrator',
],
- [
+ 'accounts' => [
'title' => 'Accounts',
+ 'enabled' => true,
'icon' => 'fa fa-users',
+ 'version' => 1.0,
'url' => 'admin/accounts',
'role' => 'administrator',
],
- [
+ 'filemanager' => [
'title' => 'Filemanager',
+ 'enabled' => true,
'icon' => 'fas fa-toolbox',
+ 'version' => 1.0,
'url' => 'admin/filemanager',
'role' => 'publisher',
],
- [
+ 'updates' => [
'title' => 'Updates',
+ 'enabled' => true,
'icon' => 'fas fa-code',
+ 'version' => 1.0,
'url' => 'admin/updates',
'role' => 'developer',
],
- [
+ 'sitemap' => [
'title' => 'Sitemap',
+ 'enabled' => true,
'icon' => 'fas fa-globe',
+ 'version' => 1.0,
'url' => 'admin/sitemap',
'role' => 'developer',
],
+
];
diff --git a/config/sentry.php b/config/sentry.php
index 63e8c378..779b9801 100644
--- a/config/sentry.php
+++ b/config/sentry.php
@@ -4,7 +4,7 @@
'dsn' => env('SENTRY_LARAVEL_DSN', 'https://b8aa8a46e793436885598609749d6876:803fa5f399be4309926bafb0b9bc9a2f@sentry.io/1221084'),
// capture release as git sha
- 'release' => trim(exec('git log --pretty="%h" -n1 HEAD')),
+ 'release' => '', //trim(exec('git log --pretty="%h" -n1 HEAD')),
// Capture bindings on SQL queries
'breadcrumbs.sql_bindings' => true,
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index 0ea1930b..a224241c 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -2,8 +2,8 @@
use Faker\Generator as Faker;
use App\Classes\Roles\Administrator;
-use App\Plugins\Pages\Model\PageTypes;
-use App\Plugins\Pages\Model\PageOptions;
+use App\Modules\Pages\Model\PageTypes;
+use App\Modules\Pages\Model\PageOptions;
/*
|--------------------------------------------------------------------------
@@ -38,7 +38,7 @@
return [
'seo_title' => $title,
'seo_keywords' => $faker->paragraph(1),
- 'seo_description' => $faker->paragraph(2),
+ 'seo_description' => $faker->paragraph(1),
'prefix' => $faker->word,
'slug' => str_slug($title),
'views' => $faker->numberBetween(75, 900),
diff --git a/database/migrations/2016_12_14_225300_create_plugins_table.php b/database/migrations/2016_12_14_225300_create_plugins_table.php
index 8185f37e..baf2095b 100644
--- a/database/migrations/2016_12_14_225300_create_plugins_table.php
+++ b/database/migrations/2016_12_14_225300_create_plugins_table.php
@@ -1,6 +1,5 @@
tinyInteger('is_backend')->nullable();
$table->timestamps();
});
-
- /*
- * DATA REQUIRED FOR APPLICATION CORE LOADING.
- */
- $plugin = new Plugin;
- $plugin->setName('products');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-book');
- $plugin->setEnabled(true);
- $plugin->setRequired(true);
- $plugin->setFrontEnd(false);
- $plugin->setBackEnd(true);
- $plugin->save();
-
- $plugin = new Plugin;
- $plugin->setName('menus');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-bars');
- $plugin->setEnabled(true);
- $plugin->setFrontEnd(false);
- $plugin->setBackEnd(true);
- $plugin->save();
-
- $plugin = new Plugin;
- $plugin->setName('pages');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-paperclip');
- $plugin->setEnabled(true);
- $plugin->setFrontEnd(true);
- $plugin->setBackEnd(true);
- $plugin->save();
-
- $plugin = new Plugin;
- $plugin->setName('news');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-newspaper-o');
- $plugin->setFrontEnd(true);
- $plugin->setBackEnd(true);
- $plugin->save();
-
- $plugin = new Plugin;
- $plugin->setName('redirects');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-magic');
- $plugin->setFrontEnd(true);
- $plugin->setBackEnd(true);
- $plugin->save();
-
- $plugin = new Plugin;
- $plugin->setName('facebook');
- $plugin->setVersion('2.8');
- $plugin->setIcon('fa-facebook-official');
- $plugin->setHide(true);
- $plugin->setFrontEnd(true);
- $plugin->setBackEnd(true);
- $plugin->save();
}
/**
diff --git a/database/migrations/2016_12_21_154441_edit_facebook_plugin_data.php b/database/migrations/2016_12_21_154441_edit_facebook_plugin_data.php
index dd63c9b9..7994751f 100644
--- a/database/migrations/2016_12_21_154441_edit_facebook_plugin_data.php
+++ b/database/migrations/2016_12_21_154441_edit_facebook_plugin_data.php
@@ -1,8 +1,6 @@
whereName('facebook');
-
- $plugin->setHide(false)->save();
+ //
}
/**
@@ -26,9 +21,6 @@ public function up()
*/
public function down()
{
- /** @var Plugin $plugin */
- $plugin = app(PluginRepository::class)->whereName('facebook');
-
- $plugin->setHide(true)->save();
+ //
}
}
diff --git a/database/migrations/2017_01_07_225206_create_carousels_table.php b/database/migrations/2017_01_07_225206_create_carousels_table.php
index ed64bc73..0d07522f 100644
--- a/database/migrations/2017_01_07_225206_create_carousels_table.php
+++ b/database/migrations/2017_01_07_225206_create_carousels_table.php
@@ -1,9 +1,7 @@
softDeletes();
$table->timestamps();
});
-
- /** @var Plugin $plugin */
- $plugin = new Plugin();
- $plugin->setName('carousels');
- $plugin->setVersion('1.0');
- $plugin->setIcon('fa-fast-forward');
- $plugin->setBackEnd(true);
- $plugin->save();
}
/**
@@ -58,7 +48,5 @@ public function down()
\Schema::drop('carousels');
\Schema::drop('carousel_slides');
-
- app(PluginRepository::class)->whereName('carousels')->delete();
}
}
diff --git a/database/migrations/2018_01_03_150616_cleanup_plugins.php b/database/migrations/2018_01_03_150616_cleanup_plugins.php
index 96dec62f..e7750b06 100644
--- a/database/migrations/2018_01_03_150616_cleanup_plugins.php
+++ b/database/migrations/2018_01_03_150616_cleanup_plugins.php
@@ -19,21 +19,6 @@ public function up()
Schema::drop('articles');
Schema::drop('plugin_feeds');
Schema::drop('plugin_options');
-
- $plugin = app(\App\Classes\Repositories\PluginRepository::class);
-
- $plugin->whereName('carousels')->delete();
- $plugin->whereName('news')->delete();
- $plugin->whereName('facebook')->delete();
-
- $item = $plugin->whereName('menus');
- $item->setVersion('2.6')->setRequired(false)->save();
- $item = $plugin->whereName('pages');
- $item->setVersion('2.1')->setRequired(false)->save();
- $item = $plugin->whereName('redirects');
- $item->setVersion('1.9')->setEnabled(true)->setRequired(false)->save();
- $item = $plugin->whereName('products');
- $item->setVersion('1.3')->save();
}
/**
diff --git a/database/migrations/2018_02_25_004151_february_update_one.php b/database/migrations/2018_02_25_004151_february_update_one.php
index dc3ea9bc..7d6c4ee7 100644
--- a/database/migrations/2018_02_25_004151_february_update_one.php
+++ b/database/migrations/2018_02_25_004151_february_update_one.php
@@ -1,8 +1,6 @@
setAttribute('name', 'articles');
- $plugin->setAttribute('version', '1.0');
- $plugin->setAttribute('icon', 'fa-book');
- $plugin->setAttribute('enabled', false);
- $plugin->setAttribute('is_frontend', true);
- $plugin->setAttribute('is_backend', true);
- $plugin->setAttribute('required', false);
- $plugin->save();
-
- /** @var \App\Classes\Repositories\PluginRepository $pluginRepository */
- $pluginRepository = app(\App\Classes\Repositories\PluginRepository::class);
-
- $pluginRepository->whereName('menus')->setAttribute('required', true)->save();
- $pluginRepository->whereName('pages')->setAttribute('required', true)->save();
-
Schema::table('plugins', function (Blueprint $table) {
$table->dropColumn('version');
$table->dropColumn('icon');
@@ -62,11 +43,6 @@ public function up()
$table->softDeletes();
$table->timestamps();
});
-
- /*
- * INDEX ALL NEW MATERIAL FOR SEARCHING.
- */
- // Artisan::call('scout:mysql-index');
}
/**
diff --git a/database/migrations/2018_03_01_232041_march_update_one.php b/database/migrations/2018_03_01_232041_march_update_one.php
index cf22105f..c151aae6 100644
--- a/database/migrations/2018_03_01_232041_march_update_one.php
+++ b/database/migrations/2018_03_01_232041_march_update_one.php
@@ -3,7 +3,7 @@
use App\Model\Page;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
-use App\Plugins\Newsletters\Model\Newsletter;
+use App\Modules\Newsletters\Model\Newsletter;
use Illuminate\Database\Migrations\Migration;
class MarchUpdateOne extends Migration
@@ -15,15 +15,6 @@ class MarchUpdateOne extends Migration
*/
public function up()
{
- $plugin = new \App\Model\Plugin();
-
- $plugin->setAttribute('name', 'newsletters');
- $plugin->setAttribute('enabled', false);
- $plugin->setAttribute('is_frontend', true);
- $plugin->setAttribute('is_backend', true);
- $plugin->setAttribute('required', false);
- $plugin->save();
-
Schema::create('newsletters', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
diff --git a/database/migrations/2018_06_03_001436_june_update_one.php b/database/migrations/2018_06_03_001436_june_update_one.php
index 94f416d5..d9877f42 100644
--- a/database/migrations/2018_06_03_001436_june_update_one.php
+++ b/database/migrations/2018_06_03_001436_june_update_one.php
@@ -1,9 +1,9 @@
string('module')->after('option')->nullable();
+ });
+
+ Page::firstOrCreate([
+ 'seo_title' => 'Articles',
+ 'identifier' => 'articles',
+ 'slug' => 'articles',
+ 'type' => PageTypes::TYPE_MODULE,
+ 'option' => PageOptions::OPTION_DISABLED,
+ ]);
+
+ foreach (Page::all() as $page) {
+ if ($page->type & PageTypes::TYPE_PLUGIN) {
+ $page->type = $page->type & ~PageTypes::TYPE_PLUGIN;
+ $page->type = $page->type | PageTypes::TYPE_MODULE;
+ }
+
+ if ($page->identifier == 'articles') {
+ $page->module = 'articles';
+ $page->type = PageTypes::TYPE_MODULE | PageTypes::TYPE_ROUTER;
+ }
+
+ if ($page->identifier == 'newsletter.success') {
+ $page->module = 'newsletters';
+ $page->option = $page->option | PageOptions::OPTION_DISABLED;
+ }
+
+ if ($page->identifier == 'error.404') {
+ $page->module = 'errors';
+ }
+
+ $page->save();
+ }
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('modules');
+ }
+}
diff --git a/resources/admin/views/structure/navbar.blade.php b/resources/admin/views/structure/navbar.blade.php
index e4d4e3fb..7db22470 100644
--- a/resources/admin/views/structure/navbar.blade.php
+++ b/resources/admin/views/structure/navbar.blade.php
@@ -19,7 +19,7 @@
diff --git a/resources/admin/views/structure/sidebar.blade.php b/resources/admin/views/structure/sidebar.blade.php
index d7d2d14f..15402467 100644
--- a/resources/admin/views/structure/sidebar.blade.php
+++ b/resources/admin/views/structure/sidebar.blade.php
@@ -22,23 +22,10 @@
- @foreach(plugins()->viewable() as $plugin)
-
-
-
-
-
-
- {{ ucfirst($plugin->name()) }}
-
-
-
-
- @endforeach
-
@foreach(config('modules') as $module)
- @role($module['role'])
+ @if($module['enabled'] && account()->hasRole($module['role']))
+
diff --git a/routes/web.php b/routes/web.php
index 200190f4..2c85d8c8 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -14,7 +14,7 @@
| contains the "web" middleware group. Now create something great!
|
*/
- Route::get('/')->uses('PageController@index')->name('index');
+ Route::get('/')->uses('App\Modules\Pages\FrontendController@index')->name('index');
/*
|--------------------------------------------------------------------------
@@ -26,7 +26,7 @@
| contains the "web" middleware group. Now create something great!
|
*/
- Route::get('/admin')->uses('DashboardController@index')->name('dashboard')->middleware(['web', 'auth', 'gateway']);
+ Route::get('/admin')->uses('App\Http\Controllers\DashboardController@index')->name('dashboard')->middleware(['web', 'auth', 'gateway']);
/*
|--------------------------------------------------------------------------
@@ -38,7 +38,7 @@
| contains the "web" middleware group. Now create something great!
|
*/
- Route::get('/admin/login')->uses('AuthController@form')->name('login');
+ Route::get('/admin/login')->uses('App\Http\Controllers\AuthController@form')->name('login');
/*
|--------------------------------------------------------------------------
@@ -50,7 +50,7 @@
| contains the "web" middleware group. Now create something great!
|
*/
- Route::post('/admin/login')->uses('AuthController@login')->name('AuthLogin');
+ Route::post('/admin/login')->uses('App\Http\Controllers\AuthController@login')->name('AuthLogin');
/*
|--------------------------------------------------------------------------
@@ -62,4 +62,4 @@
| contains the "web" middleware group. Now create something great!
|
*/
- Route::get('/admin/logout')->uses('AuthController@logout')->name('AuthLogout');
+ Route::get('/admin/logout')->uses('App\Http\Controllers\AuthController@logout')->name('AuthLogout');
diff --git a/tests/Article/ArticleInstallationTest.php b/tests/Article/ArticleInstallationTest.php
deleted file mode 100644
index 56224aee..00000000
--- a/tests/Article/ArticleInstallationTest.php
+++ /dev/null
@@ -1,87 +0,0 @@
-first();
-
- $this->assertEquals('articles', $plugin['name']);
- }
-
- /**
- * @test
- */
- public function the_article_plugin_can_be_toggled()
- {
- $plugin = Plugin::whereName('articles')->first();
-
- $plugin->toggle();
-
- $this->assertTrue($plugin->enabled);
- }
-
- /**
- * @test
- */
- public function the_article_plugin_has_a_controller_class()
- {
- $plugin = Plugin::whereName('articles')->first();
-
- $this->assertInstanceOf(ArticlesController::class, $plugin->controller);
- }
-
- /**
- * @test
- */
- public function the_article_plugin_exists_on_the_dashboard()
- {
- $this->signIn(['role_id' => Developer::$key]);
-
- $this->get('admin/products/index')
- ->assertSee('Articles');
- }
-
- /**
- * @test
- */
- public function the_article_plugin_can_be_installed()
- {
- $this->signIn(['role_id' => Developer::$key]);
-
- $this->get('/admin/products/install/articles')
- ->assertRedirect('/admin/products/index');
-
- $this->assertDatabaseHas('plugins', ['name' => 'articles', 'enabled' => true]);
- $this->assertDatabaseHas('pages', ['identifier' => 'articles']);
- }
-
- /**
- * @test
- */
- public function the_article_plugin_can_be_uninstalled()
- {
- $this->signIn(['role_id' => Developer::$key]);
-
- $this->get('/admin/products/install/articles');
-
- $this->get('/admin/products/uninstall/articles')
- ->assertRedirect('/admin/products/index');
-
- $this->assertDatabaseHas('plugins', ['name' => 'articles', 'enabled' => false]);
- $this->assertDatabaseMissing('pages', ['identifier' => 'articles']);
- }
-}
diff --git a/tests/Article/ArticleViewingTest.php b/tests/Article/ArticleViewingTest.php
index 8d26141b..13a08cfe 100644
--- a/tests/Article/ArticleViewingTest.php
+++ b/tests/Article/ArticleViewingTest.php
@@ -3,7 +3,7 @@
namespace Tests\Article;
use Tests\TestCase;
-use App\Model\Plugin;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
@@ -19,13 +19,6 @@ class ArticleViewingTest extends TestCase
*/
use RefreshDatabase;
- /**
- * The plugin model for articles.
- *
- * @var Article
- */
- private $plugin;
-
/**
* The Faker instance.
*
@@ -40,13 +33,9 @@ public function setUp()
{
parent::setUp();
- $this->plugin = Plugin::install('articles');
-
- Route::middleware('web', 'auth', 'gateway')->group(base_path(sprintf('app/Plugins/%s/Routes/backend.php', 'Articles')));
-
- Route::middleware('web')->group(base_path(sprintf('app/Plugins/%s/Routes/frontend.php', 'Articles')));
+ Route::middleware('web', 'auth', 'gateway')->group(base_path('app/Modules/Articles/Routes/backend.php'));
- // $this->app['router']->getRoutes()->refreshNameLookups();
+ Route::middleware('web')->namespace('App\Modules\Articles')->group(base_path('app/Modules/Articles/Routes/frontend.php'));
}
/**
diff --git a/tests/Module/ModuleManagerTest.php b/tests/Module/ModuleManagerTest.php
new file mode 100644
index 00000000..6a9ba981
--- /dev/null
+++ b/tests/Module/ModuleManagerTest.php
@@ -0,0 +1,238 @@
+expectException(ModuleNotFoundException::class);
+
+ // when
+ app(ModuleManager::class)->enable('unknown');
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_disable_a_module()
+ {
+ Config::set('modules.config', ['enabled' => true]);
+
+ $module = $this->mockModuleManager();
+
+ $module->disable('config');
+
+ $this->assertFalse($module->status('config'));
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_enable_a_module()
+ {
+ Config::set('modules.config', ['enabled' => false]);
+
+ $module = $this->mockModuleManager();
+
+ $module->enable('config');
+
+ $this->assertTrue($module->status('config'));
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_toggle_a_module()
+ {
+ Config::set('modules.config', ['enabled' => false]);
+
+ $module = $this->mockModuleManager();
+
+ $module->toggle('config');
+
+ $this->assertTrue($module->status('config'));
+
+ $module->toggle('config');
+
+ $this->assertFalse($module->status('config'));
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_enable_pages_attached_to_module()
+ {
+ /** @var Page $page */
+ $page = factory('App\Model\Page')->create(['module' => 'pictures', 'option' => PageOptions::OPTION_DISABLED]);
+
+ Config::set('modules.pictures', ['title' => 'Pictures', 'enabled' => false]);
+
+ $module = $this->mockModuleManager();
+
+ $module->enable('pictures');
+
+ $this->assertDatabaseHas('pages', ['id' => $page->id, 'option' => PageOptions::OPTION_DEFAULT]);
+
+ $this->assertTrue($module->status('pictures'));
+ }
+
+ /**
+ * @test
+ *
+ * @throws \App\Modules\ModuleNotFoundException
+ */
+ public function it_can_disable_pages_attached_to_module()
+ {
+ /** @var Page $page */
+ $page = factory('App\Model\Page')->create(['module' => 'pictures', 'option' => PageOptions::OPTION_PUBLIC]);
+
+ Config::set('modules.pictures', ['title' => 'Pictures', 'enabled' => true]);
+
+ $module = $this->mockModuleManager();
+
+ $module->disable('pictures');
+
+ $this->assertDatabaseHas('pages', ['id' => $page->id, 'option' => PageOptions::OPTION_PUBLIC | PageOptions::OPTION_DISABLED]);
+
+ $this->assertFalse($module->status('pictures'));
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_enable_multiple_pages_attached_to_module()
+ {
+ /** @var Page $page */
+ $pages = factory('App\Model\Page', 4)->create(['module' => 'unit-testing', 'option' => PageOptions::OPTION_DISABLED]);
+
+ Config::set('modules.unit-testing', ['title' => 'Unit Testing', 'enabled' => false]);
+
+ $module = $this->mockModuleManager();
+
+ $module->enable('unit-testing');
+
+ foreach ($pages as $page) {
+ $this->assertDatabaseHas('pages', ['id' => $page->id, 'option' => PageOptions::OPTION_DEFAULT]);
+ }
+
+ $this->assertTrue($module->status('unit-testing'));
+ }
+
+ /**
+ * @test
+ * @throws ModuleNotFoundException
+ */
+ public function it_can_disable_multiple_pages_attached_to_module()
+ {
+ /** @var Page $page */
+ $pages = factory('App\Model\Page', 4)->create(['module' => 'unit-testing', 'option' => PageOptions::OPTION_DEFAULT]);
+
+ Config::set('modules.unit-testing', ['title' => 'Unit Testing', 'enabled' => true]);
+
+ $module = $this->mockModuleManager();
+
+ $module->disable('unit-testing');
+
+ foreach ($pages as $page) {
+ $this->assertDatabaseHas('pages', ['id' => $page->id, 'option' => PageOptions::OPTION_DISABLED]);
+ }
+
+ $this->assertFalse($module->status('unit-testing'));
+ }
+
+ /**
+ * @test
+ */
+ public function it_can_return_all_modules_currently_enabled()
+ {
+ $this->mockConfiguration([
+ 'foo' => ['title' => 'foo', 'enabled' => true],
+ 'bar' => ['title' => 'bar', 'enabled' => true],
+ 'zor' => ['title' => 'zor', 'enabled' => false],
+ ]);
+
+ $modules = $this->mockModuleManager();
+
+ $this->assertCount(2, $modules->getActive());
+ }
+
+ /**
+ * @test
+ */
+ public function it_can_return_all_modules_currently_disabled()
+ {
+ $this->mockConfiguration([
+ 'san' => ['title' => 'foo', 'enabled' => false],
+ 'zap' => ['title' => 'bar', 'enabled' => true],
+ 'lae' => ['title' => 'zor', 'enabled' => false],
+ ]);
+
+ $modules = $this->mockModuleManager();
+
+ $this->assertCount(2, $modules->getInactive());
+ }
+
+ /**
+ * Mock the configuration file data.
+ *
+ * @param $array
+ */
+ private function mockConfiguration($array)
+ {
+ return config()->set('modules', $array);
+ }
+
+ /**
+ * Mock the module repository on its own.
+ *
+ * @return \PHPUnit\Framework\MockObject\MockBuilder
+ */
+ private function mockModuleRepository()
+ {
+ return $this->getMockBuilder(ModuleRepository::class)->enableOriginalConstructor();
+ }
+
+ /**
+ * Mock the module manager.
+ *
+ * @return ModuleManager
+ */
+ private function mockModuleManager()
+ {
+ // mock everything
+ $mockedClass = $this->mockModuleRepository()->setMethodsExcept(['set', 'get', 'all'])->getMock();
+
+ // save method will return
+ $mockedClass->method('save')->willReturn(true);
+
+ /* @var ModuleRepository $mockedClass */
+ return new ModuleManager($mockedClass);
+ }
+}
diff --git a/tests/Products/ProductDashboardTest.php b/tests/Products/ProductDashboardTest.php
new file mode 100644
index 00000000..2c11230d
--- /dev/null
+++ b/tests/Products/ProductDashboardTest.php
@@ -0,0 +1,31 @@
+signIn();
+
+ $response = $this->get('admin/products');
+
+ foreach (config('modules') as $module) {
+ $response->assertSee($module['title']);
+ }
+
+ $response->assertOk();
+ }
+}
diff --git a/tests/Products/ProductInstallationTest.php b/tests/Products/ProductInstallationTest.php
new file mode 100644
index 00000000..8548ac0d
--- /dev/null
+++ b/tests/Products/ProductInstallationTest.php
@@ -0,0 +1,31 @@
+shouldReceive('toggle')->andReturn(true)->getMock();
+
+ $this->app->instance(ModuleManager::class, $mocked);
+
+ $response = $this->get('/admin/products/test/toggle');
+
+ $response->assertRedirect('/admin/products')->assertSee('test');
+ }
+}