This commit is contained in:
Andrew Nicols
2025-03-05 14:03:12 +08:00
46 changed files with 749 additions and 63 deletions
+2
View File
@@ -61,6 +61,8 @@ class manager {
continue;
}
$options['pluginname'] = $pluginname;
if (!$classname::is_enabled($context, $options, $fpoptions, $editor)) {
// This plugin has disabled itself for some reason.
// This is typical for media plugins where there is no file storage.
+13 -2
View File
@@ -34,7 +34,7 @@ use context;
*/
abstract class plugin {
/**
* Whether the plugin is enabled
* Whether the plugin is enabled and accessible (e.g. capability checks).
*
* @param context $context The context that the editor is used within
* @param array $options The options passed in when requesting the editor
@@ -48,7 +48,18 @@ abstract class plugin {
array $fpoptions,
?editor $editor = null
): bool {
return true;
$plugin = $options['pluginname'];
$capability = "tiny/$plugin:use";
if (!get_capability_info($capability)) {
// Debug warning that the capability does not exist.
debugging(
'The tiny ' . $plugin . ' plugin does not define the standard capability ' . $capability ,
DEBUG_DEVELOPER
);
return true;
}
return has_capability($capability, $context);
}
/**
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_accessibilitychecker plugin.
*
* @package tiny_accessibilitychecker
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/accessibilitychecker:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -22,6 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['accessibilitychecker:use'] = 'Use TinyMCE accessibility checker';
$string['emptytext'] = 'Empty text';
$string['entiredocument'] = 'Entire document';
$string['imagesmissingalt'] = 'Images require alternative text. To fix this warning, add an alt attribute to your img tags. An empty alt attribute may be used, but only when the image is purely decorative and carries no information.';
@@ -52,3 +52,39 @@ Feature: Tiny editor accessibility checker
When I set the field "Description" to "<p>Some plain text</p><img src='/broken-image' width='1' height='1' class='behat-tinymce-placeholder'/><p>Some more text</p>"
And I click on the "Tools > Accessibility checker" menu item for the "Description" TinyMCE editor
Then I should see "Congratulations, no accessibility issues found!" in the "Accessibility checker" "dialogue"
@javascript
Scenario: Permissions can be configured to control access to accessibility checker
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/accessibilitychecker:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Tools" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "Accessibility checker"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Tools" menu item for the "Activity instructions" TinyMCE editor
And I should see "Accessibility checker"
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_accessibilitychecker';
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_autosave plugin.
*
* @package tiny_autosave
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/autosave:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -22,6 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['autosave:use'] = 'Use TinyMCE autosave';
$string['pluginname'] = 'Autosave';
$string['privacy:metadata:database:tiny_autosave:userid'] = 'The user ID of the user who created the autosave session';
$string['privacy:metadata:database:tiny_autosave:drafttext'] = 'The text content of the autosave session';
@@ -78,3 +78,42 @@ Feature: Tiny editor autosave
And I click on "New event" "button"
When I click on "Show more..." "link" in the "New event" "dialogue"
Then the field "Description" matches value ""
@javascript
Scenario: Permissions can be configured to control access to autosave
Given the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher3 | Teacher | 3 | teacher3@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher3 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/autosave:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher3"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I set the field "Activity instructions" to "This is my draft"
And I log out
And I log in as "teacher3"
And I am on the "Test assignment" Activity page
When I navigate to "Settings" in current page administration
Then the field "Activity instructions" matches value ""
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I set the field "Activity instructions" to "This is my draft"
And I log out
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And the field "Activity instructions" matches value "This is my draft"
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_autosave';
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_equation plugin.
*
* @package tiny_equation
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/equation:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -25,6 +25,7 @@
$string['buttontitle'] = 'Equation editor';
$string['cursorinfo'] = 'An arrow indicates the position that new elements from the element library will be inserted.';
$string['editequation'] = 'Edit equation using <a href="{$a}" target="_blank">TeX</a>';
$string['equation:use'] = 'Use TinyMCE equation editor';
$string['librarygroup1'] = 'Operators';
$string['librarygroup1_desc'] = 'TeX commands listed on the operators tab.';
$string['librarygroup2'] = 'Arrows';
@@ -34,3 +34,39 @@ Feature: Equation editor
Then the field "Edit equation using" matches value " \pi "
And I click on "Save equation" "button"
And the field "Description" matches value "<p>\( \pi \)</p>"
@javascript
Scenario: Permissions can be configured to control access to equation editor
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/equation:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "Equation editor"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
And I should see "Equation editor"
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_equation';
@@ -34,16 +34,6 @@ class plugininfo extends plugin implements
plugin_with_menuitems,
plugin_with_configuration {
public static function is_enabled(
context $context,
array $options,
array $fpoptions,
?\editor_tiny\editor $editor = null
): bool {
// Users must have permission to embed content.
return has_capability('tiny/h5p:addembed', $context);
}
public static function get_available_buttons(): array {
return [
'tiny_h5p/h5p',
@@ -32,5 +32,12 @@ $capabilities = [
'editingteacher' => CAP_ALLOW,
],
'clonepermissionsfrom' => 'atto/h5p:addembed',
],
'tiny/h5p:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
],
]
];
@@ -32,6 +32,7 @@ $string['displayoptions'] = 'Display options';
$string['downloadbutton'] = 'Allow download';
$string['embedbutton'] = 'Embed button';
$string['h5p:addembed'] = 'Add embedded H5P';
$string['h5p:use'] = 'Use TinyMCE H5P';
$string['h5pfile'] = 'H5P file upload';
$string['h5pfileorurl'] = 'H5P URL or file upload';
$string['h5poptions'] = 'H5P options';
@@ -50,12 +50,35 @@ Feature: Use the TinyMCE editor to upload an h5p package
Then ".h5p-placeholder" "css_element" should exist
@javascript
Scenario: When a user does not have any H5P capabilities, they cannot embed H5P content with TinyMCE
Given the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/h5p:addembed | Prohibit | editingteacher | Course | C1 |
When I am on the PageName1 "page activity editing" page logged in as teacher1
Then "Insert H5P content" "button" should not exist
Scenario: Permissions can be configured to control access to H5P
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/h5p:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "Insert H5P content"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
And I should see "Insert H5P content"
@javascript
Scenario: When a user does not have the Upload H5P capability, they can embed but not upload H5P content with TinyMCE
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025021700;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_h5p';
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_html plugin.
*
* @package tiny_html
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/html:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -25,6 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$string['html:use'] = 'Use TinyMCE HTML';
$string['pluginname'] = 'HTML';
$string['privacy:metadata'] = 'The HTML formatter plugin for TinyMCE does not store any personal data.';
@@ -22,3 +22,40 @@ Feature: Edit HTML in TinyMCE
<p>This is my draft</p>
</div>
"""
Scenario: Permissions can be configured to control access to HTML features
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/html:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I set the field "Activity instructions" to "<div><p>This is my draft</p></div>"
When I click on the "View > Source code" menu item for the "Activity instructions" TinyMCE editor
Then "#id_activityeditor_codeMirrorContainer" "css_element" should not exist
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I set the field "Activity instructions" to "<div><p>This is my draft</p></div>"
And I click on the "View > Source code" menu item for the "Activity instructions" TinyMCE editor
And "#id_activityeditor_codeMirrorContainer" "css_element" should exist
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tiny_html';
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->maturity = MATURITY_STABLE;
@@ -25,7 +25,6 @@
namespace tiny_link;
use context;
use context_system;
use editor_tiny\editor;
use editor_tiny\plugin;
use editor_tiny\plugin_with_buttons;
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_link plugin.
*
* @package tiny_link
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/link:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -28,6 +28,7 @@ $string['enterurl'] = 'Enter a URL';
$string['openinnewwindow'] = 'Open in new window';
$string['pluginname'] = 'Link';
$string['link'] = 'Link';
$string['link:use'] = 'Use TinyMCE link';
$string['unlink'] = 'Unlink';
$string['updatelink'] = 'Update link';
$string['privacy:metadata'] = 'The link plugin for TinyMCE does not store any personal data.';
@@ -153,3 +153,39 @@ Feature: Add links to TinyMCE
And I select the "a" element in position "0" of the "Description" TinyMCE editor
When I click on the "Unlink" button for the "Description" TinyMCE editor
Then the field "Description" matches value "<p>Moodle - Open-source learning platform</p>"
@javascript
Scenario: Permissions can be configured to control access to link
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/link:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "Link"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
And I should see "Link"
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_link';
@@ -31,15 +31,8 @@ use editor_tiny\plugin_with_menuitems;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menuitems, plugin_with_configuration {
/**
* Whether the plugin is enabled
*
* @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 $editor The editor instance in which the plugin is initialised
* @return boolean
*/
#[\Override]
public static function is_enabled(
context $context,
array $options,
@@ -50,10 +43,12 @@ class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menu
// - Not logged in or guest.
// - Files are not allowed.
// - Only URL are supported.
// - Don't have the correct capability.
$canhavefiles = !empty($options['maxfiles']);
$canhaveexternalfiles = !empty($options['return_types']) && ($options['return_types'] & FILE_EXTERNAL);
return isloggedin() && !isguestuser() && ($canhavefiles || $canhaveexternalfiles);
return isloggedin() && !isguestuser() && ($canhavefiles || $canhaveexternalfiles) &&
has_capability('tiny/media:use', $context);
}
public static function get_available_buttons(): array {
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_media plugin.
*
* @package tiny_media
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/media:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -75,6 +75,7 @@ $string['link'] = 'Link';
$string['loading'] = 'Preparing the image';
$string['loop'] = 'Loop';
$string['managefiles'] = 'Manage files';
$string['media:use'] = 'Use TinyMCE insert media';
$string['mediabuttontitle'] = 'Multimedia';
$string['mediamanagerbuttontitle'] = 'Media manager';
$string['mediamanagerproperties'] = 'Media manager';
@@ -84,3 +84,39 @@ Feature: Use the TinyMCE editor to upload an image
Then I should see "750" in the "#currentcount" "css_element"
And I set the field "How would you describe this image to someone who can't see it?" to "Lorem ipsum dolor sit amet."
And I should see "27" in the "#currentcount" "css_element"
@javascript
Scenario: Permissions can be configured to control access to media
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/media:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "Multimedia"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Insert" menu item for the "Activity instructions" TinyMCE editor
And I should see "Multimedia"
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800;
$plugin->version = 2025012300;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_media';
@@ -0,0 +1,35 @@
<?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/>.
/**
* Capabilities for the tiny_noautolink plugin.
*
* @package tiny_noautolink
* @copyright 2025 David Woloszyn <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/noautolink:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -26,6 +26,7 @@ $string['buttontitle'] = 'No auto-link';
$string['infoaddsuccess'] = 'Auto-link prevention added.';
$string['infoemptyselection'] = 'Select text and try again.';
$string['inforemovesuccess'] = 'Auto-link prevention removed.';
$string['noautolink:use'] = 'Use TinyMCE no auto-link';
$string['pluginname'] = 'No auto-link';
$string['privacy:metadata'] = 'The tiny_noautolink plugin does not store any personal data.';
@@ -36,3 +36,39 @@ Feature: Tiny noautolink
And I select the "span" element in position "0" of the "Description" TinyMCE editor
And I click on the "No auto-link" button for the "Description" TinyMCE editor
And the field "Description" matches value "<p>Some text</p>"
@javascript
Scenario: Permissions can be configured to control access to no auto-link
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "roles" exist:
| name | shortname | description | archetype |
| Custom teacher | custom1 | Limited permissions | editingteacher |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | custom1 |
And the following "activity" exists:
| activity | assign |
| course | C1 |
| name | Test assignment |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| tiny/noautolink:use | Prohibit | custom1 | Course | C1 |
# Check plugin access as a role with prohibited permissions.
And I log in as "teacher2"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
When I click on the "Format" menu item for the "Activity instructions" TinyMCE editor
Then I should not see "No auto-link"
# Check plugin access as a role with allowed permissions.
And I log in as "teacher1"
And I am on the "Test assignment" Activity page
And I navigate to "Settings" in current page administration
And I click on the "Format" menu item for the "Activity instructions" TinyMCE editor
And I should see "No auto-link"
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024121800; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2025012300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024100100; // Requires this Moodle version.
$plugin->component = 'tiny_noautolink'; // Full name of the plugin (used for diagnostics).
@@ -31,22 +31,14 @@ use tiny_premium\manager;
*/
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.
*
* @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 $editor The editor instance in which the plugin is initialised
* @return bool
*/
#[\Override]
public static function is_enabled(
context $context,
array $options,
array $fpoptions,
?editor $editor = null
): bool {
return has_capability('tiny/premium:accesspremium', $context) && (get_config('tiny_premium', 'apikey') != false);
return has_capability('tiny/premium:use', $context) && (get_config('tiny_premium', 'apikey') != false);
}
/**
@@ -64,8 +56,16 @@ class plugininfo extends plugin implements plugin_with_configuration {
array $fpoptions,
?editor $editor = null
): array {
$allowedplugins = [];
foreach (manager::get_enabled_plugins() as $plugin) {
if (has_capability("tiny/premium:use{$plugin}", $context)) {
$allowedplugins[] = $plugin;
}
}
return [
'premiumplugins' => implode(',', manager::get_enabled_plugins()),
'premiumplugins' => implode(',', $allowedplugins),
];
}
}
+129 -2
View File
@@ -25,11 +25,138 @@
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'tiny/premium:accesspremium' => [
'captype' => 'read',
'tiny/premium:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
'clonepermissionsfrom' => 'tiny/premium:accesspremium',
],
'tiny/premium:useadvtable' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usetypography' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usecasechange' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usechecklist' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:useeditimage' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:useexport' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usefootnotes' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:useformatpainter' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:uselinkchecker' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usepageembed' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usepermanentpen' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usepowerpaste' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usetinymcespellchecker' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:useautocorrect' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usetableofcontents' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:usemath' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
'tiny/premium:useaccessibilitychecker' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
$deprecatedcapabilities = [
'tiny/premium:accesspremium' => [
'replacement' => 'tiny/premium:use',
'message' => 'This capability has been renamed',
],
];
@@ -1 +1,2 @@
helplinktext,tiny_premium
premium:accesspremium,tiny_premium
@@ -31,7 +31,24 @@ $string['apikey_desc'] = 'Your API key is available on your <a href="https://www
$string['emptyapikeywarning'] = 'Enabled TinyMCE Premium plugins will not be available until an API key is added.';
$string['pluginname'] = 'TinyMCE Premium';
$string['pluginnotfound'] = 'Tiny Premium plugin {$a} not found.';
$string['premium:accesspremium'] = 'Access TinyMCE Premium features';
$string['premium:use'] = 'Use TinyMCE premium';
$string['premium:useaccessibilitychecker'] = 'Use TinyMCE Premium Accessibility Checker';
$string['premium:useadvtable'] = 'Use TinyMCE Premium Advanced Table';
$string['premium:useautocorrect'] = 'Use TinyMCE Premium Spelling Autocorrect';
$string['premium:usecasechange'] = 'Use TinyMCE Premium Case Change';
$string['premium:usechecklist'] = 'Use TinyMCE Premium Checklist';
$string['premium:useeditimage'] = 'Use TinyMCE Premium Enhanced Image Editing';
$string['premium:useexport'] = 'Use TinyMCE Premium Export';
$string['premium:usefootnotes'] = 'Use TinyMCE Premium Footnotes';
$string['premium:useformatpainter'] = 'Use TinyMCE Premium Format Painter';
$string['premium:uselinkchecker'] = 'Use TinyMCE Premium Link Checker';
$string['premium:usemath'] = 'Use TinyMCE Premium Math Tool';
$string['premium:usepageembed'] = 'Use TinyMCE Premium Page Embed';
$string['premium:usepermanentpen'] = 'Use TinyMCE Premium Permanent Pen';
$string['premium:usepowerpaste'] = 'Use TinyMCE Premium Powerpaste';
$string['premium:usetableofcontents'] = 'Use TinyMCE Premium Table of Contents';
$string['premium:usetinymcespellchecker'] = 'Use TinyMCE Premium Spell Checker Pro';
$string['premium:usetypography'] = 'Use TinyMCE Premium Advanced Typography';
$string['premiumplugin:a11ychecker'] = 'Accessibility Checker';
$string['premiumplugin:advtable'] = 'Advanced Table';
$string['premiumplugin:autocorrect'] = 'Spelling Autocorrect';
@@ -55,3 +72,6 @@ $string['privacy:metadata'] = 'The Tiny premium plugin for TinyMCE does not stor
// Deprecated since Moodle 4.5.
$string['helplinktext'] = 'Premium plugins';
// Deprecated since Moodle 5.0.
$string['premium:accesspremium'] = 'Access TinyMCE Premium features';
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2025011900;
$plugin->version = 2025021400;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_premium';
@@ -31,15 +31,8 @@ use editor_tiny\plugin_with_menuitems;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menuitems, plugin_with_configuration {
/**
* Whether the plugin is enabled
*
* @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 $editor The editor instance in which the plugin is initialised
* @return boolean
*/
#[\Override]
public static function is_enabled(
context $context,
array $options,
@@ -49,8 +42,9 @@ class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menu
// Disabled if:
// - Not logged in or guest.
// - Files are not allowed.
// - Doesn't have the correct capability.
$canhavefiles = !empty($options['maxfiles']);
return isloggedin() && !isguestuser() && $canhavefiles;
return isloggedin() && !isguestuser() && $canhavefiles && has_capability('tiny/recordrtc:use', $context);
}
public static function get_available_buttons(): array {
@@ -49,4 +49,11 @@ $capabilities = [
'user' => CAP_ALLOW,
],
],
'tiny/recordrtc:use' => [
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => [
'user' => CAP_ALLOW,
],
],
];
@@ -78,6 +78,7 @@ $string['recordinguploaded'] = 'Recording uploaded';
$string['recordrtc:recordaudio'] = 'Record audio in the text editor';
$string['recordrtc:recordscreen'] = 'Record screen in the text editor';
$string['recordrtc:recordvideo'] = 'Record video in the text editor';
$string['recordrtc:use'] = 'Use TinyMCE RecordRTC';
$string['resume'] = 'Resume';
$string['screenbitrate'] = 'Screen bitrate';
$string['screenbitrate_desc'] = 'Quality of screen recording (a larger number means higher quality).';
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024123100;
$plugin->version = 2025021700;
$plugin->requires = 2024100100;
$plugin->component = 'tiny_recordrtc';