diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 9dea4bc..6ec021b 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -13,21 +13,6 @@ "permission": { "permission": 2, "type": null, "element": null }, "parent": 0, "children": [ - { - "id": 1000102001, - "pid": "/", - "type": 2, - "subtype": 1, - "name": "Settings", - "uri": "{/prefix}admin/settings/general?{?}", - "target": "self", - "icon": null, - "order": 1, - "from": "Admin", - "permission": { "permission": 2, "type": null, "element": null }, - "parent": 1000101001, - "children": [] - }, { "id": 1000103001, "pid": "/", @@ -83,7 +68,7 @@ "uri": "{/prefix}admin/account/list", "target": "self", "icon": null, - "order": 3, + "order": 4, "from": "Admin", "permission": { "permission": 2, "type": null, "element": null }, "parent": 1000101001, @@ -129,7 +114,7 @@ "uri": "{/prefix}admin/module/list", "target": "self", "icon": null, - "order": 4, + "order": 5, "from": "Admin", "permission": { "permission": 2, "type": null, "element": null }, "parent": 1000101001, @@ -143,7 +128,7 @@ "uri": "{/prefix}admin/module/info?{?}", "target": "self", "icon": null, - "order": 4, + "order": 1, "from": "Admin", "permission": { "permission": 2, "type": null, "element": null }, "parent": 1000105001, @@ -158,7 +143,7 @@ "uri": "{/prefix}admin/module/settings?{?}", "target": "self", "icon": null, - "order": 4, + "order": 5, "from": "Admin", "permission": { "permission": 2, "type": null, "element": null }, "parent": 1000105001, @@ -173,7 +158,7 @@ "uri": "{/prefix}admin/module/log?{?}", "target": "self", "icon": null, - "order": 4, + "order": 10, "from": "Admin", "permission": { "permission": 2, "type": null, "element": null }, "parent": 1000105001, diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 3719f15..0330b82 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -507,6 +507,33 @@ } } }, + "app": { + "name": "app", + "fields": { + "app_id": { + "name": "app_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "app_name": { + "name": "app_name", + "type": "VARCHAR(50)", + "null": false + }, + "app_theme": { + "name": "app_theme", + "type": "VARCHAR(255)", + "null": false + }, + "app_status": { + "name": "app_status", + "type": "TINYINT", + "null": false + } + } + }, "group": { "name": "group", "fields": { @@ -858,6 +885,19 @@ "type": "VARCHAR(255)", "null": true }, + "settings_pattern": { + "name": "settings_pattern", + "type": "TEXT", + "null": true + }, + "settings_app": { + "name": "settings_app", + "type": "INT", + "default": null, + "null": true, + "foreignTable": "app", + "foreignKey": "app_id" + }, "settings_module": { "name": "settings_module", "type": "VARCHAR(190)", diff --git a/Admin/Installer.php b/Admin/Installer.php index 424c97a..a78751f 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -156,4 +156,21 @@ final class Installer extends InstallerAbstract $query->execute(); } + + /** + * Install data from providing modules. + * + * @param ApplicationAbstract $app Application + * @param array $data Additional data + * + * @return array + * + * @throws PathException + * @throws \Exception + * + * @since 1.0.0 + */ + public static function installExternal(ApplicationAbstract $app, array $data) : array + { + } } diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index bcbafda..8c3835f 100755 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -1,4 +1,16 @@ - [ + '^.*/admin/module/settings\?id=Admin.*$' => [ [ - 'dest' => '\Modules\Admin\Controller\BackendController:viewSettingsGeneral', + 'dest' => '\Modules\Admin\Controller\BackendController:viewModuleSettings', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::MODULE_NAME, 'type' => PermissionType::READ, - 'state' => PermissionState::SETTINGS, + 'state' => \Modules\Admin\Models\PermissionState::MODULE, ], ], ], + '^.*/admin/account/list.*$' => [ [ 'dest' => '\Modules\Admin\Controller\BackendController:viewAccountList', @@ -114,17 +127,6 @@ return [ ], ], ], - '^.*/admin/module/settings\?.*$' => [ - [ - 'dest' => '\Modules\Admin\Controller\BackendController:viewModuleSettings', - 'verb' => RouteVerb::GET, - 'permission' => [ - 'module' => BackendController::MODULE_NAME, - 'type' => PermissionType::READ, - 'state' => PermissionState::MODULE, - ], - ], - ], '^.*/admin/module/log\?.*$' => [ [ 'dest' => '\Modules\Admin\Controller\BackendController:viewModuleLog', diff --git a/Admin/Settings/Theme/Backend/settings.tpl.php b/Admin/Settings/Theme/Backend/settings.tpl.php new file mode 100644 index 0000000..259f44a --- /dev/null +++ b/Admin/Settings/Theme/Backend/settings.tpl.php @@ -0,0 +1,783 @@ +getData('generalSettings') ?? []; +$settings = $this->getData('settings') ?? []; + +$countryCodes = \phpOMS\Localization\ISO3166TwoEnum::getConstants(); +$countries = \phpOMS\Localization\ISO3166NameEnum::getConstants(); +$timezones = \phpOMS\Localization\TimeZoneEnumArray::getConstants(); +$timeformats = \phpOMS\Localization\ISO8601EnumArray::getConstants(); +$languages = \phpOMS\Localization\ISO639Enum::getConstants(); +$currencies = \phpOMS\Localization\ISO4217Enum::getConstants(); +$l11nDefinitions = \phpOMS\System\File\Local\Directory::list(__DIR__ . '/../../../../phpOMS/Localization/Defaults/Definitions'); + +$weights = \phpOMS\Utils\Converter\WeightType::getConstants(); +$speeds = \phpOMS\Utils\Converter\SpeedType::getConstants(); +$areas = \phpOMS\Utils\Converter\AreaType::getConstants(); +$lengths = \phpOMS\Utils\Converter\LengthType::getConstants(); +$volumes = \phpOMS\Utils\Converter\VolumeType::getConstants(); +$temperatures = \phpOMS\Utils\Converter\TemperatureType::getConstants(); + +$l11n = $this->getData('defaultlocalization') ?? new NullLocalization(); + +echo $this->getData('nav')->render(); +?> + +
+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+
+
+
getHtml('Settings'); ?>
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
getHtml('Security'); ?>
+
+
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ +
+
+
+
+ +
+
+
+
getHtml('Logging'); ?>
+
+
+ +
+ +
+ + +
+
+
+ +
+
+
+
+
+
+ request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+
+
+
+
getHtml('Localization'); ?>
+
+
+ +
+
+
+
+
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ +
+
+
+
+ +
+
+
getHtml('Time'); ?>
+
+
+ + +
+ +
+ + +
+ +

getHtml('Timeformat'); ?>

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Numeric'); ?>
+
+
+ + +
+ +
+ + +
+ +

getHtml('Numberformat'); ?>

+ +
+
+ + +
+ +
+ + +
+
+
+
+
+ +
+
+
getHtml('Precision'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Weight'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Speed'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Length'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Area'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ +
+
+
getHtml('Volume'); ?>
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+
+
+ request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
+
+
+
getHtml('Images'); ?>
+
+
+ +
+ <?= $this->getHtml('LoginImage'); ?> + +
+
+
+
+
+
+
+ request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+
+
+
getHtml('Settings'); ?>
+
+ + + + + getId() . '&ptype=p'; + $nextSettings = empty($settings) ? '{/prefix}admin/settings/general' : '{/prefix}admin/settings/general?{?}&sid=' . \end($settings)->getId() . '&ptype=n'; + + foreach ($settings as $key => $setting) : ++$count; + ?> + +
+ getHtml('ID', '0', '0'); ?> + + + + getHtml('Name'); ?> + + + + getHtml('Value'); ?> + getHtml('Module'); ?> + + + + getHtml('Group'); ?> + + + + getHtml('Account'); ?> + + + +
+ getId(); ?> + printHtml($setting->name); ?> + printHtml($setting->content); ?> + printHtml($setting->module); ?> + printHtml($setting->group); ?> + printHtml($setting->account); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+ +
+
+
+
+
+ + +asdf + +// login status (normal, read_only, disabled) +// default email settings for server (e.g. for forgot password) +// some default pages (e.g. legal pages) +// other settings defined during the installation (e.g. default unit ...) +// maybe combine page Admin/Settings and the module settings into one page. Maybe make them reference each other or maybe completely remove the Admin/Settings page because it is available in the module settings! \ No newline at end of file diff --git a/Controller/ApiController.php b/Controller/ApiController.php index d9fb241..333509e 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -16,10 +16,13 @@ declare(strict_types=1); namespace Modules\Admin\Controller; +use Model\App; +use Model\AppMapper; use Modules\Admin\Models\Account; use Modules\Admin\Models\AccountMapper; use Modules\Admin\Models\AccountPermission; use Modules\Admin\Models\AccountPermissionMapper; +use Modules\Admin\Models\ModuleMapper; use Modules\Admin\Models\Group; use Modules\Admin\Models\GroupMapper; use Modules\Admin\Models\GroupPermission; @@ -62,6 +65,7 @@ use phpOMS\Uri\UriFactory; use phpOMS\Utils\Parser\Markdown\Markdown; use phpOMS\Validation\Network\Email as EmailValidator; use phpOMS\Version\Version; +use phpOMS\Utils\StringUtils; /** * Admin controller class. @@ -153,11 +157,9 @@ final class ApiController extends Controller $account = AccountMapper::getBy((string) $request->getData('login'), 'login'); $forgotten = $this->app->appSettings->get( - null, - ['forgott_date', 'forgrott_count'], - self::MODULE_NAME, - null, - $account->getId() + names: ['forgott_date', 'forgrott_count'], + module: self::MODULE_NAME, + account: $account->getId() ); if ((int) $forgotten['forgrotten_count'] > 3) { @@ -235,6 +237,7 @@ final class ApiController extends Controller [ 'response' => $this->app->appSettings->get( $id !== null ? (int) $id : $id, + $request->getData('app') ?? null, $request->getData('name') ?? '', $request->getData('module') ?? null, $group !== null ? (int) $group : $group, @@ -265,20 +268,22 @@ final class ApiController extends Controller $id = isset($data['id']) ? (int) $data['id'] : null; $name = $data['name'] ?? null; $content = $data['content'] ?? null; + $app = $data['app'] ?? null; $module = $data['module'] ?? null; $group = isset($data['group']) ? (int) $data['group'] : null; $account = isset($data['account']) ? (int) $data['account'] : null; $this->updateModel( $request->header->account, - $this->app->appSettings->get($id, $name, $module, $group, $account), + $this->app->appSettings->get($id, $name, $app, $module, $group, $account), $data, - function () use ($id, $name, $content, $module, $group, $account) : void { + function () use ($id, $name, $content, $app, $module, $group, $account) : void { $this->app->appSettings->set([ [ 'id' => $id, 'name' => $name, 'content' => $content, + 'app' => $app, 'module' => $module, 'group' => $group, 'account' => $account, @@ -477,7 +482,7 @@ final class ApiController extends Controller */ public function apiInstallApplication(RequestAbstract $request, ResponseAbstract $response, $data = null) : void { - $appManager = new ApplicationManager($this->app->moduleManager); + $appManager = new ApplicationManager(); $app = $request->getData('appSrc'); if (!\is_dir(__DIR__ . '/../../../' . $app)) { @@ -485,12 +490,42 @@ final class ApiController extends Controller return; } - $appManager->install( + $info = new ApplicationInfo(__DIR__ . '/../../../' . $app); + $info->load(); + + // handle dependencies + $dependencies = $info->getDependencies(); + $installed = $this->app->moduleManager->getInstalledModules(); + + foreach ($dependencies as $key => $version) { + if (!isset($installed[$key])) { + $this->app->moduleManager->install($key); + } + } + + // handle app installation + $result = $appManager->install( __DIR__ . '/../../../' . $app, __DIR__ . '/../../../' . $request->getData('appDest') ?? '', $request->getData('theme') ?? 'Default' ); + // handle providing + if ($result) { + $providing = $info->getProviding(); + + foreach ($providing as $key => $version) { + if (isset($installed[$key])) { + $this->app->moduleManager->installProviding($app, $key); + } + } + } + + $app = new App(); + $app->name = $request->getData('appName') ?? ''; + $app->theme = $request->getData('theme') ?? ''; + AppMapper::create($app); + $this->apiActivateTheme($request, $response); } @@ -667,6 +702,13 @@ final class ApiController extends Controller */ public function apiGroupDelete(RequestAbstract $request, ResponseAbstract $response, $data = null) : void { + if (((int) $request->getId('id')) === 3) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Group', 'Admin group cannot be deleted', []); + + return; + } + $group = GroupMapper::get((int) $request->getData('id')); $this->deleteModel($request->header->account, $group, GroupMapper::class, 'group', $request->getOrigin()); $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Group', 'Group successfully deleted', $group); @@ -1035,7 +1077,15 @@ final class ApiController extends Controller return; } - $this->app->eventManager->trigger('PRE:Module:Admin-module-status', '', ['status' => $status, 'module' => $module]); + $old = ModuleMapper::get($module); + + $this->app->eventManager->triggerSimilar( + 'PRE:Module:Admin-module-status-update', '', + [ + $request->header->account, + ['status' => $status, 'module' => $module] + ] + ); switch ($status) { case ModuleStatusUpdateType::ACTIVATE: $done = $module === 'Admin' ? false : $this->app->moduleManager->activate($module); @@ -1062,7 +1112,20 @@ final class ApiController extends Controller $msg = 'Unknown module status change request.'; $response->header->status = RequestStatusCode::R_400; } - $this->app->eventManager->trigger('POST:Module:Admin-module-status', '', ['status' => $status, 'module' => $module]); + ModuleMapper::clearCache(); + $new = ModuleMapper::get($module); + + $this->app->eventManager->triggerSimilar( + 'POST:Module:Admin-module-status-update', '', + [ + $request->header->account, + $old, $new, + StringUtils::intHash(ModuleMapper::class), 'module-status', + $module, + self::MODULE_NAME, + $request->getOrigin() + ] + ); if (!$done) { $response->header->status = RequestStatusCode::R_400; @@ -1132,6 +1195,14 @@ final class ApiController extends Controller { /** @var GroupPermission $permission */ $permission = GroupPermissionMapper::get((int) $request->getData('id')); + + if ($permission->getGroup() === 3) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Group', 'Admin group permissions cannot be deleted', []); + + return; + } + $this->deleteModel($request->header->account, $permission, GroupPermissionMapper::class, 'group-permission', $request->getOrigin()); $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Permission', 'Permission successfully deleted', $permission); } @@ -1157,27 +1228,6 @@ final class ApiController extends Controller $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Permission', 'Permission successfully deleted', $permission); } - /** - * Api method to delete a user permission - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiUserPermissionDelete(RequestAbstract $request, ResponseAbstract $response, $data = null) : void - { - /** @var AccountPermission $permission */ - $permission = AccountPermissionMapper::get((int) $request->getData('id')); - $this->deleteModel($request->header->account, $permission, AccountPermissionMapper::class, 'user-permission', $request->getOrigin()); - $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Permission', 'Permission successfully deleted', $permission); - } - /** * Api method to add a permission to a group * @@ -1193,6 +1243,13 @@ final class ApiController extends Controller */ public function apiAddGroupPermission(RequestAbstract $request, ResponseAbstract $response, $data = null) : void { + if (((int) $request->getId('permissionref')) === 3) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Group', 'Admin group permissions cannot get modified', []); + + return; + } + if (!empty($val = $this->validatePermissionCreate($request))) { $response->set('permission_create', new FormValidation($val)); $response->header->status = RequestStatusCode::R_400; @@ -1360,6 +1417,13 @@ final class ApiController extends Controller /** @var GroupPermission $old */ $old = clone GroupPermissionMapper::get((int) $request->getData('id')); + if ($old->getGroup() === 3) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Group', 'Admin group permissions cannot get modified', []); + + return; + } + /** @var GroupPermission $new */ $new = $this->updatePermissionFromRequest(GroupPermissionMapper::get((int) $request->getData('id')), $request); @@ -1438,6 +1502,64 @@ final class ApiController extends Controller $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Group', 'Relation added', []); } + /** + * Api method to add a group to an account + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDeleteGroupFromAccount(RequestAbstract $request, ResponseAbstract $response, $data = null) : void + { + $account = (int) $request->getData('account'); + $groups = \array_map('intval', $request->getDataList('igroup-idlist')); + + if (\in_array(3, $groups) && $account === $request->header->account) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Account', 'Admin group cannot be removed from yourself', []); + + return; + } + + $this->deleteModelRelation($request->header->account, $account, $groups, AccountMapper::class, 'groups', 'account-group', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Account', 'Relation deleted', []); + } + + /** + * Api method to add an account to a group + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiDeleteAccountFromGroup(RequestAbstract $request, ResponseAbstract $response, $data = null) : void + { + $group = (int) $request->getData('group'); + $accounts = \array_map('intval', $request->getDataList('iaccount-idlist')); + + if (\in_array($request->header->account, $accounts) && $group === 3) { + // admin group cannot be deleted + $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Group', 'Admin group cannot be removed from yourself', []); + + return; + } + + $this->deleteModelRelation($request->header->account, $group, $accounts, GroupMapper::class, 'accounts', 'group-account', $request->getOrigin()); + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Group', 'Relation deleted', []); + } + /** * Api re-init routes * diff --git a/Controller/BackendController.php b/Controller/BackendController.php index ba500f8..ae13370 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -32,6 +32,7 @@ use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Utils\StringUtils; use phpOMS\Views\View; +use phpOMS\Utils\Parser\Markdown\Markdown; /** * Admin controller class. @@ -62,37 +63,6 @@ final class BackendController extends Controller return new View(); } - /** - * Method which generates the general settings view. - * - * In this view general settings for the entire application can be seen and adjusted. Settings which can be modified - * here are localization, password, database, etc. - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return RenderableInterface Response can be rendered - * - * @since 1.0.0 - */ - public function viewSettingsGeneral(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface - { - $view = new View($this->app->l11nManager, $request, $response); - $generalSettings = $this->app->appSettings->get(null, [ - SettingsEnum::PASSWORD_PATTERN, SettingsEnum::LOGIN_TIMEOUT, SettingsEnum::PASSWORD_INTERVAL, SettingsEnum::PASSWORD_HISTORY, SettingsEnum::LOGIN_TRIES, SettingsEnum::LOGGING_STATUS, SettingsEnum::LOGGING_PATH, SettingsEnum::DEFAULT_ORGANIZATION, - SettingsEnum::LOGIN_STATUS, SettingsEnum::DEFAULT_LOCALIZATION, SettingsEnum::ADMIN_MAIL, - ]); - - $view->setTemplate('/Modules/Admin/Theme/Backend/settings-general'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000104001, $request, $response)); - $view->setData('generalSettings', $generalSettings); - $view->setData('defaultlocalization', LocalizationMapper::get((int) $generalSettings[SettingsEnum::DEFAULT_LOCALIZATION])); - $view->setData('settings', SettingMapper::getAll()); - - return $view; - } - /** * Method which generates the general settings view. * @@ -373,36 +343,30 @@ final class BackendController extends Controller $view->setData('installed', $installed = $this->app->moduleManager->getInstalledModules()); $view->setData('id', $id); - $groupPermission = GroupMapper::getPermissionForModule($id); - $view->setData('groupPermissions', $groupPermission); + $type = 'Help'; + $page = 'introduction'; + $basePath = __DIR__ . '/../../' . $request->getData('id') . '/Docs/' . $type . '/' . $request->getLanguage(); + $path = \realpath($basePath . '/' . $page . '.md'); - return $view; - } - - /** - * Method which generates the module profile view. - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data - * - * @return RenderableInterface Response can be rendered - * - * @since 1.0.0 - */ - public function viewModuleSettings(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface - { - $view = new View($this->app->l11nManager, $request, $response); - $view->setTemplate('/Modules/Admin/Theme/Backend/modules-settings'); - $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000105001, $request, $response)); - - $id = $request->getData('id') ?? ''; - - $settings = SettingMapper::getFor($id, 'module'); - if (!($settings instanceof NullSetting)) { - $view->setData('settings', !\is_array($settings) ? [$settings] : $settings); + if ($path === false) { + $basePath = __DIR__ . '/../../' . $request->getData('id') . '/Docs/' . $type . '/' . $this->app->l11nServer->getLanguage(); + $path = \realpath($basePath . '/' . $page . '.md'); } + if ($path === false) { + $basePath = __DIR__ . '/../../' . $request->getData('id') . '/Docs/' . $type . '/en'; + $path = \realpath($basePath . '/' . $page . '.md'); + } + + if ($path === false) { + $path = \realpath($basePath . '/introduction.md'); + } + + $toParse = $path === false ? '' : \file_get_contents($path); + $content = Markdown::parse($toParse === false ? '' : $toParse); + + $view->setData('introduction', $content); + return $view; } @@ -423,17 +387,58 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Admin/Theme/Backend/modules-log'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000105001, $request, $response)); - $id = $request->getData('id') ?? ''; + $id = (string) ($request->getData('id') ?? ''); // audit log if ($request->getData('ptype') === 'p') { - $view->setData('auditlogs', AuditMapper::with('module', (string) $request->getData('id'), [Audit::class])::getBeforePivot((int) $request->getData('audit'), null, 25)); + $view->setData('auditlogs', AuditMapper::with('module', $id, [Audit::class])::getBeforePivot((int) $request->getData('audit'), null, 25)); } elseif ($request->getData('ptype') === 'n') { - $view->setData('auditlogs', AuditMapper::with('module', (string) $request->getData('id'), [Audit::class])::getAfterPivot((int) $request->getData('audit'), null, 25)); + $view->setData('auditlogs', AuditMapper::with('module', $id, [Audit::class])::getAfterPivot((int) $request->getData('audit'), null, 25)); } else { - $view->setData('auditlogs', AuditMapper::with('module', (string) $request->getData('id'), [Audit::class])::getAfterPivot(0, null, 25)); + $view->setData('auditlogs', AuditMapper::with('module', $id, [Audit::class])::getAfterPivot(0, null, 25)); } return $view; } + + /** + * Method which generates the module profile view. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface Response can be rendered + * + * @since 1.0.0 + */ + public function viewModuleSettings(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1000105001, $request, $response)); + + $id = $request->getData('id') ?? ''; + + $settings = SettingMapper::getFor($id, 'module'); + if (!($settings instanceof NullSetting)) { + $view->setData('settings', !\is_array($settings) ? [$settings] : $settings); + } + + if (\is_file(__DIR__ . '/../Admin/Settings/Theme/Backend/settings.tpl.php')) { + $view->setTemplate('/Modules/' . static::MODULE_NAME . '/Admin/Settings/Theme/Backend/settings'); + } else { + $view->setTemplate('/Modules/Admin/Theme/Backend/modules-settings'); + } + + $generalSettings = $this->app->appSettings->get(null, [ + SettingsEnum::PASSWORD_PATTERN, SettingsEnum::LOGIN_TIMEOUT, SettingsEnum::PASSWORD_INTERVAL, SettingsEnum::PASSWORD_HISTORY, SettingsEnum::LOGIN_TRIES, SettingsEnum::LOGGING_STATUS, SettingsEnum::LOGGING_PATH, SettingsEnum::DEFAULT_ORGANIZATION, + SettingsEnum::LOGIN_STATUS, SettingsEnum::DEFAULT_LOCALIZATION, SettingsEnum::ADMIN_MAIL, + ]); + + $view->setData('generalSettings', $generalSettings); + $view->setData('defaultlocalization', LocalizationMapper::get((int) $generalSettings[SettingsEnum::DEFAULT_LOCALIZATION])); + $view->setData('settings', SettingMapper::getAll()); + + return $view; + } } diff --git a/Models/Module.php b/Models/Module.php index db09a3d..2a4689b 100755 --- a/Models/Module.php +++ b/Models/Module.php @@ -30,10 +30,10 @@ class Module /** * Module id. * - * @var int + * @var string * @since 1.0.0 */ - protected int $id = 0; + protected string $id = ''; /** * Module name. @@ -80,11 +80,11 @@ class Module /** * Get module id. * - * @return int + * @return string * * @since 1.0.0 */ - public function getId() : int + public function getId() : string { return $this->id; } @@ -147,6 +147,7 @@ class Module return [ 'id' => $this->id, 'name' => $this->name, + 'status' => $this->status, 'description' => $this->description, 'createdAt' => $this->createdAt, ]; diff --git a/Models/NullModule.php b/Models/NullModule.php new file mode 100644 index 0000000..77bbb61 --- /dev/null +++ b/Models/NullModule.php @@ -0,0 +1,39 @@ +id = $id; + } +} diff --git a/Models/PermissionState.php b/Models/PermissionState.php index 0fb6ac4..068b61d 100755 --- a/Models/PermissionState.php +++ b/Models/PermissionState.php @@ -43,4 +43,6 @@ abstract class PermissionState extends Enum public const ACCOUNT_SETTINGS = 8; public const SEARCH = 9; + + public const API = 9; } diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 5b453dd..ef0d505 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -26,6 +26,10 @@ return [ 'Log' => 'Log', 'Info' => 'Info', 'Account' => 'Account', + 'Pages' => 'Pages', + 'Permissions' => 'Permissions', + 'Navigation' => 'Navigation', + 'Routes' => 'Routes', 'Accounts' => 'Accounts', ], ]; diff --git a/Theme/Backend/accounts-single.tpl.php b/Theme/Backend/accounts-single.tpl.php index eec08ce..7fcfc2f 100755 --- a/Theme/Backend/accounts-single.tpl.php +++ b/Theme/Backend/accounts-single.tpl.php @@ -53,8 +53,10 @@ echo $this->getData('nav')->render(); ?>
@@ -150,8 +152,31 @@ echo $this->getData('nav')->render(); ?>
+ + + request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+
+
+
getHtml('Groups'); ?>
+
+
+ + getData('grpSelector')->render('iGroup', true); ?> +
+
+
+ + +
+
+
+
+ +
getHtml('Groups'); ?>
@@ -177,70 +202,14 @@ echo $this->getData('nav')->render(); ?>
- -
-
-
getHtml('Groups'); ?>
-
-
- - getData('grpSelector')->render('iGroup', true); ?> -
-
-
- - -
-
-
+
+
+ request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
-
-
getHtml('Permissions'); ?>
-
- - - - - $value) : ++$c; - $permission = $value->getPermission(); - ?> - -
- - getHtml('ID', '0', '0'); ?> - getHtml('Unit'); ?> - getHtml('App'); ?> - getHtml('Module'); ?> - getHtml('Type'); ?> - getHtml('Ele'); ?> - getHtml('Comp'); ?> - getHtml('Perm'); ?> -
- - getId(); ?> - getUnit(); ?> - getApp(); ?> - getModule(); ?> - getType(); ?> - getElement(); ?> - getComponent(); ?> - - - - - - - - -
getHtml('Empty', '0', '0'); ?> - -
-
-
-
getHtml('Permissions'); ?>
@@ -320,6 +289,53 @@ echo $this->getData('nav')->render(); ?>
+ +
+
+
getHtml('Permissions'); ?>
+
+ + + + + $value) : ++$c; + $permission = $value->getPermission(); + ?> + +
+ + getHtml('ID', '0', '0'); ?> + getHtml('Unit'); ?> + getHtml('App'); ?> + getHtml('Module'); ?> + getHtml('Type'); ?> + getHtml('Ele'); ?> + getHtml('Comp'); ?> + getHtml('Perm'); ?> +
+ + getId(); ?> + getUnit(); ?> + getApp(); ?> + getModule(); ?> + getType(); ?> + getElement(); ?> + getComponent(); ?> + + + + + + + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
@@ -339,7 +355,7 @@ echo $this->getData('nav')->render(); ?> $volumes = VolumeType::getConstants(); $temperatures = TemperatureType::getConstants(); ?> - request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> + request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>>
@@ -790,7 +806,7 @@ echo $this->getData('nav')->render(); ?>
- request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> + request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>>
diff --git a/Theme/Backend/groups-single.tpl.php b/Theme/Backend/groups-single.tpl.php index fd494a2..6bb16f9 100755 --- a/Theme/Backend/groups-single.tpl.php +++ b/Theme/Backend/groups-single.tpl.php @@ -39,7 +39,9 @@ echo $this->getData('nav')->render(); ?>
@@ -82,8 +84,32 @@ echo $this->getData('nav')->render(); ?>
+
+
+ request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+
+
+
getHtml('Accounts'); ?>
+
+
+ + getData('accGrpSelector')->render('iAccount', 'group', true); ?> +
+
+
+ +
+
+
+
+
+ +
+
getHtml('Accounts'); ?>
@@ -103,88 +129,15 @@ echo $this->getData('nav')->render(); ?>
- -
-
-
getHtml('Accounts'); ?>
-
-
- - getData('accGrpSelector')->render('iAccount', 'group', true); ?> -
-
-
- -
-
-
+
+
+ request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
-
-
getHtml('Permissions'); ?>
-
- - - - - - $value) : ++$c; $permission = $value->getPermission(); ?> - -
- - getHtml('ID', '0', '0'); ?> - getHtml('Unit'); ?> - getHtml('App'); ?> - getHtml('Module'); ?> - getHtml('Type'); ?> - getHtml('Ele'); ?> - getHtml('Comp'); ?> - getHtml('Perm'); ?> -
- - getId(); ?> - getUnit(); ?> - getApp(); ?> - getModule(); ?> - getType(); ?> - getElement(); ?> - getComponent(); ?> - - - - - - - - -
getHtml('Empty', '0', '0'); ?> - -
-
-
- - -
+
getHtml('Permissions'); ?>
@@ -263,10 +216,74 @@ echo $this->getData('nav')->render(); ?>
+ +
+
+
getHtml('Permissions'); ?>
+
+ + + + + + $value) : ++$c; $permission = $value->getPermission(); ?> + +
+ + getHtml('ID', '0', '0'); ?> + getHtml('Unit'); ?> + getHtml('App'); ?> + getHtml('Module'); ?> + getHtml('Type'); ?> + getHtml('Ele'); ?> + getHtml('Comp'); ?> + getHtml('Perm'); ?> +
+ + getId(); ?> + getUnit(); ?> + getApp(); ?> + getModule(); ?> + getType(); ?> + getElement(); ?> + getComponent(); ?> + + + + + + + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
- request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> + request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>>
diff --git a/Theme/Backend/modules-info.tpl.php b/Theme/Backend/modules-info.tpl.php index 237956c..b116ecb 100644 --- a/Theme/Backend/modules-info.tpl.php +++ b/Theme/Backend/modules-info.tpl.php @@ -23,7 +23,9 @@ $active = $this->getData('active'); $installed = $this->getData('installed'); $id = $this->getData('id'); -echo $this->getData('nav')->render(); +if (isset($installed[$id])) { + echo $this->getData('nav')->render(); +} ?>
@@ -87,38 +89,13 @@ echo $this->getData('nav')->render();
-
+ getData('introduction'))) : ?> +
-
getHtml('Settings'); ?>
-
- +
getData('introduction'); ?>
- -
-
- - - - - - getData('groupPermissions'); - foreach ($groupPermissions as $key => $value) : ++$c; - $url = UriFactory::build('{/prefix}admin/group/settings?{?}&id=' . $value->getId()); ?> - -
getHtml('Permissions'); ?>
getHtml('ID', '0', '0'); ?> - Type - getHtml('Name'); ?> -
- Group - name; ?> - - -
getHtml('Empty', '0', '0'); ?> - -
-
-
+
diff --git a/Theme/Backend/modules-list.tpl.php b/Theme/Backend/modules-list.tpl.php index 9abdf7a..a0b0d6b 100755 --- a/Theme/Backend/modules-list.tpl.php +++ b/Theme/Backend/modules-list.tpl.php @@ -72,7 +72,7 @@ $isntalled = $this->getData('isntalled') ?? []; $module) : ++$count; - $url = UriFactory::build('{/prefix}admin/module/settings?{?}&id=' . $module->getInternalName()); + $url = UriFactory::build('{/prefix}admin/module/info?{?}&id=' . $module->getInternalName()); if (isset($active[$module->getInternalName()])) { $status = ModuleStatus::ACTIVE; diff --git a/Theme/Backend/modules-settings.tpl.php b/Theme/Backend/modules-settings.tpl.php index 86a5b2d..4908152 100755 --- a/Theme/Backend/modules-settings.tpl.php +++ b/Theme/Backend/modules-settings.tpl.php @@ -18,96 +18,88 @@ declare(strict_types=1); $settings = $this->getData('settings') ?? []; echo $this->getData('nav')->render(); -?> -
-
- -
-
- request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> -
-
-
-
-
getHtml('Settings'); ?>
-
- - - - - $setting) : ++$count; - ?> - -
- getHtml('ID', '0', '0'); ?> - - - - getHtml('Name'); ?> - - - - getHtml('Value'); ?> - getHtml('Group'); ?> - - - - getHtml('Account'); ?> - - - -
- getId(); ?> - printHtml($setting->name); ?> - printHtml($setting->content); ?> - printHtml($setting->group); ?> - printHtml($setting->account); ?> - - -
getHtml('Empty', '0', '0'); ?> - -
-
-
-
+ +if ($this->hasData('settingsTpl') + && \is_file($this->getData('settingsTpl')) +) : + include $this->getData('settingsTpl'); +else : ?> +
+
+
+
getHtml('Settings'); ?>
+
+ + + + + $setting) : ++$count; + ?> + +
+ getHtml('ID', '0', '0'); ?> + + + + getHtml('Name'); ?> + + + + getHtml('Value'); ?> + getHtml('Group'); ?> + + + + getHtml('Account'); ?> + + + +
+ getId(); ?> + printHtml($setting->name); ?> + printHtml($setting->content); ?> + printHtml($setting->group); ?> + printHtml($setting->account); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
-
+ diff --git a/Theme/Backend/page-list.tpl.php b/Theme/Backend/page-list.tpl.php new file mode 100644 index 0000000..b88c454 --- /dev/null +++ b/Theme/Backend/page-list.tpl.php @@ -0,0 +1,118 @@ +getData('pages') ?? []; + +$previous = empty($pages) ? '{/prefix}admin/page/list' : '{/prefix}admin/page/list?{?}&id=' . \reset($pages)->getId() . '&ptype=p'; +$next = empty($pages) ? '{/prefix}admin/page/list' : '{/prefix}admin/page/list?{?}&id=' . \end($pages)->getId() . '&ptype=n'; + +echo $this->getData('nav')->render(); ?> + +
+
+
+
+ getHtml('PAges'); ?> +
+
+ + + + + $value) : ++$c; + $url = UriFactory::build('{/prefix}admin/account/settings?{?}&id=' . $value->getId()); + $color = 'darkred'; + if ($value->getStatus() === AccountStatus::ACTIVE) { $color = 'green'; } + elseif ($value->getStatus() === AccountStatus::INACTIVE) { $color = 'darkblue'; } + elseif ($value->getStatus() === AccountStatus::TIMEOUT) { $color = 'purple'; } + elseif ($value->getStatus() === AccountStatus::BANNED) { $color = 'red'; } ?> + +
getHtml('ID', '0', '0'); ?> + + + getHtml('Status'); ?> + + + getHtml('Name'); ?> + + + + getHtml('Activity'); ?> + + + + getHtml('Created'); ?> + + + +
getId(); ?> + getHtml('Status'. $value->getStatus()); ?> + printHtml( + \sprintf('%3$s %2$s %1$s', $value->name1, $value->name2, $value->name3) + ); ?> + printHtml($value->getLastActive()->format('Y-m-d H:i:s')); ?> + printHtml($value->createdAt->format('Y-m-d H:i:s')); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+ +
+
+