Interactive Tool
Explore a real plugin structure with our interactive tool:
Open Plugin Code Explorer1. Anatomy of a Plugin
Every plugin requires a version.php file to define its identity.
// version.php
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'local_myplugin'; // Full name of the plugin
$plugin->version = 2023101000; // YYYYMMDDXX
$plugin->requires = 2022112800; // Requires Moodle 4.1+
$plugin->maturity = MATURITY_STABLE;
$plugin->release = 'v1.0';
2. Language Strings
Strings are stored in lang/en/local_myplugin.php.
// lang/en/local_myplugin.php
$string['pluginname'] = 'My Custom Plugin';
$string['welcome'] = 'Welcome to my plugin!';
Usage:
echo get_string('welcome', 'local_myplugin');
3. Database Tables (XMLDB)
Database schemas are defined in db/install.xml. You can use the XMLDB editor in the admin panel to generate this file.
4. Upgrade Script
When you change the database schema or need to run code during an update, use db/upgrade.php.
// db/upgrade.php
function xmldb_local_myplugin_upgrade($oldversion) {
global $DB;
$dbman = $DB->get_manager();
if ($oldversion < 2023101001) {
// Define table, add field, etc.
// ...
upgrade_plugin_savepoint(true, 2023101001, 'local', 'myplugin');
}
return true;
}
5. Privacy API (GDPR)
Every plugin that stores user data must implement the Privacy API to support data export and deletion requests.
// classes/privacy/provider.php
namespace local_myplugin\privacy;
class provider implements \core_privacy\local\metadata\null_provider {
// If your plugin DOES NOT store user data, use null_provider.
public static function get_reason() : string {
return 'privacy:metadata';
}
}
If you do store data, you must implement \core_privacy\local\metadata\provider and define get_metadata, export_user_data, and delete_data_for_user.
6. Backup & Restore API
To ensure your plugin's data is included in course backups, you must implement the Backup API.
- backup/moodle2/backup_local_myplugin_stepslib.php: Define the structure of data to backup.
- backup/moodle2/restore_local_myplugin_stepslib.php: Define how to restore that data.
This is complex but essential for Activity modules.
7. Creating External Services (API)
To expose your plugin's functionality via the REST API, you need to define a service.
1. Define the function in db/services.php:
$functions = [
'local_myplugin_get_items' => [
'classname' => 'local_myplugin\external\get_items',
'methodname' => 'execute',
'classpath' => 'local/myplugin/classes/external/get_items.php',
'description' => 'Get a list of items',
'type' => 'read',
'ajax' => true, // Allow calling from JS
],
];
2. Implement the external class:
namespace local_myplugin\external;
use external_api;
use external_function_parameters;
use external_single_structure;
use external_value;
class get_items extends external_api {
public static function execute_parameters() {
return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'Course ID'),
]);
}
public static function execute($courseid) {
self::validate_parameters(self::execute_parameters(), ['courseid' => $courseid]);
// ... logic ...
return ['data' => '...'];
}
public static function execute_returns() {
return new external_single_structure([
'data' => new external_value(PARAM_TEXT, 'The data'),
]);
}
}