From 807f490eb5d3b0d6007541b084a5709bb6e319c2 Mon Sep 17 00:00:00 2001 From: trendschau Date: Tue, 28 Feb 2023 22:39:30 +0100 Subject: [PATCH] Activate plugins --- .../ControllerApiSystemExtensions.php | 76 ++++++++++++++++ .../ControllerApiSystemPlugins.php | 7 ++ .../Controllers/ControllerWebSystem.php | 17 ++-- system/typemill/Models/Validation.php | 15 ++++ system/typemill/Plugin.php | 28 ++++++ system/typemill/author/js/vue-plugins.js | 88 ++++++++++++++++--- system/typemill/author/js/vue-shared.js | 37 -------- system/typemill/routes/api.php | 2 + system/typemill/settings/systemnavi.yaml | 12 +-- 9 files changed, 221 insertions(+), 61 deletions(-) create mode 100644 system/typemill/Controllers/ControllerApiSystemExtensions.php diff --git a/system/typemill/Controllers/ControllerApiSystemExtensions.php b/system/typemill/Controllers/ControllerApiSystemExtensions.php new file mode 100644 index 0000000..f7b825e --- /dev/null +++ b/system/typemill/Controllers/ControllerApiSystemExtensions.php @@ -0,0 +1,76 @@ +getParsedBody(); + + # validate input + $validate = new Validation(); + $vresult = $validate->activateExtension($params); + + if($vresult !== true) + { + $response->getBody()->write(json_encode([ + 'message' => 'Something went wrong, the input is not valid.', + 'errors' => $vresult + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + if(!isset($this->settings[$params['type']][$params['name']])) + { + $response->getBody()->write(json_encode([ + 'message' => 'The plugin or themes was not found.', + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + + $storage = new StorageWrapper('\Typemill\Models\Storage'); + + if($params['checked'] == true) + { + $definitions = $storage->getYaml($params['type'] . DIRECTORY_SEPARATOR . $params['name'], $params['name'] . '.yaml'); + + if(isset($definitions['license']) && in_array($definitions['license'], ['MAKER', 'BUSINESS'])) + { + $license = new License(); + $licenseScope = $license->getLicenseScope($this->c->get('urlinfo')); + if(!isset($licenseScope[$definitions['license']])) + { + $response->getBody()->write(json_encode([ + 'message' => 'We can not activate this plugin because you need a valid '. $definitions['license'] .'-license and your website must run under the domain of your license.', + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(400); + } + } + } + + $objectdata = []; + $objectdata[$params['type']][$params['name']] = $this->settings[$params['type']][$params['name']]; + $objectdata[$params['type']][$params['name']]['active'] = $params['checked']; + + + # store updated settings here + $updatedSettings = Settings::updateSettings($objectdata); + + $response->getBody()->write(json_encode([ + 'message' => 'settings have been saved' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(200); + } +} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemPlugins.php b/system/typemill/Controllers/ControllerApiSystemPlugins.php index 14f90dd..f250d4c 100644 --- a/system/typemill/Controllers/ControllerApiSystemPlugins.php +++ b/system/typemill/Controllers/ControllerApiSystemPlugins.php @@ -34,6 +34,13 @@ class ControllerApiSystemPlugins extends ControllerData return $response->withHeader('Content-Type', 'application/json')->withStatus(400); } + # keep the active setting + $validatedOutput['active'] = false; + if(isset($plugininput['active']) && $plugininput['active'] == true) + { + $validatedOutput['active'] = true; + } + $plugindata['plugins'][$pluginname] = $validatedOutput; # store updated settings here diff --git a/system/typemill/Controllers/ControllerWebSystem.php b/system/typemill/Controllers/ControllerWebSystem.php index 06d2f03..057523e 100644 --- a/system/typemill/Controllers/ControllerWebSystem.php +++ b/system/typemill/Controllers/ControllerWebSystem.php @@ -62,13 +62,19 @@ class ControllerWebSystem extends ControllerData public function showPlugins($request, $response, $args) { $translations = $this->c->get('translations'); - $pluginSettings = $this->getPluginDetails(); + $pluginDefinitions = $this->getPluginDetails(); - $plugindata = []; + $pluginSettings = []; foreach($this->settings['plugins'] as $pluginname => $plugininputs) { - $plugindata[$pluginname] = $plugininputs; + $pluginSettings[$pluginname] = $plugininputs; + } + + $license = []; + if(is_array($this->settings['license'])) + { + $license = array_keys($this->settings['license']); } return $this->c->get('view')->render($response, 'system/plugins.twig', [ @@ -76,8 +82,9 @@ class ControllerWebSystem extends ControllerData 'mainnavi' => $this->getMainNavigation($request->getAttribute('c_userrole')), 'systemnavi' => $this->getSystemNavigation($request->getAttribute('c_userrole')), 'jsdata' => [ - 'settings' => $plugindata, - 'plugins' => $pluginSettings, + 'settings' => $pluginSettings, + 'definitions' => $pluginDefinitions, + 'license' => $license, 'labels' => $translations, 'urlinfo' => $this->c->get('urlinfo') ] diff --git a/system/typemill/Models/Validation.php b/system/typemill/Models/Validation.php index 77ec3b6..00d0602 100644 --- a/system/typemill/Models/Validation.php +++ b/system/typemill/Models/Validation.php @@ -367,6 +367,21 @@ class Validation return $v->errors(); } + public function activateExtension(array $params) + { + $v = new Validator($params); + $v->rule('required', ['name', 'type', 'checked']); + $v->rule('in', 'type', ['plugins', 'themes']); + $v->rule('boolean', 'checked'); + + if($v->validate()) + { + return true; + } + + return $v->errors(); + } + /** * validation for system settings diff --git a/system/typemill/Plugin.php b/system/typemill/Plugin.php index 7a4c224..213fc08 100644 --- a/system/typemill/Plugin.php +++ b/system/typemill/Plugin.php @@ -36,6 +36,7 @@ abstract class Plugin implements EventSubscriberInterface protected function isXhr() { + return true; if($this->container['request']->isXhr()) { return true; @@ -45,11 +46,13 @@ abstract class Plugin implements EventSubscriberInterface protected function getParams() { + return true; return $this->container['request']->getParams(); } protected function returnJson($data) { + return true; return $this->container['response'] ->withHeader("Content-Type", "application/json") ->withStatus(200) @@ -58,6 +61,7 @@ abstract class Plugin implements EventSubscriberInterface protected function returnJsonError($data) { + return true; return $this->container['response'] ->withHeader("Content-Type", "application/json") ->withStatus(400) @@ -66,118 +70,141 @@ abstract class Plugin implements EventSubscriberInterface protected function getSettings() { + return true; return $this->container->get('settings'); } protected function getPluginSettings($plugin) { + return true; return $this->container->get('settings')['plugins'][$plugin]; } protected function getRoute() { + return true; return $this->container['request']->getUri()->withUserInfo(''); } protected function getPath() { + return true; return $this->container['request']->getUri()->getPath(); } protected function getDispatcher() { + return true; return $this->container['dispatcher']; } protected function getTwig() { + return true; return $this->container['view']; } protected function addTwigGlobal($name, $class) { + return true; $this->container->view->getEnvironment()->addGlobal($name, $class); } protected function addTwigFilter($name, $filter) { + return true; $filter = new \Twig_SimpleFilter($name, $filter); $this->container->view->getEnvironment()->addFilter($filter); } protected function addTwigFunction($name, $function) { + return true; $function = new \Twig_SimpleFunction($name, $function); $this->container->view->getEnvironment()->addFunction($function); } protected function addJS($JS) { + return true; $this->container->assets->addJS($JS); } protected function addEditorJS($JS) { + return true; $this->container->assets->addEditorJS($JS); } protected function addInlineJS($JS) { + return true; $this->container->assets->addInlineJS($JS); } protected function addSvgSymbol($symbol) { + return true; $this->container->assets->addSvgSymbol($symbol); } protected function addEditorInlineJS($JS) { + return true; $this->container->assets->addEditorInlineJS($JS); } protected function addCSS($CSS) { + return true; $this->container->assets->addCSS($CSS); } protected function addInlineCSS($CSS) { + return true; $this->container->assets->addInlineCSS($CSS); } protected function addEditorCSS($CSS) { + return true; $this->container->assets->addEditorCSS($CSS); } protected function getMeta() { + return true; return $this->container->assets->meta; } public function addMeta($key,$meta) { + return true; $this->container->assets->addMeta($key, $meta); } protected function activateAxios() { + return true; $this->container->assets->activateAxios(); } protected function activateVue() { + return true; $this->container->assets->activateVue(); } protected function activateTachyons() { + return true; $this->container->assets->activateTachyons(); } protected function markdownToHtml($markdown) { + return true; $parsedown = new ParsedownExtension(); $contentArray = $parsedown->text($markdown); @@ -188,6 +215,7 @@ abstract class Plugin implements EventSubscriberInterface protected function getFormData($pluginName) { + return true; $flash = $this->container->flash->getMessages(); if(isset($flash['formdata'])) diff --git a/system/typemill/author/js/vue-plugins.js b/system/typemill/author/js/vue-plugins.js index 896be14..78755e7 100644 --- a/system/typemill/author/js/vue-plugins.js +++ b/system/typemill/author/js/vue-plugins.js @@ -3,16 +3,16 @@ const app = Vue.createApp({
+
+ + + + + +
`, data() { return { current: '', - formDefinitions: data.plugins, + formDefinitions: data.definitions, formData: data.settings, + license: data.license, message: '', messageClass: '', errors: {}, userroles: false, + showModal: false, + modalMessage: 'default', } }, mounted() { @@ -77,6 +95,50 @@ const app = Vue.createApp({ }); }, methods: { + getActiveClass: function(pluginname) + { + if(this.formData[pluginname]['active']) + { + return 'bg-teal-500 text-white'; + } + }, + getLinkToLicense: function() + { + return tmaxios.defaults.baseURL + "/tm/license"; + }, + checkLicense: function(haystack, needle) + { + if(needle == 'MAKER' || needle == 'BUSINESS') + { + if(haystack.indexOf(needle) == -1) + { + return false; + } + } + return true; + }, + activate: function(pluginname) + { + var self = this; + + tmaxios.post('/api/v1/extensions',{ + 'csrf_name': document.getElementById("csrf_name").value, + 'csrf_value': document.getElementById("csrf_value").value, + 'type': 'plugins', + 'name': pluginname, + 'checked': this.formData[pluginname]['active'] + }) + .then(function (response) + { + + }) + .catch(function (error) + { + self.formData[pluginname]['active'] = false; + self.modalMessage = error.response.data.message; + self.showModal = true; + }); + }, setCurrent: function(name) { if(this.current == name) diff --git a/system/typemill/author/js/vue-shared.js b/system/typemill/author/js/vue-shared.js index a89049c..14ac79d 100644 --- a/system/typemill/author/js/vue-shared.js +++ b/system/typemill/author/js/vue-shared.js @@ -1087,43 +1087,6 @@ app.component('modal', { }, }) -app.component('activebox', { - props: ['id', 'description', 'readonly', 'required', 'disabled', 'label', 'checkboxlabel', 'name', 'type', 'css', 'value', 'errors'], - data() { - return { - checked: false - } - }, - template: `
- - -

{{ errors[name] }}

-

{{ $filters.translate(description) }}

-
`, - mounted: function() - { - if(this.value === true || this.value == 'on') - { - this.checked = true; - } - }, - methods: { - activate: function(checked, name) - { - alert("yes"); - }, - }, -}) - - - - - const medialib = app.component('medialib', { props: ['parentcomponent'], template: `
diff --git a/system/typemill/routes/api.php b/system/typemill/routes/api.php index 54a78bd..9ca52d7 100644 --- a/system/typemill/routes/api.php +++ b/system/typemill/routes/api.php @@ -8,6 +8,7 @@ use Typemill\Controllers\ControllerApiMedia; use Typemill\Controllers\ControllerApiSystemSettings; use Typemill\Controllers\ControllerApiSystemThemes; use Typemill\Controllers\ControllerApiSystemPlugins; +use Typemill\Controllers\ControllerApiSystemExtensions; use Typemill\Controllers\ControllerApiSystemLicense; use Typemill\Controllers\ControllerApiSystemUsers; use Typemill\Controllers\ControllerApiImage; @@ -24,6 +25,7 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) { $group->post('/license', ControllerApiSystemLicense::class . ':createLicense')->setName('api.license.create')->add(new ApiAuthorization($acl, 'system', 'update')); # admin $group->post('/theme', ControllerApiSystemThemes::class . ':updateTheme')->setName('api.theme.set')->add(new ApiAuthorization($acl, 'system', 'update')); # admin $group->post('/plugin', ControllerApiSystemPlugins::class . ':updatePlugin')->setName('api.plugin.set')->add(new ApiAuthorization($acl, 'system', 'update')); # admin + $group->post('/extensions', ControllerApiSystemExtensions::class . ':activateExtension')->setName('api.extension.activate')->add(new ApiAuthorization($acl, 'system', 'update')); # admin $group->get('/users/getbynames', ControllerApiSystemUsers::class . ':getUsersByNames')->setName('api.usersbynames')->add(new ApiAuthorization($acl, 'user', 'update')); # admin $group->get('/users/getbyemail', ControllerApiSystemUsers::class . ':getUsersByEmail')->setName('api.usersbyemail')->add(new ApiAuthorization($acl, 'user', 'update')); # admin $group->get('/users/getbyrole', ControllerApiSystemUsers::class . ':getUsersByRole')->setName('api.usersbyrole')->add(new ApiAuthorization($acl, 'user', 'update')); # admin diff --git a/system/typemill/settings/systemnavi.yaml b/system/typemill/settings/systemnavi.yaml index b4fb962..47e627e 100644 --- a/system/typemill/settings/systemnavi.yaml +++ b/system/typemill/settings/systemnavi.yaml @@ -4,6 +4,12 @@ 'icon': 'icon-wrench' 'aclresource': 'system' 'aclprivilege': 'view' +'license': + 'title': 'License' + 'routename': 'license.show' + 'icon': 'icon-wrench' + 'aclresource': 'system' + 'aclprivilege': 'view' 'themes': 'title': 'Themes' 'routename': 'themes.show' @@ -16,12 +22,6 @@ 'icon': 'icon-plug' 'aclresource': 'system' 'aclprivilege': 'view' -'license': - 'title': 'License' - 'routename': 'license.show' - 'icon': 'icon-wrench' - 'aclresource': 'system' - 'aclprivilege': 'view' 'account': 'title': 'Account' 'routename': 'user.account'