mirror of
https://github.com/moodle/moodle.git
synced 2025-03-19 23:20:09 +01:00
MDL-80571 tiny_premium: Premium plugins can be individually enabled
This commit is contained in:
parent
792698af00
commit
ed42b2e92b
@ -1,3 +1,3 @@
|
||||
define("tiny_premium/configuration",["exports","editor_tiny/utils"],(function(_exports,_utils){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0;_exports.configure=instanceConfig=>{let plugins=instanceConfig.plugins,menu=instanceConfig.menu,toolbar=(toolbar=>(toolbar=(0,_utils.addToolbarSection)(toolbar,"premium_a","advanced",!0),(0,_utils.addToolbarSection)(toolbar,"premium_b","formatting",!0)))(instanceConfig.toolbar),contextmenu=instanceConfig.contextmenu;return plugins+=" advtable",menu=(0,_utils.addMenubarItem)(menu,"table","| advtablerownumbering","advtablesort"),plugins+=" editimage",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","editimage","tiny_media_image"),instanceConfig.editimage_toolbar="rotateleft rotateright flipv fliph editimage",plugins+=" export",menu=(0,_utils.addMenubarItem)(menu,"tools","| export"),plugins+=" pageembed",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","pageembed","tiny_media_video"),plugins+=" typography",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_b","typography"),plugins+=" casechange",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","casechange"),plugins+=" checklist",toolbar=(0,_utils.addToolbarButton)(toolbar,"lists","checklist"),plugins+=" tinymcespellchecker",menu=(0,_utils.addMenubarItem)(menu,"tools","spellcheckdialog","spellcheckerlanguage"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"spellchecker"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","spellcheckdialog"),plugins+=" autocorrect",menu=(0,_utils.addMenubarItem)(menu,"tools","| autocorrect capitalization","spellcheckdialog"),plugins+=" permanentpen",menu=(0,_utils.addMenubarItem)(menu,"format","| permanentpen configurepermanentpen"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","permanentpen"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"configurepermanentpen"),plugins+=" formatpainter",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","formatpainter"),plugins+=" linkchecker",contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"linkchecker"),plugins+=" tableofcontents",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","tableofcontents"),plugins+=" footnotes",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","footnotes"),menu=(0,_utils.addMenubarItem)(menu,"insert","footnotes","tableofcontents"),plugins+=" powerpaste",{plugins:plugins,toolbar:toolbar,menu:menu,contextmenu:contextmenu}}}));
|
||||
define("tiny_premium/configuration",["exports","editor_tiny/utils","editor_tiny/options"],(function(_exports,_utils,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0;_exports.configure=(instanceConfig,options)=>{const enabledPremiumPlugins=(0,_options.getInitialPluginConfiguration)(options)[(0,_options.getPluginOptionName)("tiny_premium/plugin","premiumplugins")].split(",");let plugins=instanceConfig.plugins,menu=instanceConfig.menu,toolbar=(toolbar=>(toolbar=(0,_utils.addToolbarSection)(toolbar,"premium_a","advanced",!0),(0,_utils.addToolbarSection)(toolbar,"premium_b","formatting",!0)))(instanceConfig.toolbar),contextmenu=instanceConfig.contextmenu;return-1!==enabledPremiumPlugins.indexOf("advtable")&&(plugins+=" advtable",menu=(0,_utils.addMenubarItem)(menu,"table","| advtablerownumbering","advtablesort")),-1!==enabledPremiumPlugins.indexOf("editimage")&&(plugins+=" editimage",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","editimage","tiny_media_image"),instanceConfig.editimage_toolbar="rotateleft rotateright flipv fliph editimage"),-1!==enabledPremiumPlugins.indexOf("export")&&(plugins+=" export",menu=(0,_utils.addMenubarItem)(menu,"tools","| export")),-1!==enabledPremiumPlugins.indexOf("pageembed")&&(plugins+=" pageembed",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","pageembed","tiny_media_video")),-1!==enabledPremiumPlugins.indexOf("typography")&&(plugins+=" typography",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_b","typography")),-1!==enabledPremiumPlugins.indexOf("casechange")&&(plugins+=" casechange",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","casechange")),-1!==enabledPremiumPlugins.indexOf("checklist")&&(plugins+=" checklist",toolbar=(0,_utils.addToolbarButton)(toolbar,"lists","checklist")),-1!==enabledPremiumPlugins.indexOf("tinymcespellchecker")&&(plugins+=" tinymcespellchecker",menu=(0,_utils.addMenubarItem)(menu,"tools","spellcheckdialog","spellcheckerlanguage"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"spellchecker"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","spellcheckdialog")),-1!==enabledPremiumPlugins.indexOf("autocorrect")&&(plugins+=" autocorrect",menu=(0,_utils.addMenubarItem)(menu,"tools","| autocorrect capitalization","spellcheckdialog")),-1!==enabledPremiumPlugins.indexOf("permanentpen")&&(plugins+=" permanentpen",menu=(0,_utils.addMenubarItem)(menu,"format","| permanentpen configurepermanentpen"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","permanentpen"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"configurepermanentpen")),-1!==enabledPremiumPlugins.indexOf("formatpainter")&&(plugins+=" formatpainter",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","formatpainter")),-1!==enabledPremiumPlugins.indexOf("linkchecker")&&(plugins+=" linkchecker",contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"linkchecker")),-1!==enabledPremiumPlugins.indexOf("tableofcontents")&&(plugins+=" tableofcontents",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","tableofcontents")),-1!==enabledPremiumPlugins.indexOf("footnotes")&&(plugins+=" footnotes",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","footnotes"),menu=(0,_utils.addMenubarItem)(menu,"insert","footnotes","tableofcontents")),-1!==enabledPremiumPlugins.indexOf("powerpaste")&&(plugins+=" powerpaste"),{plugins:plugins,toolbar:toolbar,menu:menu,contextmenu:contextmenu}}}));
|
||||
|
||||
//# sourceMappingURL=configuration.min.js.map
|
File diff suppressed because one or more lines are too long
@ -27,6 +27,10 @@ import {
|
||||
addToolbarSection,
|
||||
addContextmenuItem
|
||||
} from 'editor_tiny/utils';
|
||||
import {
|
||||
getInitialPluginConfiguration,
|
||||
getPluginOptionName
|
||||
} from 'editor_tiny/options';
|
||||
|
||||
const configureToolbar = (toolbar) => {
|
||||
// Add premium toolbar sections to house all the plugins with no natural home.
|
||||
@ -35,9 +39,12 @@ const configureToolbar = (toolbar) => {
|
||||
return toolbar;
|
||||
};
|
||||
|
||||
export const configure = (instanceConfig) => {
|
||||
// There is some manipulating of the plugin menu, toolbar, context and quickbar items.
|
||||
// This was necessary to enhance user experience and closer align to the Tiny demo site.
|
||||
export const configure = (instanceConfig, options) => {
|
||||
// Get the namespaced options for Tiny Premium before they are officially initialised.
|
||||
// Due to the timing the plugin options are available, we need to get at the options in this slightly unconventional way.
|
||||
const pluginOptions = getInitialPluginConfiguration(options);
|
||||
const enabledPremiumPlugins = pluginOptions[getPluginOptionName('tiny_premium/plugin', 'premiumplugins')].split(',');
|
||||
|
||||
let plugins = instanceConfig.plugins;
|
||||
let menu = instanceConfig.menu;
|
||||
let toolbar = configureToolbar(instanceConfig.toolbar);
|
||||
@ -45,71 +52,87 @@ export const configure = (instanceConfig) => {
|
||||
let pluginsettings = {};
|
||||
|
||||
// Advanced Table.
|
||||
plugins += ` advtable`;
|
||||
menu = addMenubarItem(menu, 'table', '| advtablerownumbering', 'advtablesort');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('advtable') !== -1) {
|
||||
plugins += ` advtable`;
|
||||
menu = addMenubarItem(menu, 'table', '| advtablerownumbering', 'advtablesort');
|
||||
}
|
||||
// Enhanced Image Editing.
|
||||
plugins += ` editimage`;
|
||||
toolbar = addToolbarButton(toolbar, 'content', 'editimage', 'tiny_media_image');
|
||||
// Remove the duplicate image button from the quickbar toolbar by redefining the values without 'imageoptions'.
|
||||
// eslint-disable-next-line camelcase
|
||||
instanceConfig.editimage_toolbar = 'rotateleft rotateright flipv fliph editimage';
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('editimage') !== -1) {
|
||||
plugins += ` editimage`;
|
||||
toolbar = addToolbarButton(toolbar, 'content', 'editimage', 'tiny_media_image');
|
||||
// Remove the duplicate image button from the quickbar toolbar by redefining the values without 'imageoptions'.
|
||||
// eslint-disable-next-line camelcase
|
||||
instanceConfig.editimage_toolbar = 'rotateleft rotateright flipv fliph editimage';
|
||||
}
|
||||
// Export.
|
||||
plugins += ` export`;
|
||||
menu = addMenubarItem(menu, 'tools', '| export');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('export') !== -1) {
|
||||
plugins += ` export`;
|
||||
menu = addMenubarItem(menu, 'tools', '| export');
|
||||
}
|
||||
// Page Embed.
|
||||
plugins += ` pageembed`;
|
||||
toolbar = addToolbarButton(toolbar, 'content', 'pageembed', 'tiny_media_video');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('pageembed') !== -1) {
|
||||
plugins += ` pageembed`;
|
||||
toolbar = addToolbarButton(toolbar, 'content', 'pageembed', 'tiny_media_video');
|
||||
}
|
||||
// Advanced Typography.
|
||||
plugins += ` typography`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_b', 'typography');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('typography') !== -1) {
|
||||
plugins += ` typography`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_b', 'typography');
|
||||
}
|
||||
// Case Change.
|
||||
plugins += ` casechange`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'casechange');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('casechange') !== -1) {
|
||||
plugins += ` casechange`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'casechange');
|
||||
}
|
||||
// Checklist.
|
||||
plugins += ` checklist`;
|
||||
toolbar = addToolbarButton(toolbar, 'lists', 'checklist');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('checklist') !== -1) {
|
||||
plugins += ` checklist`;
|
||||
toolbar = addToolbarButton(toolbar, 'lists', 'checklist');
|
||||
}
|
||||
// Spell Checker Pro.
|
||||
plugins += ` tinymcespellchecker`;
|
||||
menu = addMenubarItem(menu, 'tools', 'spellcheckdialog', 'spellcheckerlanguage');
|
||||
contextmenu = addContextmenuItem(contextmenu, 'spellchecker');
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'spellcheckdialog');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('tinymcespellchecker') !== -1) {
|
||||
plugins += ` tinymcespellchecker`;
|
||||
menu = addMenubarItem(menu, 'tools', 'spellcheckdialog', 'spellcheckerlanguage');
|
||||
contextmenu = addContextmenuItem(contextmenu, 'spellchecker');
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'spellcheckdialog');
|
||||
}
|
||||
// Spelling Autocorrect.
|
||||
plugins += ` autocorrect`;
|
||||
menu = addMenubarItem(menu, 'tools', '| autocorrect capitalization', 'spellcheckdialog');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('autocorrect') !== -1) {
|
||||
plugins += ` autocorrect`;
|
||||
menu = addMenubarItem(menu, 'tools', '| autocorrect capitalization', 'spellcheckdialog');
|
||||
}
|
||||
// Permanent Pen.
|
||||
plugins += ` permanentpen`;
|
||||
menu = addMenubarItem(menu, 'format', '| permanentpen configurepermanentpen');
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'permanentpen');
|
||||
contextmenu = addContextmenuItem(contextmenu, 'configurepermanentpen');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('permanentpen') !== -1) {
|
||||
plugins += ` permanentpen`;
|
||||
menu = addMenubarItem(menu, 'format', '| permanentpen configurepermanentpen');
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'permanentpen');
|
||||
contextmenu = addContextmenuItem(contextmenu, 'configurepermanentpen');
|
||||
}
|
||||
// Format Painter.
|
||||
plugins += ` formatpainter`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'formatpainter');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('formatpainter') !== -1) {
|
||||
plugins += ` formatpainter`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'formatpainter');
|
||||
}
|
||||
// Link Checker.
|
||||
plugins += ` linkchecker`;
|
||||
contextmenu = addContextmenuItem(contextmenu, 'linkchecker');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('linkchecker') !== -1) {
|
||||
plugins += ` linkchecker`;
|
||||
contextmenu = addContextmenuItem(contextmenu, 'linkchecker');
|
||||
}
|
||||
// Table of Contents.
|
||||
plugins += ` tableofcontents`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'tableofcontents');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('tableofcontents') !== -1) {
|
||||
plugins += ` tableofcontents`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'tableofcontents');
|
||||
}
|
||||
// Footnotes.
|
||||
plugins += ` footnotes`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'footnotes');
|
||||
menu = addMenubarItem(menu, 'insert', 'footnotes', 'tableofcontents');
|
||||
|
||||
if (enabledPremiumPlugins.indexOf('footnotes') !== -1) {
|
||||
plugins += ` footnotes`;
|
||||
toolbar = addToolbarButton(toolbar, 'premium_a', 'footnotes');
|
||||
menu = addMenubarItem(menu, 'insert', 'footnotes', 'tableofcontents');
|
||||
}
|
||||
// Powerpaste.
|
||||
plugins += ` powerpaste`;
|
||||
if (enabledPremiumPlugins.indexOf('powerpaste') !== -1) {
|
||||
plugins += ` powerpaste`;
|
||||
}
|
||||
|
||||
return {
|
||||
plugins,
|
||||
|
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tiny_premium\local;
|
||||
|
||||
use tiny_premium\manager;
|
||||
|
||||
/**
|
||||
* Admin setting for managing Tiny Premium plugins.
|
||||
*
|
||||
* @package tiny_premium
|
||||
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class admin_setting_tiny_premium_plugins extends \admin_setting {
|
||||
|
||||
/**
|
||||
* Calls parent::__construct with specific arguments.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->nosave = true;
|
||||
parent::__construct(
|
||||
name: 'tiny_premium/premiumplugins',
|
||||
visiblename: new \lang_string('premiumplugins', 'tiny_premium'),
|
||||
description: new \lang_string('premiumplugins_desc', 'tiny_premium'),
|
||||
defaultsetting: '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns true.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_setting(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns '' and doesn't write anything.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string Always returns ''
|
||||
*/
|
||||
public function write_setting($data): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the HTML to display the Tiny Premium plugins table.
|
||||
*
|
||||
* @param mixed $data Unused
|
||||
* @param string $query
|
||||
* @return string highlight
|
||||
*/
|
||||
public function output_html($data, $query=''): string {
|
||||
global $OUTPUT;
|
||||
|
||||
$return = '';
|
||||
|
||||
// Warn users about an empty API key when displaying enabled plugins.
|
||||
if (empty(get_config('tiny_premium', 'apikey')) && !empty(manager::get_enabled_plugins())) {
|
||||
$return .= \core\notification::warning(get_string('emptyapikeywarning', 'tiny_premium'));
|
||||
}
|
||||
|
||||
$return .= $OUTPUT->box_start('generalbox');
|
||||
$return .= $OUTPUT->heading(get_string('premiumplugins', 'tiny_premium'), 3);
|
||||
$return .= \html_writer::tag('p', get_string('premiumplugins_desc', 'tiny_premium'));
|
||||
$return .= $this->define_manage_tiny_premium_plugins_table();
|
||||
$return .= $OUTPUT->box_end();
|
||||
|
||||
return highlight($query, $return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines table for managing Tiny Premium plugins.
|
||||
*
|
||||
* @return string HTML for table
|
||||
*/
|
||||
public function define_manage_tiny_premium_plugins_table(): string {
|
||||
global $OUTPUT;
|
||||
$sesskey = sesskey();
|
||||
|
||||
// Set up table.
|
||||
$table = new \html_table();
|
||||
$table->id = 'managetinypremiumpluginstable';
|
||||
$table->attributes['class'] = 'admintable generaltable';
|
||||
$table->head = [
|
||||
get_string('name'),
|
||||
get_string('enable'),
|
||||
];
|
||||
$table->colclasses = [
|
||||
'leftalign',
|
||||
'centeralign',
|
||||
];
|
||||
$table->data = [];
|
||||
|
||||
// Keep enabled plugins on top.
|
||||
$plugins = manager::get_plugins();
|
||||
$enabledplugins = manager::get_enabled_plugins();
|
||||
$disabledplugins = array_diff($plugins, $enabledplugins);
|
||||
$plugins = array_merge($enabledplugins, $disabledplugins);
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
|
||||
$pluginname = get_string('premiumplugin:' . $plugin, 'tiny_premium');
|
||||
|
||||
// Determine plugin actions.
|
||||
if (manager::is_plugin_enabled($plugin)) {
|
||||
$action = 'disable';
|
||||
$icon = $OUTPUT->pix_icon('t/hide', get_string('disableplugin', 'core_admin', $pluginname));
|
||||
$class = '';
|
||||
} else {
|
||||
$action = 'enable';
|
||||
$icon = $OUTPUT->pix_icon('t/show', get_string('enableplugin', 'core_admin', $pluginname));
|
||||
$class = 'dimmed_text';
|
||||
}
|
||||
|
||||
// Prepare a link to perform the action.
|
||||
$hideshowurl = new \moodle_url('/lib/editor/tiny/plugins/premium/pluginsettings.php', [
|
||||
'action' => $action,
|
||||
'plugin' => $plugin,
|
||||
'sesskey' => $sesskey,
|
||||
]);
|
||||
$hideshowlink = \html_writer::link($hideshowurl, $icon);
|
||||
|
||||
// Populate table row.
|
||||
$row = new \html_table_row([
|
||||
$pluginname,
|
||||
$hideshowlink,
|
||||
]);
|
||||
$row->attributes['class'] = $class;
|
||||
$table->data[] = $row;
|
||||
}
|
||||
|
||||
return \html_writer::table($table);
|
||||
}
|
||||
}
|
109
lib/editor/tiny/plugins/premium/classes/manager.php
Normal file
109
lib/editor/tiny/plugins/premium/classes/manager.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tiny_premium;
|
||||
|
||||
/**
|
||||
* Tiny Premium manager.
|
||||
*
|
||||
* @package tiny_premium
|
||||
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class manager {
|
||||
|
||||
/**
|
||||
* Get all Tiny Premium plugins currently supported.
|
||||
*
|
||||
* The plugin identifiers are taken from Tiny Cloud (https://www.tiny.cloud/docs/tinymce/6/plugins/#premium-plugins).
|
||||
*
|
||||
* @return array The array of plugins.
|
||||
*/
|
||||
public static function get_plugins(): array {
|
||||
return [
|
||||
'advtable',
|
||||
'typography',
|
||||
'casechange',
|
||||
'checklist',
|
||||
'editimage',
|
||||
'export',
|
||||
'footnotes',
|
||||
'formatpainter',
|
||||
'linkchecker',
|
||||
'pageembed',
|
||||
'permanentpen',
|
||||
'powerpaste',
|
||||
'tinymcespellchecker',
|
||||
'autocorrect',
|
||||
'tableofcontents',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enabled Tiny Premium plugins.
|
||||
*
|
||||
* @return array The array of enabled plugins.
|
||||
*/
|
||||
public static function get_enabled_plugins(): array {
|
||||
$plugins = self::get_plugins();
|
||||
$enabledplugins = [];
|
||||
foreach ($plugins as $plugin) {
|
||||
if (self::is_plugin_enabled($plugin)) {
|
||||
$enabledplugins[] = $plugin;
|
||||
}
|
||||
}
|
||||
return $enabledplugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Tiny Premium plugin is enabled in config.
|
||||
*
|
||||
* @param string $plugin The plugin to check.
|
||||
* @return bool Return true if enabled.
|
||||
*/
|
||||
public static function is_plugin_enabled(string $plugin): bool {
|
||||
$config = get_config('tiny_premium_' . $plugin, 'enabled');
|
||||
return ($config == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new value for a Tiny Premium plugin config.
|
||||
*
|
||||
* @param array $data The data to set.
|
||||
* @param string $plugin The plugin to use.
|
||||
*/
|
||||
public static function set_plugin_config(array $data, string $plugin): void {
|
||||
// Check this is a valid premium plugin.
|
||||
if (!in_array($plugin, self::get_plugins())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin = 'tiny_premium_' . $plugin;
|
||||
|
||||
foreach ($data as $key => $newvalue) {
|
||||
// Get the old value for the log.
|
||||
$oldvalue = get_config($plugin, $key) ?? null;
|
||||
add_to_config_log($key, $oldvalue, $newvalue, $plugin);
|
||||
|
||||
// If we are disabling the plugin, remove it, otherwise, set the new value.
|
||||
if ($key === 'enabled' && $newvalue == 0) {
|
||||
unset_config($key, $plugin);
|
||||
} else {
|
||||
set_config($key, $newvalue, $plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ namespace tiny_premium;
|
||||
use context;
|
||||
use editor_tiny\editor;
|
||||
use editor_tiny\plugin;
|
||||
use editor_tiny\plugin_with_configuration;
|
||||
use tiny_premium\manager;
|
||||
|
||||
/**
|
||||
* Tiny Premium plugin.
|
||||
@ -27,7 +29,7 @@ use editor_tiny\plugin;
|
||||
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plugininfo extends plugin {
|
||||
class plugininfo extends plugin implements plugin_with_configuration {
|
||||
|
||||
/**
|
||||
* Determine if the plugin should be enabled by checking the capability and if the Tiny Premium API key is set.
|
||||
@ -46,4 +48,24 @@ class plugininfo extends plugin {
|
||||
): bool {
|
||||
return has_capability('tiny/premium:accesspremium', $context) && (get_config('tiny_premium', 'apikey') != false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of enabled Tiny Premium plugins set by the admin.
|
||||
*
|
||||
* @param context $context The context that the editor is used within
|
||||
* @param array $options The options passed in when requesting the editor
|
||||
* @param array $fpoptions The filepicker options passed in when requesting the editor
|
||||
* @param editor|null $editor The editor instance in which the plugin is initialised
|
||||
* @return array
|
||||
*/
|
||||
public static function get_plugin_configuration_for_context(
|
||||
context $context,
|
||||
array $options,
|
||||
array $fpoptions,
|
||||
?editor $editor = null
|
||||
): array {
|
||||
return [
|
||||
'premiumplugins' => implode(',', manager::get_enabled_plugins()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
55
lib/editor/tiny/plugins/premium/db/upgrade.php
Normal file
55
lib/editor/tiny/plugins/premium/db/upgrade.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
/**
|
||||
* Upgrade code for tiny_premium.
|
||||
*
|
||||
* @package tiny_premium
|
||||
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to upgrade tiny_premium.
|
||||
*
|
||||
* @param int $oldversion the version we are upgrading from
|
||||
* @return bool result
|
||||
*/
|
||||
function xmldb_tiny_premium_upgrade($oldversion) {
|
||||
// Automatically generated Moodle v4.1.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.2.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Automatically generated Moodle v4.3.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
if ($oldversion < 2024042400) {
|
||||
|
||||
// Only enable the premium plugins if we have an API key.
|
||||
if (!empty(get_config('tiny_premium', 'apikey'))) {
|
||||
$premiumplugins = \tiny_premium\manager::get_plugins();
|
||||
foreach ($premiumplugins as $plugin) {
|
||||
\tiny_premium\manager::set_plugin_config(['enabled' => 1], $plugin);
|
||||
};
|
||||
}
|
||||
|
||||
upgrade_plugin_savepoint(true, 2024042400, 'tiny', 'premium');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -25,9 +25,28 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['pluginname'] = 'TinyMCE Premium';
|
||||
$string['apikey'] = 'API key';
|
||||
$string['apikey_desc'] = '<p>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.</p><p>See the list of available TinyMCE Premium features for Moodle in the documentation <a href="https://docs.moodle.org/en/TinyMCE_editor">TinyMCE editor</a>.</p>';
|
||||
$string['apikey_desc'] = 'Your API key is available on your <a target="_blank" 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['helplinktext'] = 'Premium plugins';
|
||||
$string['pluginname'] = 'TinyMCE Premium';
|
||||
$string['pluginnotfound'] = 'Tiny Premium plugin {$a} not found.';
|
||||
$string['premium:accesspremium'] = 'Access TinyMCE Premium features';
|
||||
$string['privacy:metadata'] = 'The TinyMCE Premium plugin does not store any personal data.';
|
||||
$string['premiumplugin:advtable'] = 'Advanced Table';
|
||||
$string['premiumplugin:autocorrect'] = 'Spelling Autocorrect';
|
||||
$string['premiumplugin:casechange'] = 'Case Change';
|
||||
$string['premiumplugin:checklist'] = 'Checklist';
|
||||
$string['premiumplugin:editimage'] = 'Enhanced Image Editing';
|
||||
$string['premiumplugin:export'] = 'Export';
|
||||
$string['premiumplugin:footnotes'] = 'Footnotes';
|
||||
$string['premiumplugin:formatpainter'] = 'Format Painter';
|
||||
$string['premiumplugin:linkchecker'] = 'Link Checker';
|
||||
$string['premiumplugin:pageembed'] = 'Page Embed';
|
||||
$string['premiumplugin:permanentpen'] = 'Permanent Pen';
|
||||
$string['premiumplugin:powerpaste'] = 'Powerpaste';
|
||||
$string['premiumplugin:tableofcontents'] = 'Table of Contents';
|
||||
$string['premiumplugin:tinymcespellchecker'] = 'Spell Checker Pro';
|
||||
$string['premiumplugin:typography'] = 'Advanced Typography';
|
||||
$string['premiumplugins'] = 'Premium plugins';
|
||||
$string['premiumplugins_desc'] = 'Access to TinyMCE Premium plugins requires an API key. Not all listed plugins may be available with your TinyMCE Premium subscription. You can check available plugins on your <a target="_blank" href="https://www.tiny.cloud/my-account/integrate/">Tiny Cloud</a> account page.';
|
||||
$string['privacy:metadata'] = 'The Tiny premium plugin for TinyMCE does not store any personal data.';
|
||||
|
74
lib/editor/tiny/plugins/premium/pluginsettings.php
Normal file
74
lib/editor/tiny/plugins/premium/pluginsettings.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* TinyMCE Premium plugins configuration page.
|
||||
*
|
||||
* @package tiny_premium
|
||||
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ALPHANUMEXT);
|
||||
$plugin = required_param('plugin', PARAM_ALPHANUMEXT);
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$PAGE->set_url('/lib/editor/tiny/plugins/premium/pluginsettings.php');
|
||||
$PAGE->set_context($syscontext);
|
||||
|
||||
require_admin();
|
||||
require_sesskey();
|
||||
|
||||
$return = new moodle_url('/admin/settings.php', ['section' => 'tiny_premium_settings']);
|
||||
|
||||
// Get all Tiny Premium plugins.
|
||||
$premiumplugins = \tiny_premium\manager::get_plugins();
|
||||
if (!in_array($plugin, $premiumplugins)) {
|
||||
throw new moodle_exception('pluginnotfound', 'tiny_premium', $return, $plugin);
|
||||
}
|
||||
|
||||
// Get enabled Tiny Premium plugins.
|
||||
$enabledplugins = \tiny_premium\manager::get_enabled_plugins();
|
||||
$pluginname = get_string('premiumplugin:' . $plugin, 'tiny_premium');
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
if (in_array($plugin, $enabledplugins)) {
|
||||
\tiny_premium\manager::set_plugin_config(['enabled' => 0], $plugin);
|
||||
|
||||
\core\notification::add(
|
||||
get_string('plugin_disabled', 'core_admin', $pluginname),
|
||||
\core\notification::SUCCESS
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'enable':
|
||||
if (!in_array($plugin, $enabledplugins)) {
|
||||
\tiny_premium\manager::set_plugin_config(['enabled' => 1], $plugin);
|
||||
|
||||
\core\notification::add(
|
||||
get_string('plugin_enabled', 'core_admin', $pluginname),
|
||||
\core\notification::SUCCESS
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
redirect($return);
|
@ -4,9 +4,12 @@ A request to Tiny Cloud is made in the plugin.js file of this plugin.
|
||||
This request passes the Tiny Premium API key as part of a URL.
|
||||
The URL also contains the major version of Tiny and may need to be updated.
|
||||
|
||||
The URL looks like this: https://cdn.tiny.cloud/1/YOUR_API_KEY/tinymce/6/plugins.min.js
|
||||
|
||||
Notice that the version (6) is baked into the URL and may need revision.
|
||||
The URL looks like this: https://cdn.tiny.cloud/1/YOUR_API_KEY/tinymce/VERSION/plugins.min.js
|
||||
|
||||
When upgrading, check Tiny Cloud's documentation regarding the correct API URL
|
||||
to use. Go to https://www.tiny.cloud/docs/tinymce
|
||||
|
||||
TinyMCE Premium plugins can be individually enabled/disabled by admins.
|
||||
Each release of TinyMCE may have a different selection of plugins available.
|
||||
When upgrading, please check the list of available TinyMCE Premium plugins and update the list
|
||||
with the revisions (lib/editor/tiny/plugins/premium/classes/manager.php).
|
||||
|
@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
if ($hassiteconfig) {
|
||||
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
|
||||
if ($ADMIN->fulltree) {
|
||||
// Set API key.
|
||||
$setting = new admin_setting_configpasswordunmask(
|
||||
'tiny_premium/apikey',
|
||||
get_string('apikey', 'tiny_premium'),
|
||||
@ -35,5 +36,8 @@ if ($hassiteconfig) {
|
||||
'',
|
||||
);
|
||||
$settings->add($setting);
|
||||
|
||||
// Set individual Tiny Premium plugins.
|
||||
$settings->add(new \tiny_premium\local\admin_setting_tiny_premium_plugins());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
@editor @editor_tiny
|
||||
Feature: Check the features of the TinyMCE Premium settings
|
||||
In order to use TinyMCE Premium features
|
||||
As an admin
|
||||
I need TinyMCE Premium settings to be configured correctly
|
||||
|
||||
Background:
|
||||
Given I am logged in as "admin"
|
||||
And I navigate to "Plugins > Text editors > TinyMCE editor > TinyMCE Premium" in site administration
|
||||
|
||||
@javascript
|
||||
Scenario: I can see a warning banner when I enable a TinyMCE premium plugin without an API key set
|
||||
When I click on "Enable Advanced Table" "link"
|
||||
Then I should see "Advanced Table enabled."
|
||||
And I should see "Enabled TinyMCE Premium plugins will not be available until an API key is added."
|
||||
|
||||
@javascript
|
||||
Scenario: I cannot see a warning banner when I enable a TinyMCE premium plugin with an API key set
|
||||
Given the following config values are set as admin:
|
||||
| apikey | "123456" | tiny_premium |
|
||||
When I click on "Enable Advanced Table" "link"
|
||||
Then I should see "Advanced Table enabled."
|
||||
And I should not see "Enabled TinyMCE Premium plugins will not be available until an API key is added."
|
73
lib/editor/tiny/plugins/premium/tests/manager_test.php
Normal file
73
lib/editor/tiny/plugins/premium/tests/manager_test.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tiny_premium;
|
||||
|
||||
/**
|
||||
* Manager tests class for tiny_premium.
|
||||
*
|
||||
* @package tiny_premium
|
||||
* @category test
|
||||
* @copyright 2024 David Woloszyn <david.woloszyn@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class manager_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test the getting of all available Tiny Premium plugins.
|
||||
*
|
||||
* @covers \tiny_premium\manager
|
||||
*/
|
||||
public function test_get_plugins(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// Check all Tiny Premium plugins are returned.
|
||||
$premiumplugins = manager::get_plugins();
|
||||
$this->assertCount(15, $premiumplugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the getting and setting of enabled Tiny Premium plugins.
|
||||
*
|
||||
* @covers \tiny_premium\manager
|
||||
*/
|
||||
public function test_get_and_set_enabled_plugins(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// Check all enabled Tiny Premium plugins are returned (all disabled by default).
|
||||
$enabledpremiumplugins = manager::get_enabled_plugins();
|
||||
$this->assertCount(0, $enabledpremiumplugins);
|
||||
|
||||
// Enable a couple premium plugins.
|
||||
manager::set_plugin_config(['enabled' => 1], 'advtable');
|
||||
manager::set_plugin_config(['enabled' => 1], 'formatpainter');
|
||||
// Check the premium plugins are enabled.
|
||||
$enabledpremiumplugins = manager::get_enabled_plugins();
|
||||
$this->assertCount(2, $enabledpremiumplugins);
|
||||
$this->assertTrue(manager::is_plugin_enabled('advtable'));
|
||||
$this->assertTrue(manager::is_plugin_enabled('formatpainter'));
|
||||
|
||||
// Disable a premium plugin.
|
||||
manager::set_plugin_config(['enabled' => 0], 'advtable');
|
||||
// Check the correct premium plugins are enabled.
|
||||
$enabledpremiumplugins = manager::get_enabled_plugins();
|
||||
$this->assertCount(1, $enabledpremiumplugins);
|
||||
$this->assertFalse(manager::is_plugin_enabled('advtable'));
|
||||
$this->assertTrue(manager::is_plugin_enabled('formatpainter'));
|
||||
}
|
||||
}
|
@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2024042200;
|
||||
$plugin->version = 2024043000;
|
||||
$plugin->requires = 2024041600;
|
||||
$plugin->component = 'tiny_premium';
|
||||
|
Loading…
x
Reference in New Issue
Block a user