From a8bcf89311070662c4fd9a00cdbfcd2f6717a337 Mon Sep 17 00:00:00 2001 From: Thomas Wedekind Date: Tue, 3 Sep 2024 14:36:32 +0200 Subject: [PATCH 1/5] plugininfo for autosave --- .../plugins/autosave/classes/plugininfo.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php index 38aca833f8697..51cf03ca5bd3d 100644 --- a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php +++ b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php @@ -35,17 +35,28 @@ public static function get_plugin_configuration_for_context( array $fpoptions, ?\editor_tiny\editor $editor = null ): array { - global $PAGE; + global $PAGE, $DB; if (empty($editor) || empty($options['autosave'])) { return [ 'autosave' => null, ]; } - + //maybe add parameter: 'pagehash' => s($editor->get_text()) + if($options['collaborative_enabled']) { + $created = $DB->get_record('tiny_autosave', ['elementid' => $options['elementid'], 'contextid' => $options['contextid']], '*', IGNORE_MISSING); + if($created) { + $pagehash = $created->pagehash; + $pageinstance = $created->pageinstance; + } + } + if(!$pagehash) { + $pagehash = sha1($PAGE->url . '<>' . s($editor->get_text())); + $pageinstance = bin2hex(random_bytes(16)); + } return [ - 'pagehash' => sha1($PAGE->url . '<>' . s($editor->get_text())), - 'pageinstance' => bin2hex(random_bytes(16)), + 'pagehash' => $pagehash, + 'pageinstance' => $pageinstance, 'backoffTime' => (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) ? 0 : 500, ]; } From acbdf78db2cdb6a9de011ce99978eed552335346 Mon Sep 17 00:00:00 2001 From: Thomas Wedekind Date: Tue, 3 Sep 2024 14:37:20 +0200 Subject: [PATCH 2/5] fix indention --- lib/editor/tiny/plugins/autosave/classes/plugininfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php index 51cf03ca5bd3d..52ffaede15900 100644 --- a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php +++ b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php @@ -43,14 +43,14 @@ public static function get_plugin_configuration_for_context( ]; } //maybe add parameter: 'pagehash' => s($editor->get_text()) - if($options['collaborative_enabled']) { + if ($options['collaborative_enabled']) { $created = $DB->get_record('tiny_autosave', ['elementid' => $options['elementid'], 'contextid' => $options['contextid']], '*', IGNORE_MISSING); if($created) { $pagehash = $created->pagehash; $pageinstance = $created->pageinstance; } } - if(!$pagehash) { + if (!$pagehash) { $pagehash = sha1($PAGE->url . '<>' . s($editor->get_text())); $pageinstance = bin2hex(random_bytes(16)); } From 6e29ad5ba99cb8e4771159f865c777c7b394910a Mon Sep 17 00:00:00 2001 From: Jan Britz Date: Tue, 3 Sep 2024 10:23:30 -0400 Subject: [PATCH 3/5] fix: create necessary plugin files --- .../plugins/autosave/classes/plugininfo.php | 3 +- .../plugins/collaborative/amd/src/commands.js | 18 ++++++++++ .../plugins/collaborative/amd/src/common.js | 6 ++++ .../collaborative/amd/src/configuration.js | 4 +++ .../plugins/collaborative/amd/src/options.js | 28 +++++++++++++++ .../plugins/collaborative/amd/src/plugin.js | 36 +++++++++++++++++++ .../collaborative/classes/plugininfo.php | 14 ++------ 7 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 lib/editor/tiny/plugins/collaborative/amd/src/commands.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/src/common.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/src/configuration.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/src/options.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/src/plugin.js diff --git a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php index 52ffaede15900..92dfdbc3ebe68 100644 --- a/lib/editor/tiny/plugins/autosave/classes/plugininfo.php +++ b/lib/editor/tiny/plugins/autosave/classes/plugininfo.php @@ -42,8 +42,9 @@ public static function get_plugin_configuration_for_context( 'autosave' => null, ]; } + $pagehash = null; //maybe add parameter: 'pagehash' => s($editor->get_text()) - if ($options['collaborative_enabled']) { + if ($options['collaborative_enabled'] ?? null) { $created = $DB->get_record('tiny_autosave', ['elementid' => $options['elementid'], 'contextid' => $options['contextid']], '*', IGNORE_MISSING); if($created) { $pagehash = $created->pagehash; diff --git a/lib/editor/tiny/plugins/collaborative/amd/src/commands.js b/lib/editor/tiny/plugins/collaborative/amd/src/commands.js new file mode 100644 index 0000000000000..badd5a4ca0192 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/src/commands.js @@ -0,0 +1,18 @@ +/** + * Handle the action for your plugin. + * @param {TinyMCE.editor} editor The tinyMCE editor instance. + */ +const handleAction = (editor) => { + // TODO Handle the action. + window.console.log(editor); +}; + +export const getSetup = async() => { + return (editor) => { + // Register the startdemo Toolbar Button. + editor.ui.registry.addButton("Toggle collaborative", { + tooltip: "Toggle collaborative", + onAction: () => handleAction(editor), + }); + }; +}; \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/src/common.js b/lib/editor/tiny/plugins/collaborative/amd/src/common.js new file mode 100644 index 0000000000000..b140fe814f535 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/src/common.js @@ -0,0 +1,6 @@ +const component = 'tiny_collaborative'; + +export default { + component, + pluginName: `${component}/plugin` +}; \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/src/configuration.js b/lib/editor/tiny/plugins/collaborative/amd/src/configuration.js new file mode 100644 index 0000000000000..ad57ca10dd32f --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/src/configuration.js @@ -0,0 +1,4 @@ + +export const configure = () => { + return {}; +}; \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/src/options.js b/lib/editor/tiny/plugins/collaborative/amd/src/options.js new file mode 100644 index 0000000000000..b253660ebe9a6 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/src/options.js @@ -0,0 +1,28 @@ +import {getPluginOptionName} from 'editor_tiny/options'; +import {pluginName} from './common'; + +// Helper variables for the option names. +const myFirstPropertyName = getPluginOptionName(pluginName, 'myFirstProperty'); + +/** + * Options registration function. + * + * @param {tinyMCE} editor + */ +export const register = (editor) => { + const registerOption = editor.options.register; + + // For each option, register it with the editor. + // Valid type are defined in https://www.tiny.cloud/docs/tinymce/6/apis/tinymce.editoroptions/ + registerOption(myFirstPropertyName, { + processor: 'number', + }); +}; + +/** + * Fetch the myFirstProperty value for this editor instance. + * + * @param {tinyMCE} editor The editor instance to fetch the value for + * @returns {object} The value of the myFirstProperty option + */ +export const getMyFirstProperty = (editor) => editor.options.get(myFirstPropertyName); \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/src/plugin.js b/lib/editor/tiny/plugins/collaborative/amd/src/plugin.js new file mode 100644 index 0000000000000..a7855539aced1 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/src/plugin.js @@ -0,0 +1,36 @@ +import {getTinyMCE} from 'editor_tiny/loader'; +import {getPluginMetadata} from 'editor_tiny/utils'; + +import {component, pluginName} from './common'; +import {register as registerOptions} from './options'; +import {getSetup as getCommandSetup} from './commands'; +import * as Configuration from './configuration'; + +// Setup the tiny_example Plugin. +export default new Promise(async(resolve) => { + // Note: The PluginManager.add function does not support asynchronous configuration. + // Perform any asynchronous configuration here, and then call the PluginManager.add function. + const [ + tinyMCE, + pluginMetadata, + setupCommands, + ] = await Promise.all([ + getTinyMCE(), + getPluginMetadata(component, pluginName), + getCommandSetup(), + ]); + + // Reminder: Any asynchronous code must be run before this point. + tinyMCE.PluginManager.add(pluginName, (editor) => { + // Register any options that your plugin has + registerOptions(editor); + + // Setup any commands such as buttons, menu items, and so on. + setupCommands(editor); + + // Return the pluginMetadata object. This is used by TinyMCE to display a help link for your plugin. + return pluginMetadata; + }); + + resolve([pluginName, Configuration]); +}); \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/classes/plugininfo.php b/lib/editor/tiny/plugins/collaborative/classes/plugininfo.php index 6a5417ed4d40d..4e008db6af69d 100644 --- a/lib/editor/tiny/plugins/collaborative/classes/plugininfo.php +++ b/lib/editor/tiny/plugins/collaborative/classes/plugininfo.php @@ -35,18 +35,10 @@ public static function get_plugin_configuration_for_context( array $fpoptions, ?\editor_tiny\editor $editor = null ): array { - global $PAGE; - - if (empty($editor) || empty($options['autosave'])) { - return [ - 'autosave' => null, - ]; - } - + // Your values go here. + // These will be mapped to a namespaced EditorOption in Tiny. return [ - 'pagehash' => sha1($PAGE->url . '<>' . s($editor->get_text())), - 'pageinstance' => bin2hex(random_bytes(16)), - 'backoffTime' => (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) ? 0 : 500, + 'myFirstProperty' => 'TODO Calculate your values here', ]; } } From 9983af14216eca3821d9e4fcf917f733a5f77ee5 Mon Sep 17 00:00:00 2001 From: Jan Britz Date: Tue, 3 Sep 2024 10:23:55 -0400 Subject: [PATCH 4/5] fix: create necessary plugin files --- .../tiny/plugins/collaborative/amd/build/commands.min.js | 3 +++ .../tiny/plugins/collaborative/amd/build/commands.min.js.map | 1 + lib/editor/tiny/plugins/collaborative/amd/build/common.min.js | 3 +++ .../tiny/plugins/collaborative/amd/build/common.min.js.map | 1 + .../tiny/plugins/collaborative/amd/build/configuration.min.js | 3 +++ .../plugins/collaborative/amd/build/configuration.min.js.map | 1 + lib/editor/tiny/plugins/collaborative/amd/build/options.min.js | 3 +++ .../tiny/plugins/collaborative/amd/build/options.min.js.map | 1 + lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js | 3 +++ .../tiny/plugins/collaborative/amd/build/plugin.min.js.map | 1 + 10 files changed, 20 insertions(+) create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js.map create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/common.min.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/common.min.js.map create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js.map create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/options.min.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/options.min.js.map create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js create mode 100644 lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js.map diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js b/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js new file mode 100644 index 0000000000000..1372dc3e893af --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js @@ -0,0 +1,3 @@ +define("tiny_collaborative/commands",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getSetup=void 0;_exports.getSetup=async()=>editor=>{editor.ui.registry.addButton("Toggle collaborative",{tooltip:"Toggle collaborative",onAction:()=>(editor=>{window.console.log(editor)})(editor)})}})); + +//# sourceMappingURL=commands.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js.map b/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js.map new file mode 100644 index 0000000000000..4fddf717bd859 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/commands.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"commands.min.js","sources":["../src/commands.js"],"sourcesContent":["/**\n * Handle the action for your plugin.\n * @param {TinyMCE.editor} editor The tinyMCE editor instance.\n */\nconst handleAction = (editor) => {\n // TODO Handle the action.\n window.console.log(editor);\n};\n\nexport const getSetup = async() => {\n return (editor) => {\n // Register the startdemo Toolbar Button.\n editor.ui.registry.addButton(\"Toggle collaborative\", {\n tooltip: \"Toggle collaborative\",\n onAction: () => handleAction(editor),\n });\n };\n};"],"names":["async","editor","ui","registry","addButton","tooltip","onAction","window","console","log","handleAction"],"mappings":"wKASwBA,SACZC,SAEJA,OAAOC,GAAGC,SAASC,UAAU,uBAAwB,CACjDC,QAAS,uBACTC,SAAU,IAVAL,CAAAA,SAElBM,OAAOC,QAAQC,IAAIR,SAQKS,CAAaT"} \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js b/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js new file mode 100644 index 0000000000000..f7256e5a74338 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js @@ -0,0 +1,3 @@ +define("tiny_collaborative/common",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;var _default={component:"tiny_collaborative",pluginName:"".concat("tiny_collaborative","/plugin")};return _exports.default=_default,_exports.default})); + +//# sourceMappingURL=common.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js.map b/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js.map new file mode 100644 index 0000000000000..b23c43ad31162 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/common.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.min.js","sources":["../src/common.js"],"sourcesContent":["const component = 'tiny_collaborative';\n\nexport default {\n component,\n pluginName: `${component}/plugin`\n};"],"names":["component","pluginName"],"mappings":"gKAEe,CACXA,UAHc,qBAIdC,qBAJc"} \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js b/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js new file mode 100644 index 0000000000000..139ace2324d01 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js @@ -0,0 +1,3 @@ +define("tiny_collaborative/configuration",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0;_exports.configure=()=>({})})); + +//# sourceMappingURL=configuration.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js.map b/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js.map new file mode 100644 index 0000000000000..1dfea9c9a8148 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/configuration.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"configuration.min.js","sources":["../src/configuration.js"],"sourcesContent":["\nexport const configure = () => {\n return {};\n};"],"names":[],"mappings":"+KACyB,KACd"} \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js b/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js new file mode 100644 index 0000000000000..f7d02485437a2 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js @@ -0,0 +1,3 @@ +define("tiny_collaborative/options",["exports","editor_tiny/options","./common"],(function(_exports,_options,_common){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.register=_exports.getMyFirstProperty=void 0;const myFirstPropertyName=(0,_options.getPluginOptionName)(_common.pluginName,"myFirstProperty");_exports.register=editor=>{(0,editor.options.register)(myFirstPropertyName,{processor:"number"})};_exports.getMyFirstProperty=editor=>editor.options.get(myFirstPropertyName)})); + +//# sourceMappingURL=options.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js.map b/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js.map new file mode 100644 index 0000000000000..b7f7fd9aae66d --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/options.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"options.min.js","sources":["../src/options.js"],"sourcesContent":["import {getPluginOptionName} from 'editor_tiny/options';\nimport {pluginName} from './common';\n\n// Helper variables for the option names.\nconst myFirstPropertyName = getPluginOptionName(pluginName, 'myFirstProperty');\n\n/**\n * Options registration function.\n *\n * @param {tinyMCE} editor\n */\nexport const register = (editor) => {\n const registerOption = editor.options.register;\n\n // For each option, register it with the editor.\n // Valid type are defined in https://www.tiny.cloud/docs/tinymce/6/apis/tinymce.editoroptions/\n registerOption(myFirstPropertyName, {\n processor: 'number',\n });\n};\n\n/**\n * Fetch the myFirstProperty value for this editor instance.\n *\n * @param {tinyMCE} editor The editor instance to fetch the value for\n * @returns {object} The value of the myFirstProperty option\n */\nexport const getMyFirstProperty = (editor) => editor.options.get(myFirstPropertyName);"],"names":["myFirstPropertyName","pluginName","editor","registerOption","options","register","processor","get"],"mappings":"yOAIMA,qBAAsB,gCAAoBC,mBAAY,qCAOnCC,UAKrBC,EAJuBD,OAAOE,QAAQC,UAIvBL,oBAAqB,CAChCM,UAAW,wCAUgBJ,QAAWA,OAAOE,QAAQG,IAAIP"} \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js b/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js new file mode 100644 index 0000000000000..8f7c26413854a --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js @@ -0,0 +1,3 @@ +define("tiny_collaborative/plugin",["exports","editor_tiny/loader","editor_tiny/utils","./common","./options","./commands","./configuration"],(function(_exports,_loader,_utils,_common,_options,_commands,Configuration){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Configuration=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Configuration);var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,setupCommands]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName),(0,_commands.getSetup)()]);tinyMCE.PluginManager.add(_common.pluginName,(editor=>((0,_options.register)(editor),setupCommands(editor),pluginMetadata))),resolve([_common.pluginName,Configuration])}));return _exports.default=_default,_exports.default})); + +//# sourceMappingURL=plugin.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js.map b/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js.map new file mode 100644 index 0000000000000..71c5926d48c40 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/amd/build/plugin.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"plugin.min.js","sources":["../src/plugin.js"],"sourcesContent":["import {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport {register as registerOptions} from './options';\nimport {getSetup as getCommandSetup} from './commands';\nimport * as Configuration from './configuration';\n\n// Setup the tiny_example Plugin.\nexport default new Promise(async(resolve) => {\n // Note: The PluginManager.add function does not support asynchronous configuration.\n // Perform any asynchronous configuration here, and then call the PluginManager.add function.\n const [\n tinyMCE,\n pluginMetadata,\n setupCommands,\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n getCommandSetup(),\n ]);\n\n // Reminder: Any asynchronous code must be run before this point.\n tinyMCE.PluginManager.add(pluginName, (editor) => {\n // Register any options that your plugin has\n registerOptions(editor);\n\n // Setup any commands such as buttons, menu items, and so on.\n setupCommands(editor);\n\n // Return the pluginMetadata object. This is used by TinyMCE to display a help link for your plugin.\n return pluginMetadata;\n });\n\n resolve([pluginName, Configuration]);\n});"],"names":["Promise","async","tinyMCE","pluginMetadata","setupCommands","all","component","pluginName","PluginManager","add","editor","resolve","Configuration"],"mappings":"ovCASe,IAAIA,SAAQC,MAAAA,gBAInBC,QACAC,eACAC,qBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,qBAC7B,0BAIJL,QAAQM,cAAcC,IAAIF,oBAAaG,+BAEnBA,QAGhBN,cAAcM,QAGPP,kBAGXQ,QAAQ,CAACJ,mBAAYK"} \ No newline at end of file From 555bccba22984ac602c5738423e1c88a15c01adc Mon Sep 17 00:00:00 2001 From: Thomas Wedekind Date: Tue, 3 Sep 2024 19:08:43 +0200 Subject: [PATCH 5/5] collaboratiny services --- .../collaborative/classes/change_manager.php | 95 ++++++++++++++++ .../classes/external/get_changes.php | 104 ++++++++++++++++++ .../classes/external/save_changes.php | 104 ++++++++++++++++++ .../tiny/plugins/collaborative/db/install.xml | 22 ++++ .../plugins/collaborative/db/services.php | 44 ++++++++ 5 files changed, 369 insertions(+) create mode 100644 lib/editor/tiny/plugins/collaborative/classes/change_manager.php create mode 100644 lib/editor/tiny/plugins/collaborative/classes/external/get_changes.php create mode 100644 lib/editor/tiny/plugins/collaborative/classes/external/save_changes.php create mode 100644 lib/editor/tiny/plugins/collaborative/db/install.xml create mode 100644 lib/editor/tiny/plugins/collaborative/db/services.php diff --git a/lib/editor/tiny/plugins/collaborative/classes/change_manager.php b/lib/editor/tiny/plugins/collaborative/classes/change_manager.php new file mode 100644 index 0000000000000..5bb9f1ae0c4fc --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/classes/change_manager.php @@ -0,0 +1,95 @@ +. + +namespace tiny_collaborative; + +use stdClass; + +/** + * Autosave Manager. + * + * @package tiny_autosave + * @copyright 2022 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class change_manager { + + /** @var int The contextid */ + protected $contextid; + + /** @var string The page hash reference */ + protected $pagehash; + + /** @var string The page instance reference */ + protected $pageinstance; + + /** @var string The elementid for this editor */ + protected $elementid; + + protected $oldcontenthash; + + /** + * Constructor for the autosave manager. + * + * @param int $contextid The contextid of the session + * @param string $pagehash The page hash + * @param string $pageinstance The page instance + * @param string $elementid The element id + * @param null|stdClass $user The user object for the owner of the autosave + */ + public function __construct( + int $contextid, + string $pagehash, + string $pageinstance, + string $elementid, + string $oldcontenthash + ) { + $this->contextid = $contextid; + $this->pagehash = $pagehash; + $this->pageinstance = $pageinstance; + $this->elementid = $elementid; + $this->oldcontenthash = $oldcontenthash; + } + + public function add_collaborative_record($newcontenthash, $changes) { + global $DB; + + $autosave = $DB->get_record('tiny_autosave', ['elementid' => $this->elementid, 'contextid' => $this->contextid, 'pagehash' =>$this->pagehash]); + $record = new \stdClass(); + $record->oldcontenthash = $this->oldcontenthash; + $record->newcontenthash = $newcontenthash; + $record->timemodified = time(); + $record->changes = $changes; + $record->autosaveid = $autosave->id; + + try{ + $record = $DB->insert_record('tiny_collaborative_changes', $record); + } catch(\Exception $e) { + return "-1"; + } + return $record->id; + } + + public function get_changes() { + global $DB; + $changesarray = []; + while ($change = $DB->get_record('tiny_collaborative_changes', ['oldcontenthash' => $this->oldcontenthash])) { + $changesarray[] = $change->changes; + } + return $changesarray; + } + +} diff --git a/lib/editor/tiny/plugins/collaborative/classes/external/get_changes.php b/lib/editor/tiny/plugins/collaborative/classes/external/get_changes.php new file mode 100644 index 0000000000000..05575bf749a1a --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/classes/external/get_changes.php @@ -0,0 +1,104 @@ +. + +namespace tiny_collaborative\external; + +use core_external\external_api; +use core_external\external_function_parameters; +use core_external\external_single_structure; +use core_external\external_value; + +/** + * Web Service to resume an autosave session. + * + * @package tiny_autosave + * @category external + * @copyright 2022 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class get_changes extends external_api { + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function execute_parameters(): external_function_parameters { + return new external_function_parameters([ + 'contextid' => new external_value(PARAM_INT, 'The context id that owns the editor', VALUE_REQUIRED), + 'pagehash' => new external_value(PARAM_ALPHANUMEXT, 'The page hash', VALUE_REQUIRED), + 'pageinstance' => new external_value(PARAM_ALPHANUMEXT, 'The page instance', VALUE_REQUIRED), + 'elementid' => new external_value(PARAM_RAW, 'The ID of the element', VALUE_REQUIRED), + 'hash' => new external_value(PARAM_ALPHANUMEXT, 'The ID of the element', VALUE_REQUIRED), + ]); + } + + /** + * Reset the autosave entry for this autosave instance. + * + * If not matching autosave area could be found, the function will + * silently return and this is not treated as an error condition. + * + * @param int $contextid The context id of the owner + * @param string $pagehash The hash of the page + * @param string $pageinstance The instance id of the page + * @param string $elementid The id of the element + * @param int $draftid The id of the draftid to resume to + * @return null + */ + public static function execute( + int $contextid, + string $pagehash, + string $pageinstance, + string $elementid, + string $hash + ): array { + + [ + 'contextid' => $contextid, + 'pagehash' => $pagehash, + 'pageinstance' => $pageinstance, + 'elementid' => $elementid, + 'hash' => $hash, + ] = self::validate_parameters(self::execute_parameters(), [ + 'contextid' => $contextid, + 'pagehash' => $pagehash, + 'pageinstance' => $pageinstance, + 'elementid' => $elementid, + 'hash' => $hash, + ]); + + + // May have been called by a non-logged in user. + if (isloggedin() && !isguestuser()) { + $manager = new \tiny_collaborative\change_manager($contextid, $pagehash, $pageinstance, $elementid,$hash); + $changes = $manager->get_changes(); + } + return [ + 'changes' => $changes, + ]; + } + + /** + * Describe the return structure of the external service. + * + * @return external_single_structure + */ + public static function execute_returns(): external_single_structure { + return new external_single_structure([ + 'drafttext' => new external_value(PARAM_RAW, 'The draft text'), + ]); + } +} diff --git a/lib/editor/tiny/plugins/collaborative/classes/external/save_changes.php b/lib/editor/tiny/plugins/collaborative/classes/external/save_changes.php new file mode 100644 index 0000000000000..3c4c080939f91 --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/classes/external/save_changes.php @@ -0,0 +1,104 @@ +. + +namespace tiny_collaborative\external; + +use core_external\external_api; +use core_external\external_function_parameters; +use core_external\external_single_structure; +use core_external\external_value; + +/** + * + * + * @package tiny_collaborative + * @category external + * @copyright 2024 Thomas Wedekind + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class save_changes extends external_api { + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function execute_parameters(): external_function_parameters { + return new external_function_parameters([ + 'contextid' => new external_value(PARAM_INT, 'The context id that owns the editor', VALUE_REQUIRED), + 'pagehash' => new external_value(PARAM_ALPHANUMEXT, 'The page hash', VALUE_REQUIRED), + 'pageinstance' => new external_value(PARAM_ALPHANUMEXT, 'The page instance', VALUE_REQUIRED), + 'elementid' => new external_value(PARAM_RAW, 'The ID of the element', VALUE_REQUIRED), + 'oldcontenthash' => new external_value(PARAM_ALPHANUMEXT, 'The hash of the old status', VALUE_REQUIRED), + 'newcontenthash' => new external_value(PARAM_ALPHANUMEXT, 'The hash of the new status', VALUE_REQUIRED), + 'changes' => new external_value(PARAM_RAW, 'The changes done between old and new hash', VALUE_REQUIRED), + ]); + } + + /** + * + * @param int $contextid The context id of the owner + * @param string $pagehash The hash of the page + * @param string $pageinstance The instance id of the page + * @param string $elementid The id of the element + * @param string $drafttext The text to store + * @return null + */ + public static function execute( + int $contextid, + string $pagehash, + string $pageinstance, + string $elementid, + string $oldcontenthash, + string $newcontenthash, + string $changes + ): array { + + [ + 'contextid' => $contextid, + 'pagehash' => $pagehash, + 'pageinstance' => $pageinstance, + 'elementid' => $elementid, + 'oldcontenthash' => $oldcontenthash, + 'newcontenthash' => $newcontenthash, + 'changes' => $changes + ] = self::validate_parameters(self::execute_parameters(), [ + 'contextid' => $contextid, + 'pagehash' => $pagehash, + 'pageinstance' => $pageinstance, + 'elementid' => $elementid, + 'oldcontenthash' => $oldcontenthash, + 'newcontenthash' => $newcontenthash, + 'changes' => $changes + ]); + + // May have been called by a non-logged in user. + if (isloggedin() && !isguestuser()) { + $manager = new \tiny_collaborative\change_manager($contextid, $pagehash, $pageinstance, $elementid, $oldcontenthash); + $manager->add_collaborative_record($newcontenthash, $changes); + } + + return []; + } + + /** + * Describe the return structure of the external service. + * + * @return external_single_structure + */ + public static function execute_returns(): external_single_structure { + return new external_single_structure([]); + } +} diff --git a/lib/editor/tiny/plugins/collaborative/db/install.xml b/lib/editor/tiny/plugins/collaborative/db/install.xml new file mode 100644 index 0000000000000..c9b14067b2f4b --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/db/install.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + +
+
+
diff --git a/lib/editor/tiny/plugins/collaborative/db/services.php b/lib/editor/tiny/plugins/collaborative/db/services.php new file mode 100644 index 0000000000000..022f2739734bd --- /dev/null +++ b/lib/editor/tiny/plugins/collaborative/db/services.php @@ -0,0 +1,44 @@ +. + +/** + * External service definitions for tiny_collaborative + * + * @package tiny_collaborative + * @copyright 2024 Thomas Wedekind + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +$functions = [ + 'tiny_collaborate_get_changes' => array( + 'classname' => 'tiny_collaborative\external\get_changes', + 'methodname' => 'execute', + 'description' => 'Get changes based on hash', + 'type' => 'read', + 'loginrequired' => false, + 'ajax' => true, + ), + 'tiny_collaborate_save_changes' => array( + 'classname' => 'tiny_collaborative\external\save_changes', + 'methodname' => 'execute', + 'description' => 'Save changes the user made in a collaborative session', + 'type' => 'write', + 'loginrequired' => false, + 'ajax' => true, + ), +];