MDL-85727 tiny_premium: Support On-Premise version
Users can now select whether to use the Cloud-hosted version or the On-Premise version of Premium plugins, providing flexibility ased on their deployment preferences
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
issueNumber: MDL-85727
|
||||
notes:
|
||||
tiny_premium:
|
||||
- message: >
|
||||
The `tiny_premium_get_api_key` web service now returns an additional
|
||||
field `usecloud` to indicate whether the cloud version or self-hosted
|
||||
version of Tiny Premium plugins should be used.
|
||||
type: improved
|
||||
@@ -5,6 +5,6 @@ define("tiny_premium/plugin",["exports","editor_tiny/loader","editor_tiny/utils"
|
||||
* @module tiny_premium/plugin
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/(Configuration);const currentContextId=(_config=(obj=_config)&&obj.__esModule?obj:{default:obj}).default.contextid;var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,externalData]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName),(0,_external.getApiKey)(currentContextId)]);tinyMCE.PluginManager.add("".concat(_common.component,"/plugin"),(()=>pluginMetadata)),await getTinyPremium(tinyMCE,externalData.apikey),resolve(["".concat(_common.component,"/plugin"),Configuration])}));let tinyPremiumPromise;_exports.default=_default;const getTinyPremium=(tinyMCE,apikey)=>tinyPremiumPromise||(tinyPremiumPromise=new Promise(((resolve,reject)=>{const head=document.querySelector("head"),script=document.createElement("script"),tinyVersion="".concat(tinyMCE.majorVersion,".").concat(tinyMCE.minorVersion);script.dataset.tinymce="premium",script.src="https://cdn.tiny.cloud/1/".concat(apikey,"/tinymce/").concat(tinyVersion,"/plugins.min.js"),script.referrerpolicy="origin",script.addEventListener("load",(()=>{resolve()}),!1),script.addEventListener("error",(err=>{reject(err)}),!1),head.append(script)})),tinyPremiumPromise);return _exports.default}));
|
||||
*/(Configuration);const currentContextId=(_config=(obj=_config)&&obj.__esModule?obj:{default:obj}).default.contextid;var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,externalData]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName),(0,_external.getApiKey)(currentContextId)]);tinyMCE.PluginManager.add("".concat(_common.component,"/plugin"),(()=>pluginMetadata)),externalData.usecloud&&await getTinyPremium(tinyMCE,externalData.apikey),resolve(["".concat(_common.component,"/plugin"),Configuration])}));let tinyPremiumPromise;_exports.default=_default;const getTinyPremium=(tinyMCE,apikey)=>tinyPremiumPromise||(tinyPremiumPromise=new Promise(((resolve,reject)=>{const head=document.querySelector("head"),script=document.createElement("script"),tinyVersion="".concat(tinyMCE.majorVersion,".").concat(tinyMCE.minorVersion);script.dataset.tinymce="premium",script.src="https://cdn.tiny.cloud/1/".concat(apikey,"/tinymce/").concat(tinyVersion,"/plugins.min.js"),script.referrerpolicy="origin",script.addEventListener("load",(()=>{resolve()}),!1),script.addEventListener("error",(err=>{reject(err)}),!1),head.append(script)})),tinyPremiumPromise);return _exports.default}));
|
||||
|
||||
//# sourceMappingURL=plugin.min.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny Premium plugin for Moodle.\n *\n * @module tiny_premium/plugin\n * @copyright 2023 David Woloszyn <[email protected]>\n * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\nimport {component, pluginName} from 'tiny_premium/common';\nimport * as Configuration from 'tiny_premium/configuration';\nimport {getApiKey} from 'tiny_premium/external';\nimport Config from 'core/config';\n\nconst currentContextId = Config.contextid;\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n pluginMetadata,\n externalData\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n getApiKey(currentContextId)\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, () => {\n return pluginMetadata;\n });\n\n // Load the Tiny Premium script using the provided API key.\n await getTinyPremium(tinyMCE, externalData.apikey);\n\n resolve([`${component}/plugin`, Configuration]);\n});\n\nlet tinyPremiumPromise;\n\n/**\n * Promise for Tiny Premium plugins script.\n *\n * @param {TinyMCE} tinyMCE\n * @param {string} apikey\n * @return {Promise}\n */\nconst getTinyPremium = (tinyMCE, apikey) => {\n if (tinyPremiumPromise) {\n return tinyPremiumPromise;\n }\n\n tinyPremiumPromise = new Promise((resolve, reject) => {\n const head = document.querySelector('head');\n const script = document.createElement('script');\n const tinyVersion = `${tinyMCE.majorVersion}.${tinyMCE.minorVersion}`;\n\n script.dataset.tinymce = 'premium';\n script.src = `https://cdn.tiny.cloud/1/${apikey}/tinymce/${tinyVersion}/plugins.min.js`;\n script.referrerpolicy = \"origin\";\n\n script.addEventListener('load', () => {\n resolve();\n }, false);\n\n script.addEventListener('error', (err) => {\n reject(err);\n }, false);\n\n head.append(script);\n });\n\n return tinyPremiumPromise;\n};\n"],"names":["currentContextId","contextid","Promise","async","tinyMCE","pluginMetadata","externalData","all","component","pluginName","PluginManager","add","getTinyPremium","apikey","resolve","Configuration","tinyPremiumPromise","reject","head","document","querySelector","script","createElement","tinyVersion","majorVersion","minorVersion","dataset","tinymce","src","referrerpolicy","addEventListener","err","append"],"mappings":";;;;;;;2BA8BMA,mFAA0BC,uBAGjB,IAAIC,SAAQC,MAAAA,gBAEnBC,QACAC,eACAC,oBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,qBAC7B,uBAAUT,oBAGdI,QAAQM,cAAcC,cAAOH,8BAAoB,IACtCH,uBAILO,eAAeR,QAASE,aAAaO,QAE3CC,QAAQ,WAAIN,6BAAoBO,uBAGhCC,mDASEJ,eAAiB,CAACR,QAASS,SACzBG,qBAIJA,mBAAqB,IAAId,SAAQ,CAACY,QAASG,gBACjCC,KAAOC,SAASC,cAAc,QAC9BC,OAASF,SAASG,cAAc,UAChCC,sBAAiBnB,QAAQoB,yBAAgBpB,QAAQqB,cAEvDJ,OAAOK,QAAQC,QAAU,UACzBN,OAAOO,uCAAkCf,2BAAkBU,+BAC3DF,OAAOQ,eAAiB,SAExBR,OAAOS,iBAAiB,QAAQ,KAC5BhB,aACD,GAEHO,OAAOS,iBAAiB,SAAUC,MAC9Bd,OAAOc,QACR,GAEHb,KAAKc,OAAOX,WAGTL"}
|
||||
{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny Premium plugin for Moodle.\n *\n * @module tiny_premium/plugin\n * @copyright 2023 David Woloszyn <[email protected]>\n * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\nimport {component, pluginName} from 'tiny_premium/common';\nimport * as Configuration from 'tiny_premium/configuration';\nimport {getApiKey} from 'tiny_premium/external';\nimport Config from 'core/config';\n\nconst currentContextId = Config.contextid;\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n pluginMetadata,\n externalData\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n getApiKey(currentContextId)\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, () => {\n return pluginMetadata;\n });\n\n if (externalData.usecloud) {\n // Load the Tiny Premium script using the provided API key.\n await getTinyPremium(tinyMCE, externalData.apikey);\n }\n\n resolve([`${component}/plugin`, Configuration]);\n});\n\nlet tinyPremiumPromise;\n\n/**\n * Promise for Tiny Premium plugins script.\n *\n * @param {TinyMCE} tinyMCE\n * @param {string} apikey\n * @return {Promise}\n */\nconst getTinyPremium = (tinyMCE, apikey) => {\n if (tinyPremiumPromise) {\n return tinyPremiumPromise;\n }\n\n tinyPremiumPromise = new Promise((resolve, reject) => {\n const head = document.querySelector('head');\n const script = document.createElement('script');\n const tinyVersion = `${tinyMCE.majorVersion}.${tinyMCE.minorVersion}`;\n\n script.dataset.tinymce = 'premium';\n script.src = `https://cdn.tiny.cloud/1/${apikey}/tinymce/${tinyVersion}/plugins.min.js`;\n script.referrerpolicy = \"origin\";\n\n script.addEventListener('load', () => {\n resolve();\n }, false);\n\n script.addEventListener('error', (err) => {\n reject(err);\n }, false);\n\n head.append(script);\n });\n\n return tinyPremiumPromise;\n};\n"],"names":["currentContextId","contextid","Promise","async","tinyMCE","pluginMetadata","externalData","all","component","pluginName","PluginManager","add","usecloud","getTinyPremium","apikey","resolve","Configuration","tinyPremiumPromise","reject","head","document","querySelector","script","createElement","tinyVersion","majorVersion","minorVersion","dataset","tinymce","src","referrerpolicy","addEventListener","err","append"],"mappings":";;;;;;;2BA8BMA,mFAA0BC,uBAGjB,IAAIC,SAAQC,MAAAA,gBAEnBC,QACAC,eACAC,oBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,qBAC7B,uBAAUT,oBAGdI,QAAQM,cAAcC,cAAOH,8BAAoB,IACtCH,iBAGPC,aAAaM,gBAEPC,eAAeT,QAASE,aAAaQ,QAG/CC,QAAQ,WAAIP,6BAAoBQ,uBAGhCC,mDASEJ,eAAiB,CAACT,QAASU,SACzBG,qBAIJA,mBAAqB,IAAIf,SAAQ,CAACa,QAASG,gBACjCC,KAAOC,SAASC,cAAc,QAC9BC,OAASF,SAASG,cAAc,UAChCC,sBAAiBpB,QAAQqB,yBAAgBrB,QAAQsB,cAEvDJ,OAAOK,QAAQC,QAAU,UACzBN,OAAOO,uCAAkCf,2BAAkBU,+BAC3DF,OAAOQ,eAAiB,SAExBR,OAAOS,iBAAiB,QAAQ,KAC5BhB,aACD,GAEHO,OAAOS,iBAAiB,SAAUC,MAC9Bd,OAAOc,QACR,GAEHb,KAAKc,OAAOX,WAGTL"}
|
||||
@@ -46,8 +46,10 @@ export default new Promise(async(resolve) => {
|
||||
return pluginMetadata;
|
||||
});
|
||||
|
||||
// Load the Tiny Premium script using the provided API key.
|
||||
await getTinyPremium(tinyMCE, externalData.apikey);
|
||||
if (externalData.usecloud) {
|
||||
// Load the Tiny Premium script using the provided API key.
|
||||
await getTinyPremium(tinyMCE, externalData.apikey);
|
||||
}
|
||||
|
||||
resolve([`${component}/plugin`, Configuration]);
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ use core_external\external_api;
|
||||
use core_external\external_function_parameters;
|
||||
use core_external\external_single_structure;
|
||||
use core_external\external_value;
|
||||
use tiny_premium\manager;
|
||||
|
||||
/**
|
||||
* External API for Tiny Premium.
|
||||
@@ -61,6 +62,7 @@ class get_api_key extends external_api {
|
||||
self::validate_context($context);
|
||||
return [
|
||||
'apikey' => get_config('tiny_premium', 'apikey'),
|
||||
'usecloud' => get_config('tiny_premium', 'plugin_source') !== manager::PACKAGE_SELF_HOSTED,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -73,6 +75,7 @@ class get_api_key extends external_api {
|
||||
public static function execute_returns(): external_single_structure {
|
||||
return new external_single_structure([
|
||||
'apikey' => new external_value(PARAM_ALPHANUM, 'The API key for Tiny Premium'),
|
||||
'usecloud' => new external_value(PARAM_BOOL, 'Whether to use the cloud version of Tiny Premium plugins or self-hosted'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -72,7 +72,8 @@ class admin_setting_tiny_premium_plugins extends \admin_setting {
|
||||
$return = '';
|
||||
|
||||
// Warn users about an empty API key when displaying enabled plugins.
|
||||
if (empty(get_config('tiny_premium', 'apikey')) && !empty(manager::get_enabled_plugins())) {
|
||||
if (get_config('tiny_premium', 'plugin_source') == manager::PACKAGE_CLOUD && empty(get_config('tiny_premium', 'apikey')) &&
|
||||
!empty(manager::get_enabled_plugins())) {
|
||||
$return .= \core\notification::warning(get_string('emptyapikeywarning', 'tiny_premium'));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ class manager {
|
||||
|
||||
/** @var string Tiny Premium plugin prefix. */
|
||||
const PLUGIN_NAME_PREFIX = 'tiny_premium_';
|
||||
/** @var int Indicates usage of self-hosted TinyMCE packages. */
|
||||
public const PACKAGE_SELF_HOSTED = 2;
|
||||
/** @var int Indicates usage of cloud-hosted TinyMCE packages. */
|
||||
public const PACKAGE_CLOUD = 1;
|
||||
|
||||
/**
|
||||
* Get all Tiny Premium plugins currently supported.
|
||||
|
||||
@@ -30,8 +30,13 @@ $string['apikey'] = 'API key';
|
||||
$string['apikey_desc'] = 'Your API key is available on your <a href="https://www.tiny.cloud">Tiny Cloud</a> account page if you have purchased a subscription, or if you are on a free trial.';
|
||||
$string['emptyapikeywarning'] = 'Enabled TinyMCE Premium plugins will not be available until an API key is added.';
|
||||
$string['invalidurl'] = 'Wrong URL';
|
||||
$string['invalidpath'] = 'You have not provided a valid path to the TinyMCE standalone package. Please check the <a href="{$a}">TinyMCE General settings</a> page.';
|
||||
$string['pluginname'] = 'TinyMCE Premium';
|
||||
$string['pluginnotfound'] = 'Tiny Premium plugin {$a} not found.';
|
||||
$string['pluginsource'] = 'Plugin source';
|
||||
$string['pluginsource:cloud'] = 'Tiny Cloud';
|
||||
$string['pluginsource:selfhosted'] = 'Self-hosted';
|
||||
$string['pluginsource_desc'] = 'Select the source of the Tiny Premium plugins. If you select \'Tiny Cloud\', you will need to provide an API key. If you select \'Self-hosted\', you will need to provide a valid path to TinyMCE in the <a href="{$a}">TinyMCE General settings</a> page.';
|
||||
$string['premium:use'] = 'Use TinyMCE Premium';
|
||||
$string['premium:usea11ychecker'] = 'Use TinyMCE Premium Accessibility Checker';
|
||||
$string['premium:useadvtable'] = 'Use TinyMCE Premium Advanced Table';
|
||||
|
||||
@@ -23,11 +23,38 @@
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use tiny_premium\manager;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
|
||||
if ($ADMIN->fulltree) {
|
||||
$sourcepathurl = new moodle_url('/admin/settings.php', ['section' => 'editorsettingstiny']);
|
||||
$setting = new admin_setting_configselect(
|
||||
'tiny_premium/plugin_source',
|
||||
new lang_string('pluginsource', 'tiny_premium'),
|
||||
new lang_string('pluginsource_desc', 'tiny_premium', $sourcepathurl->out(false)),
|
||||
manager::PACKAGE_CLOUD,
|
||||
[
|
||||
manager::PACKAGE_CLOUD => new lang_string('pluginsource:cloud', 'tiny_premium'),
|
||||
manager::PACKAGE_SELF_HOSTED => new lang_string('pluginsource:selfhosted', 'tiny_premium'),
|
||||
],
|
||||
);
|
||||
$setting->set_validate_function(function(int $value): string {
|
||||
if ($value == manager::PACKAGE_SELF_HOSTED) {
|
||||
// If the self-hosted package is selected, we need to check if the standalone path is set.
|
||||
// If not, we return a warning message.
|
||||
$packagesource = get_config('editor_tiny', 'package_source');
|
||||
$standalonepath = get_config('editor_tiny', 'package_source_standalone_path');
|
||||
if ($packagesource != manager::PACKAGE_SELF_HOSTED || empty($standalonepath)) {
|
||||
return get_string('package_source_standalone_path_invalid', 'editor_tiny');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
$settings->add($setting);
|
||||
|
||||
// Set API key.
|
||||
$setting = new admin_setting_configpasswordunmask(
|
||||
'tiny_premium/apikey',
|
||||
@@ -36,6 +63,12 @@ if ($hassiteconfig) {
|
||||
'',
|
||||
);
|
||||
$settings->add($setting);
|
||||
$settings->hide_if(
|
||||
'tiny_premium/apikey',
|
||||
'tiny_premium/plugin_source',
|
||||
'eq',
|
||||
manager::PACKAGE_SELF_HOSTED,
|
||||
);
|
||||
|
||||
// Set individual Tiny Premium plugins.
|
||||
$settings->add(new \tiny_premium\local\admin_setting_tiny_premium_plugins());
|
||||
|
||||
Reference in New Issue
Block a user