+ * @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;
+}
diff --git a/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php b/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php
index f9843b70337..bddbda2c960 100644
--- a/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php
+++ b/lib/editor/tiny/plugins/premium/lang/en/tiny_premium.php
@@ -25,9 +25,28 @@
defined('MOODLE_INTERNAL') || die();
-$string['pluginname'] = 'TinyMCE Premium';
$string['apikey'] = 'API key';
-$string['apikey_desc'] = 'Your API key is available on your Tiny Cloud account page if you have purchased a subscription, or if you are on a free trial.
See the list of available TinyMCE Premium features for Moodle in the documentation TinyMCE editor.
';
+$string['apikey_desc'] = 'Your API key is available on your Tiny Cloud 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 Tiny Cloud account page.';
+$string['privacy:metadata'] = 'The Tiny premium plugin for TinyMCE does not store any personal data.';
diff --git a/lib/editor/tiny/plugins/premium/pluginsettings.php b/lib/editor/tiny/plugins/premium/pluginsettings.php
new file mode 100644
index 00000000000..4111246556f
--- /dev/null
+++ b/lib/editor/tiny/plugins/premium/pluginsettings.php
@@ -0,0 +1,74 @@
+.
+
+/**
+ * TinyMCE Premium plugins configuration page.
+ *
+ * @package tiny_premium
+ * @copyright 2024 David Woloszyn
+ * @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);
diff --git a/lib/editor/tiny/plugins/premium/readme_moodle.txt b/lib/editor/tiny/plugins/premium/readme_moodle.txt
index d0afd906ebb..f175412625e 100644
--- a/lib/editor/tiny/plugins/premium/readme_moodle.txt
+++ b/lib/editor/tiny/plugins/premium/readme_moodle.txt
@@ -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).
diff --git a/lib/editor/tiny/plugins/premium/settings.php b/lib/editor/tiny/plugins/premium/settings.php
index 737ed7ceeaf..128b3debb99 100644
--- a/lib/editor/tiny/plugins/premium/settings.php
+++ b/lib/editor/tiny/plugins/premium/settings.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());
}
}
diff --git a/lib/editor/tiny/plugins/premium/tests/behat/tiny_premium_settings.feature b/lib/editor/tiny/plugins/premium/tests/behat/tiny_premium_settings.feature
new file mode 100644
index 00000000000..e60ce3aee15
--- /dev/null
+++ b/lib/editor/tiny/plugins/premium/tests/behat/tiny_premium_settings.feature
@@ -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."
diff --git a/lib/editor/tiny/plugins/premium/tests/manager_test.php b/lib/editor/tiny/plugins/premium/tests/manager_test.php
new file mode 100644
index 00000000000..bf438e4a1b6
--- /dev/null
+++ b/lib/editor/tiny/plugins/premium/tests/manager_test.php
@@ -0,0 +1,73 @@
+.
+
+namespace tiny_premium;
+
+/**
+ * Manager tests class for tiny_premium.
+ *
+ * @package tiny_premium
+ * @category test
+ * @copyright 2024 David Woloszyn
+ * @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'));
+ }
+}
diff --git a/lib/editor/tiny/plugins/premium/version.php b/lib/editor/tiny/plugins/premium/version.php
index e6caa3110eb..e7341171a24 100644
--- a/lib/editor/tiny/plugins/premium/version.php
+++ b/lib/editor/tiny/plugins/premium/version.php
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2024042200;
+$plugin->version = 2024043000;
$plugin->requires = 2024041600;
$plugin->component = 'tiny_premium';