mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-02-04 06:22:59 -05:00
remove
This commit is contained in:
@@ -1,110 +0,0 @@
|
|||||||
# TinyMCE MediaCMS Plugin
|
|
||||||
|
|
||||||
A TinyMCE 6 plugin for Moodle that integrates MediaCMS content into the text editor.
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
This plugin adds a MediaCMS button to the TinyMCE toolbar in Moodle. When clicked, it opens a dialog that allows users to browse and select MediaCMS content to embed directly in their course content.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Visual Media Selection**: Browse available MediaCMS content in a grid view
|
|
||||||
- **Permission-Aware**: Only shows media the user has permission to view
|
|
||||||
- **RBAC Integration**: Respects MediaCMS role-based access control
|
|
||||||
- **Multiple Selection**: Select and insert multiple media items at once
|
|
||||||
- **Pagination**: Navigate through large media libraries
|
|
||||||
- **Filter Options**: Filter by "My Media" or view all accessible content
|
|
||||||
- **Responsive Design**: Works on desktop and tablet devices
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- Moodle 5.0 or later (with TinyMCE 6)
|
|
||||||
- MediaCMS instance with LTI integration
|
|
||||||
- Configured LTI 1.3 external tool in Moodle
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
1. Copy this directory to `{moodle}/lib/editor/tiny/plugins/tiny_mediacms`
|
|
||||||
2. Visit Site administration → Notifications
|
|
||||||
3. Follow the upgrade prompts
|
|
||||||
4. Configure the plugin in TinyMCE settings
|
|
||||||
|
|
||||||
For detailed installation instructions, see [TINYMCE_PLUGIN_INSTALLATION.md](../../TINYMCE_PLUGIN_INSTALLATION.md) in the MediaCMS root directory.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
1. Open any text editor in Moodle
|
|
||||||
2. Click the MediaCMS button (video camera icon) in the toolbar
|
|
||||||
3. Select one or more media items
|
|
||||||
4. Click "Insert" to embed the content
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
The plugin can be configured at:
|
|
||||||
- Site administration → Plugins → Text editors → TinyMCE plugins → MediaCMS
|
|
||||||
|
|
||||||
Configuration options:
|
|
||||||
- MediaCMS URL (typically auto-configured from LTI settings)
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Plugin Type
|
|
||||||
- Type: TinyMCE 6 plugin
|
|
||||||
- Category: Content insertion
|
|
||||||
- API: Moodle editor_tiny API
|
|
||||||
|
|
||||||
### Files
|
|
||||||
- `version.php` - Plugin metadata
|
|
||||||
- `classes/plugininfo.php` - Plugin registration and configuration
|
|
||||||
- `amd/src/plugin.js` - Main plugin functionality
|
|
||||||
- `amd/src/common.js` - Shared constants
|
|
||||||
- `amd/src/configuration.js` - Configuration handling
|
|
||||||
- `lang/en/tiny_mediacms.php` - Language strings
|
|
||||||
- `pix/icon.svg` - Plugin icon
|
|
||||||
|
|
||||||
### Backend Endpoints (MediaCMS)
|
|
||||||
- `/lti/tinymce-select/` - Media selection interface
|
|
||||||
- `/lti/tinymce-embed/<token>/` - Embed code API
|
|
||||||
|
|
||||||
## Security
|
|
||||||
|
|
||||||
- Requires active LTI session
|
|
||||||
- Respects MediaCMS permissions and RBAC
|
|
||||||
- Uses CSRF protection
|
|
||||||
- Validates user authentication
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For issues, bugs, or feature requests:
|
|
||||||
1. Check the installation guide
|
|
||||||
2. Review Moodle and MediaCMS logs
|
|
||||||
3. Consult MediaCMS LTI documentation
|
|
||||||
4. Open an issue in the MediaCMS repository
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This plugin is part of MediaCMS and Moodle.
|
|
||||||
|
|
||||||
- Moodle components: GNU GPL v3 or later
|
|
||||||
- MediaCMS integration: Same as MediaCMS license
|
|
||||||
|
|
||||||
## Version
|
|
||||||
|
|
||||||
- Version: 1.0.0
|
|
||||||
- Release date: 2026-01-12
|
|
||||||
- Moodle requirement: 5.0+
|
|
||||||
- Maturity: Stable
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
|
|
||||||
Developed for MediaCMS LTI integration with Moodle.
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
### 1.0.0 (2026-01-12)
|
|
||||||
- Initial release
|
|
||||||
- Media selection dialog
|
|
||||||
- Multiple media insertion
|
|
||||||
- RBAC and permission support
|
|
||||||
- Pagination support
|
|
||||||
- Filter options
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
define("tiny_mediacms/common",[],function(){const component="tiny_mediacms",pluginName=`${component}/plugin`,icon="icon",buttonName=`${component}/button`;return{component:component,pluginName:pluginName,icon:icon,buttonName:buttonName}});
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
define("tiny_mediacms/configuration",["tiny_mediacms/common","editor_tiny/options"],function(common,Options){const pluginName=common.pluginName,mediacmsUrlName=Options.getPluginOptionName(pluginName,"mediacmsUrl");return{register:editor=>{const registerOption=editor.options.register;registerOption(mediacmsUrlName,{processor:"string",default:""})},getConfig:editor=>({mediacmsUrl:editor.options.get(mediacmsUrlName)})}});
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
define("tiny_mediacms/plugin",["editor_tiny/loader","tiny_mediacms/common","tiny_mediacms/configuration"],function(Loader,common,Configuration){const component=common.component,pluginName=common.pluginName,icon=common.icon,buttonName=common.buttonName,handleAction=async editor=>{const config=Configuration.getConfig(editor),dialogConfig={title:"Select MediaCMS content",size:"large",body:{type:"panel",items:[{type:"htmlpanel",html:'<div id="mediacms-loading" style="text-align: center; padding: 20px;">Loading MediaCMS content...</div><iframe id="mediacms-iframe" style="width: 100%; height: 500px; border: none; display: none;"></iframe>'}]},buttons:[{type:"cancel",text:"Close"}],initialData:{},onSubmit:function(api){api.close()}},dialog=editor.windowManager.open(dialogConfig),messageHandler=event=>{if(event.data&&"mediacms-embed"===event.data.type){const embedCode=event.data.embedCode;embedCode&&(editor.insertContent(embedCode),dialog.close())}};window.addEventListener("message",messageHandler);const courseId="undefined"!=typeof M&&M.cfg&&M.cfg.courseId?M.cfg.courseId:1,mediacmsBaseUrl=config.mediacmsUrl||window.location.origin,selectMediaUrl=mediacmsBaseUrl+"/lti/select-media/?mode=tinymce&courseid="+courseId;setTimeout(()=>{const iframe=document.querySelector("#mediacms-iframe"),loading=document.querySelector("#mediacms-loading");iframe&&loading&&(iframe.onload=()=>{loading.style.display="none",iframe.style.display="block"},iframe.onerror=()=>{loading.innerHTML='<p style="color: red;">Error loading MediaCMS content. Please check your configuration.</p>'},iframe.src=selectMediaUrl)},100);const originalClose=dialog.close;dialog.close=function(){window.removeEventListener("message",messageHandler),originalClose.call(this)}};return{getSetup:async()=>{const[tinyMCE]=await Promise.all([Loader.getTinyMCE()]);return editor=>(editor.ui.registry.addButton(buttonName,{icon:icon,tooltip:"Insert MediaCMS content",onAction:()=>handleAction(editor)}),editor.ui.registry.addMenuItem(buttonName,{icon:icon,text:"Insert MediaCMS content",onAction:()=>handleAction(editor)}),void 0)}}});
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common values for the Tiny MediaCMS plugin.
|
|
||||||
*
|
|
||||||
* @module tiny_mediacms/common
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
const component = 'tiny_mediacms';
|
|
||||||
const pluginName = `${component}/plugin`;
|
|
||||||
const icon = 'icon';
|
|
||||||
const buttonName = `${component}/button`;
|
|
||||||
|
|
||||||
export {
|
|
||||||
component,
|
|
||||||
pluginName,
|
|
||||||
icon,
|
|
||||||
buttonName,
|
|
||||||
};
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for Tiny MediaCMS plugin.
|
|
||||||
*
|
|
||||||
* @module tiny_mediacms/configuration
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {pluginName} from './common';
|
|
||||||
import {getPluginOptionName} from 'editor_tiny/options';
|
|
||||||
|
|
||||||
const mediacmsUrlName = getPluginOptionName(pluginName, 'mediacmsUrl');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the plugin configuration.
|
|
||||||
*
|
|
||||||
* @param {TinyMCE} editor
|
|
||||||
*/
|
|
||||||
export const register = (editor) => {
|
|
||||||
const registerOption = editor.options.register;
|
|
||||||
|
|
||||||
registerOption(mediacmsUrlName, {
|
|
||||||
processor: 'string',
|
|
||||||
"default": '',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration for the plugin.
|
|
||||||
*
|
|
||||||
* @param {TinyMCE.Editor} editor
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
export const getConfig = (editor) => {
|
|
||||||
return {
|
|
||||||
mediacmsUrl: editor.options.get(mediacmsUrlName),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny MediaCMS plugin.
|
|
||||||
*
|
|
||||||
* @module tiny_mediacms/plugin
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {getTinyMCE} from 'editor_tiny/loader';
|
|
||||||
import {getPluginOptionName} from 'editor_tiny/options';
|
|
||||||
import {component, pluginName, icon, buttonName} from './common';
|
|
||||||
import * as Configuration from './configuration';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the action when button is clicked.
|
|
||||||
*
|
|
||||||
* @param {TinyMCE.Editor} editor The TinyMCE editor instance.
|
|
||||||
*/
|
|
||||||
const handleAction = async(editor) => {
|
|
||||||
const config = Configuration.getConfig(editor);
|
|
||||||
|
|
||||||
// Get the MediaCMS LTI tool ID from the external tool in the activity
|
|
||||||
// For simplicity, we'll use a dialog that loads the MediaCMS select-media view
|
|
||||||
const dialogConfig = {
|
|
||||||
title: 'Select MediaCMS content',
|
|
||||||
size: 'large',
|
|
||||||
body: {
|
|
||||||
type: 'panel',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
type: 'htmlpanel',
|
|
||||||
html: '<div id="mediacms-loading" style="text-align: center; padding: 20px;">Loading MediaCMS content...</div>' +
|
|
||||||
'<iframe id="mediacms-iframe" style="width: 100%; height: 500px; border: none; display: none;"></iframe>'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
type: 'cancel',
|
|
||||||
text: 'Close'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
initialData: {},
|
|
||||||
onSubmit: function(api) {
|
|
||||||
api.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const dialog = editor.windowManager.open(dialogConfig);
|
|
||||||
|
|
||||||
// Listen for messages from the iframe
|
|
||||||
const messageHandler = (event) => {
|
|
||||||
// Security check: verify origin if needed
|
|
||||||
// if (event.origin !== expectedOrigin) return;
|
|
||||||
|
|
||||||
if (event.data && event.data.type === 'mediacms-embed') {
|
|
||||||
const embedCode = event.data.embedCode;
|
|
||||||
if (embedCode) {
|
|
||||||
editor.insertContent(embedCode);
|
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('message', messageHandler);
|
|
||||||
|
|
||||||
// Get the current course ID from Moodle
|
|
||||||
const courseId = (typeof M !== 'undefined' && M.cfg && M.cfg.courseId) ? M.cfg.courseId : 1;
|
|
||||||
|
|
||||||
// Build the MediaCMS select-media URL with TinyMCE mode
|
|
||||||
// This URL should point to your MediaCMS instance
|
|
||||||
// You'll need to configure this in the plugin settings
|
|
||||||
const mediacmsBaseUrl = config.mediacmsUrl || window.location.origin;
|
|
||||||
const selectMediaUrl = mediacmsBaseUrl + '/lti/select-media/?mode=tinymce&courseid=' + courseId;
|
|
||||||
|
|
||||||
// Load the iframe after dialog is rendered
|
|
||||||
setTimeout(() => {
|
|
||||||
const iframe = document.querySelector('#mediacms-iframe');
|
|
||||||
const loading = document.querySelector('#mediacms-loading');
|
|
||||||
|
|
||||||
if (iframe && loading) {
|
|
||||||
iframe.onload = () => {
|
|
||||||
loading.style.display = 'none';
|
|
||||||
iframe.style.display = 'block';
|
|
||||||
};
|
|
||||||
iframe.onerror = () => {
|
|
||||||
loading.innerHTML = '<p style="color: red;">Error loading MediaCMS content. Please check your configuration.</p>';
|
|
||||||
};
|
|
||||||
iframe.src = selectMediaUrl;
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
// Cleanup on dialog close (TinyMCE 6 API)
|
|
||||||
// Note: TinyMCE dialog may not have an 'on' method, so we'll rely on cleanup when the component unmounts
|
|
||||||
const originalClose = dialog.close;
|
|
||||||
dialog.close = function() {
|
|
||||||
window.removeEventListener('message', messageHandler);
|
|
||||||
originalClose.call(this);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the setup function for the buttons.
|
|
||||||
*
|
|
||||||
* This is performed in an async function which ultimately returns the registration function as the
|
|
||||||
* Tiny.AddOnManager.Add() function does not support async functions.
|
|
||||||
*
|
|
||||||
* @returns {function} The registration function to call within the Plugin.add function.
|
|
||||||
*/
|
|
||||||
export const getSetup = async() => {
|
|
||||||
const [
|
|
||||||
tinyMCE,
|
|
||||||
] = await Promise.all([
|
|
||||||
getTinyMCE(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return (editor) => {
|
|
||||||
// Register the button
|
|
||||||
editor.ui.registry.addButton(buttonName, {
|
|
||||||
icon: icon,
|
|
||||||
tooltip: 'Insert MediaCMS content',
|
|
||||||
onAction: () => handleAction(editor),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register the menu item
|
|
||||||
editor.ui.registry.addMenuItem(buttonName, {
|
|
||||||
icon: icon,
|
|
||||||
text: 'Insert MediaCMS content',
|
|
||||||
onAction: () => handleAction(editor),
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny MediaCMS plugin info.
|
|
||||||
*
|
|
||||||
* @package tiny_mediacms
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace tiny_mediacms;
|
|
||||||
|
|
||||||
use context;
|
|
||||||
use editor_tiny\plugin;
|
|
||||||
use editor_tiny\plugin_with_buttons;
|
|
||||||
use editor_tiny\plugin_with_configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny MediaCMS plugin for Moodle.
|
|
||||||
*
|
|
||||||
* @package tiny_mediacms
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
class plugininfo extends plugin implements plugin_with_buttons, plugin_with_configuration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of the buttons provided by this plugin.
|
|
||||||
*
|
|
||||||
* @return string[]
|
|
||||||
*/
|
|
||||||
public static function get_available_buttons(): array {
|
|
||||||
return [
|
|
||||||
'tiny_mediacms/button',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configuration for this plugin.
|
|
||||||
*
|
|
||||||
* @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_tiny\editor|null $editor The editor instance in which the plugin is initialized
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function get_plugin_configuration_for_context(
|
|
||||||
context $context,
|
|
||||||
array $options,
|
|
||||||
array $fpoptions,
|
|
||||||
?\editor_tiny\editor $editor = null
|
|
||||||
): array {
|
|
||||||
global $CFG;
|
|
||||||
|
|
||||||
// Return the MediaCMS LTI tool URL configuration
|
|
||||||
return [
|
|
||||||
'mediacmsUrl' => $CFG->wwwroot,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<?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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Language strings for tiny_mediacms plugin.
|
|
||||||
*
|
|
||||||
* @package tiny_mediacms
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
|
||||||
|
|
||||||
$string['pluginname'] = 'MediaCMS';
|
|
||||||
$string['privacy:metadata'] = 'The MediaCMS plugin does not store any personal data.';
|
|
||||||
$string['button_title'] = 'Insert MediaCMS content';
|
|
||||||
$string['dialog_title'] = 'Select MediaCMS content';
|
|
||||||
$string['insert'] = 'Insert';
|
|
||||||
$string['cancel'] = 'Cancel';
|
|
||||||
$string['loading'] = 'Loading MediaCMS content...';
|
|
||||||
$string['error_no_tool'] = 'No MediaCMS LTI tool configured for this course.';
|
|
||||||
$string['error_loading'] = 'Error loading MediaCMS content. Please try again.';
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect x="2" y="4" width="20" height="16" rx="2" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
||||||
<polygon points="10,9 10,15 16,12" fill="currentColor"/>
|
|
||||||
<circle cx="18" cy="7" r="2" fill="#ff0000"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 319 B |
@@ -1,23 +0,0 @@
|
|||||||
<?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.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny MediaCMS plugin version details.
|
|
||||||
*
|
|
||||||
* @package tiny_mediacms
|
|
||||||
* @copyright 2026 MediaCMS
|
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
|
||||||
|
|
||||||
$plugin->component = 'tiny_mediacms';
|
|
||||||
$plugin->version = 2026011200; // YYYYMMDDXX format.
|
|
||||||
$plugin->requires = 2024042200; // Moodle 5.0 or later.
|
|
||||||
$plugin->maturity = MATURITY_STABLE;
|
|
||||||
$plugin->release = '1.0.0';
|
|
||||||
Reference in New Issue
Block a user