### Install Dependencies and Start Development Server Source: https://github.com/moodle/devdocs/blob/main/general/app/development/setup/index.md Navigate to the cloned repository, install project dependencies, and start the development server to run the app in a browser. ```bash cd moodleapp npm install npm start ``` -------------------------------- ### Install and Start Development Server Source: https://github.com/moodle/devdocs/blob/main/README.md Installs Node.js version manager, Node.js, Yarn, project dependencies, and starts the development server. ```bash nvm install npm i -g yarn yarn yarn start ``` -------------------------------- ### Example install.php for a block plugin Source: https://github.com/moodle/devdocs/blob/main/docs/guides/upgrade/index.md Illustrates how to define an installation behavior in the install.php script for a Moodle block plugin named 'block_example'. ```php { // TODO Handle the action. window.console.log(editor); }; export const getSetup = async() => { const [ startdemoButtonNameTitle, startdemoMenuItemNameTitle, buttonImage, ] = await Promise.all([ getString('button_startdemo', component), getString('menuitem_startdemo', component), getButtonImage('icon', component), ]); return (editor) => { // Register the Moodle SVG as an icon suitable for use as a TinyMCE toolbar button. editor.ui.registry.addIcon(icon, buttonImage.html); // Register the startdemo Toolbar Button. editor.ui.registry.addButton(startdemoButtonName, { icon, tooltip: startdemoButtonNameTitle, onAction: () => handleAction(editor), }); // Add the startdemo Menu Item. // This allows it to be added to a standard menu, or a context menu. editor.ui.registry.addMenuItem(startdemoMenuItemName, { icon, text: startdemoMenuItemNameTitle, onAction: () => handleAction(editor), }); }; }; ``` -------------------------------- ### Install Windows Build Tools Source: https://github.com/moodle/devdocs/blob/main/general/app/development/setup/index.md Run this command as administrator on Windows to install native build tools required by node-gyp. Be aware that this installation can take a significant amount of time. ```bash npm install --global --production windows-build-tools ``` -------------------------------- ### File Header Documentation Example Source: https://github.com/moodle/devdocs/blob/main/general/development/policies/codingstyle/index.md All PHP files must start with a GPL copyright statement followed by a comprehensive docblock. This docblock includes a one-line description, a longer description, and required tags like @package, @copyright, and @license. The @category tag is optional and used for core APIs. ```php . /** * This is a one-line short description of the file. * * You can have a rather longer description of the file as well, * if you like, and it can span multiple lines. * * @package mod_mymodule * @category backup * @copyright 2008 Kim Bloggs * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ ``` -------------------------------- ### Start the Development Server Source: https://github.com/moodle/devdocs/blob/main/general/documentation/installation.md Run this command to start the local development server. Changes to markdown files will automatically reload in the browser. ```bash yarn start ``` -------------------------------- ### Valid Storage Full Example Source: https://github.com/moodle/devdocs/blob/main/general/contentguidelines/01-productwriting/errormsg.md Clearly state the problem. This example indicates that the user's storage is full. ```text Your storage is full. ``` -------------------------------- ### Standard Editing UI Example Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/enrol/index.md Example of UI library for standard editing UI in manual enrolments. ```php import UiLib from '!!raw-loader!./_examples/ui_lib.php'; ``` -------------------------------- ### Install PHPUnit via Composer Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/phpunit/index.md Execute Composer to install PHPUnit. Use '--prefer-source' if connection issues arise. ```bash cd /your/moodle/dirroot php composer.phar install ``` ```bash php composer.phar install --prefer-source ``` -------------------------------- ### Example Error Installing node-sass on MacOS Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/nodejs.md This is a typical error message encountered when the MacOS setup for node-sass is incomplete or outdated. It indicates a build failure during the npm installation process. ```bash npm ERR! code 1 npm ERR! path /Users/jun/Work/moodles/integration_master/moodle/node_modules/node-sass npm ERR! command failed npm ERR! command sh /var/folders/87/fnlrch612m5d40trk64lrd480000gn/T/postinstall-a2316f45.sh npm ERR! Building: /Users/jun/.nvm/versions/node/v16.17.0/bin/node /Users/jun/Work/moodles/integration_master/moodle/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library= npm ERR! make: Entering directory '/Users/jun/Work/moodles/integration_master/moodle/node_modules/node-sass/build' ``` -------------------------------- ### Get Help Creating an Upgrade Note Source: https://github.com/moodle/devdocs/blob/main/general/development/upgradenotes.md Displays full help information for the `create` command, detailing all available options and their usage. ```bash .grunt/upgradenotes.mjs create -h ``` -------------------------------- ### Install CocoaPods on Mac Source: https://github.com/moodle/devdocs/blob/main/general/app/development/setup/index.md Install CocoaPods on macOS, which is necessary for the push notifications plugin when compiling the native iOS application. Follow these commands for installation and setup. ```bash sudo gem install cocoapods pod setup ``` -------------------------------- ### Manual Moodle Installation Steps Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/mdk.md This block details the manual steps equivalent to the 'mdk create' command, including directory creation, cloning Moodle, running the installer, and configuring 'config.php'. ```bash mkdir /dir/to/stable_24/moodle mkdir /dir/to/stable_24/moodledata ln -s /dir/to/stable_24/moodle /var/www/stable_24 git clone git://git.moodle.org/moodle.git /dir/to/moodle cd /dir/to/stable_24/moodle php admin/cli/install.php --wwwroot## "http://localhost/stable_24" --dataroot/dir/to/stable_24/moodledata --dbtype## pgsql --dbnamestable24 --dbuser## root --dbpassroot --dbhost## localhost --fullname"Stable 24 PostgreSQL" --shortname## stable_24 --adminuseradmin --adminpass=test --allow-unstable --agree-license --non-interactive vim config.php # Add the following settings: # - $CFG->sessioncookiepath: /stable_24/ # - $CFG->debug: DEBUG_DEVELOPER # - $CFG->debugdisplay: 1 # - $CFG->passwordpolicy: 0 # - $CFG->perfdebug: 15 # - $CFG->debugpageinfo: 1 # - $CFG->allowthemechangeonurl: 1 # - $CFG->cachejs: 0 # - $CFG->yuicomboloading: 0 # Include FirePHP Core # Login to Moodle # Create 10 students, 3 teachers and 3 managers ``` -------------------------------- ### Create and Install Moodle Instance with Dev Settings Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/mdk.md Use this command to create a new Moodle instance, install it with a specified database engine, and configure it for development. It can also create user accounts. ```bash mdk create -i -v 24 -e pgsql -r dev users ``` ```bash mdk create --install --version 24 --engine pgsql --run dev users ``` -------------------------------- ### Delegated Transaction Example Source: https://github.com/moodle/devdocs/blob/main/docs/apis/core/dml/index.md A try-catch block demonstrating how to start, commit, or rollback a delegated transaction for data consistency. ```php start_delegated_transaction(); $DB->insert_record('foo', $object); $DB->insert_record('bar', $otherobject); // Assuming the both inserts work, we get to the following line. $transaction->allow_commit(); } catch (Exception $e) { $transaction->rollback($e); } ?> ``` -------------------------------- ### Format Plugin Initialization and Rendering (Moodle 4.0) Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/format/migration.md This example demonstrates the new workflow in Moodle 4.0 for initializing and rendering course formats. It shows how to obtain the renderer and render output classes directly. ```php dirroot . '/course/format/lib.php'); require_once($CFG->dirroot . '/course/classes.php'); /** * Course format plugin. */ class format_pluginname extends core_courseformat\base { /** * Constructor for the format_pluginname class. * * @param stdClass $course The course object. */ public function __construct($course) { parent::__construct($course); } /** * Returns the name of the renderer class for this format. * * @return string The fully qualified name of the renderer class. */ public function get_renderer_classname() { return 'format_pluginname_renderer'; } /** * Returns the name of the output class for the course format. * * @return string The fully qualified name of the output class. */ public function get_output_classname() { return 'format_pluginname_output'; } /** * Prints the course content for the format. * * @param stdClass $course The course object. * @param stdClass $cm The course module object. * @param std.Class $module The module object. * @param std.Class $page The page object. * @param std.Class $output The output object. */ public function outputcourse($course, $cm, $module, $page, $output) { // Get the renderer instance. $renderer = $this->get_renderer($page); // Render the course content using the format's output class. echo $renderer->{$this->get_output_classname()}->render($this); } } ``` -------------------------------- ### Build and Serve Docs Locally Source: https://github.com/moodle/devdocs/blob/main/general/documentation/installation.md Use these commands to build the documentation and serve it locally, primarily for testing the build process. ```bash yarn build yarn serve ``` -------------------------------- ### PHP Example: Get users able to submit an assignment Source: https://github.com/moodle/devdocs/blob/main/docs/apis/subsystems/enrol.md Fetches all users who possess the 'mod/assign:submit' capability within a given context. ```php $submissioncandidates = get_enrolled_users($modcontext, 'mod/assign:submit'); ``` -------------------------------- ### Setup Text Editor Source: https://github.com/moodle/devdocs/blob/main/docs/apis/subsystems/editor/index.md Enables a text editor for an existing HTML text area. Requires calling `editors_get_preferred_editor()` first to get the editor object. ```php $editor = editors_get_preferred_editor(FORMAT_HTML); $editor->use_editor('mytextareaid'); ``` -------------------------------- ### lib.php Example Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/format/index.md The main library file for the format plugin. It should contain the format base class extending core_courseformat\base and may include other necessary callbacks. ```php . /** * Unit tests for the get_fruit function of the kitchen. * * @package mod_kitchen * @category external * @copyright 20XX Your Name * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_kitchen\external; defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->dirroot . '/webservice/tests/helpers.php'); class get_fruit_test extends externallib_advanced_testcase { /** * Test the execute function when capabilities are present. * * @covers \mod_fruit\external\get_fruit::execute */ public function test_capabilities(): void { $this->resetAfterTest(true); $course = $this->getDataGenerator()->create_course(); $cm = $this->getDataGenerator()->create_module('mod_kitchen', [ 'course' => $course->id, ]); // Set the required capabilities by the external function $contextid = context_module::instance($cm->cmid)->id; $roleid = $this->assignUserCapability('moodle/CAPABILITYNAME', $contextid); // Call the external service function. $returnvalue = get_fruit::execute([ 'course' => $course->id, 'cmid' => $cm->id, ]); // We need to execute the return values cleaning process to simulate // the web service server. $returnvalue = \core_external\external_api::clean_returnvalue( get_fruit::execute_returns(), $returnvalue ); // Assert that there was a response. // The actual response is tested in other tests. $this->assertNotNull($returnvalue); } /** * Test the execute function when capabilities are missing. * * @covers \mod_fruit\external\get_fruit::execute */ public function test_capabilities_missing(): void { global $USER; $this->resetAfterTest(true); $course = $this->getDataGenerator()->create_course(); $cm = $this->getDataGenerator()->create_module('mod_kitchen', [ 'course' => $course->id, ]); // Set the required capabilities by the external function $contextid = context_module::instance($cm->cmid)->id; $this->unassignUserCapability('moodle/CAPABILITYNAME', $contextid, $roleid); $params = [PARAM1, PARAM2, ...]; // Call without required capability $this->expectException(required_capability_exception::class); get_fruit::execute([ 'course' => $course->id, 'cmid' => $cm->id, ]); } } ``` -------------------------------- ### Inline Comments (Initialization) Source: https://github.com/moodle/devdocs/blob/main/general/development/policies/codingstyle/index.md Inline comments must use the '// ' style, start with a capital letter or digit, and end with punctuation. This example shows initializing an empty array. ```php $ratings = []; // Initialize the empty array. ``` -------------------------------- ### JavaScript: Complete options.js implementation Source: https://github.com/moodle/devdocs/blob/main/versioned_docs/version-5.2/apis/plugintypes/tiny/index.md A full example of `options.js` demonstrating how to import helpers, define option names, register options with processors, and fetch values for a TinyMCE plugin. ```javascript import {getPluginOptionName} from 'editor_tiny/options'; import {pluginName} from './common'; // Helper variables for the option names. const myFirstPropertyName = getPluginOptionName(pluginName, 'myFirstProperty'); /** * Options registration function. * * @param {tinyMCE} editor */ export const register = (editor) => { const registerOption = editor.options.register; // For each option, register it with the editor. // Valid type are defined in https://www.tiny.cloud/docs/tinymce/6/apis/tinymce.editoroptions/ registerOption(myFirstPropertyName, { processor: 'number', }); }; /** * Fetch the myFirstProperty value for this editor instance. * * @param {tinyMCE} editor The editor instance to fetch the value for * @returns {object} The value of the myFirstProperty option */ export const getMyFirstProperty = (editor) => editor.options.get(myFirstPropertyName); ``` -------------------------------- ### User List Provider Polyfill Example Source: https://github.com/moodle/devdocs/blob/main/versioned_docs/version-5.2/apis/subsystems/privacy/index.md Provides a polyfill for the `core_privacy equest equest_userlist` interface for older Moodle versions. Implements functions to get and delete user data within a context. ```php contextlevel != CONTEXT_MODULE) { return false; } // Make sure the filearea is one of those used by the plugin. if ($filearea !== 'expectedfilearea' && $filearea !== 'anotherexpectedfilearea') { return false; } // Make sure the user is logged in and has access to the module (plugins that are not course modules should leave out the 'cm' part). require_login($course, true, $cm); // Check the relevant capabilities - these may vary depending on the filearea being accessed. if (!has_capability('mod/myplugin:view', $context)) { return false; } // The args is an array containing [itemid, path]. // Fetch the itemid from the path. $itemid = array_shift($args); // The itemid can be used to check access to a record, and ensure that the // record belongs to the specifeid context. For example: if ($filearea === 'expectedfilearea') { $post = $DB->get_record('myplugin_posts', ['id' => $itemid]); if ($post->myplugin !== $context->instanceid) { // This post does not belong to the requested context. return false; } // You may want to perform additional checks here, for example: // - ensure that if the record relates to a grouped activity, that this // user has access to it // - check whether the record is hidden // - check whether the user is allowed to see the record for some other // reason. // If, for any reason, the user does not hve access, you can return // false here. } // For a plugin which does not specify the itemid, you may want to use the following to keep your code consistent: // $itemid = null; // Extract the filename / filepath from the $args array. $filename = array_pop($args); // The last item in the $args array. if (empty($args)) { // $args is empty => the path is '/'. $filepath = '/'; } else { // $args contains the remaining elements of the filepath. $filepath = '/' . implode('/', $args) . '/'; } // Retrieve the file from the Files API. $fs = get_file_storage(); $file = $fs->get_file($context->id, 'mod_myplugin', $filearea, $itemid, $filepath, $filename); if (!$file) { // The file does not exist. ``` -------------------------------- ### Manual Moodle Pull and PHPUnit Setup Steps Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/mdk.md This block details the manual Git and configuration steps equivalent to the 'mdk pull' and 'mdk phpunit' commands, including setting up PHPUnit data root and prefix. ```bash cd /dir/to/stable_24/moodle git branch --tracker MDL-12345-24-test MOODLE_24_STABLE git checkout MDL-12345-24-test git pull git://github.org/Someone/moodle.git MDL-12345-24 # And now the PHPUnit part mkdir /dir/to/stable_24/moodledata_phpu vim config.php # To add # - $CFG->phpunit_dataroot = '/dir/to/stable_24/moodledata_phpu'; # - $CFG->phpunit_prefix = 'phpu_'; php admin/tool/phpunit/cli/init.php phpunit ``` -------------------------------- ### Get Response Data for Generate Image Action Source: https://github.com/moodle/devdocs/blob/main/docs/apis/subsystems/ai/index.md The `get_response_data()` method returns the response data as an associative array. This example demonstrates how to retrieve the `draftfile`, `revisedprompt`, and `sourceurl` for the `generate_image` action response. ```php #[\Override] public function get_response_data(): array { return [ 'draftfile' => $this->draftfile, 'revisedprompt' => $this->revisedprompt, 'sourceurl' => $this->sourceurl, ]; } ``` -------------------------------- ### Create Moodle Instances for Backporting Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/mdk.md Use these commands to create specific Moodle versions for backporting fixes. Ensure you have the correct version flags and instance names. ```bash mdk create -v 38 -i -r dev users makecourse -n stable_38 mdk create -v 37 -i -r dev users makecourse -n stable_37 ``` -------------------------------- ### Get Files from Draft Area (PHP) Source: https://github.com/moodle/devdocs/blob/main/docs/apis/subsystems/external/files.md Example of retrieving files from a specified draft area using the `external_util::get_area_files` method in PHP. This is useful for fetching files previously uploaded via web services. ```php $forum->introfiles = external_util::get_area_files($context->id, 'mod_forum', 'intro', false, false); ``` -------------------------------- ### Example Usage of supports() Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/fileconverter/index.md Demonstrates how to check if a specific file conversion is supported by a plugin before attempting the conversion. ```php if (\fileconverter_example::supports('jpg', 'pdf')) { // ... } ``` -------------------------------- ### Get List of Plugin Types Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/index.md Use this PHP script to retrieve and display all plugin types known to your Moodle installation, along with their plural names and directory paths. This script requires Moodle's core files to be included. ```php get_plugin_types() as $type => $dir) { $dir = substr($dir, strlen($CFG->dirroot)); printf( "%-20s %-50s %s" . PHP_EOL, $type, $pluginman->plugintype_name_plural($type), $dir) ; } ``` -------------------------------- ### Example Directory Layout for format_pluginname Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/format/index.md This shows the typical file and directory structure for a course format plugin named 'pluginname'. ```console course/format/pluginname/ |-- classes | `-- output | `-- courseformat | `-- (Overridden outputs) | `-- renderer.php |-- db | `-- access.php |-- lang | `-- en | `-- format_pluginname.php |-- format.php |-- lib.php `-- version.php ``` -------------------------------- ### Define Site-Wide Settings for Local Plugin Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/local/index.mdx This example demonstrates how to create a new settings page for a local plugin and add a text-based configuration field for an API key. Ensure the `$hassiteconfig` variable is true before proceeding. This code is intended for use within a local plugin's setup. ```php if ($hassiteconfig) { // Create the new settings page // - in a local plugin this is not defined as standard, so normal $settings->methods will throw an error as // $settings will be null $settings = new admin_settingpage('local_[pluginname]', 'Your Settings Page Title'); // Create $ADMIN->add('localplugins', $settings); // Add a setting field to the settings for this page $settings->add(new admin_setting_configtext( // This is the reference you will use to your configuration 'local_[pluginname]/apikey', // This is the friendly title for the config, which will be displayed 'External API: Key', // This is helper text for this config field 'This is the key used to access the External API', // This is the default value 'No Key Defined', // This is the type of Parameter this config is PARAM_TEXT )); } ``` -------------------------------- ### Example upgrade.php File Structure Source: https://github.com/moodle/devdocs/blob/main/docs/guides/upgrade/index.md This example demonstrates the basic structure of an upgrade.php file, including how to check the old version and perform upgrade steps. It utilizes the Moodle DDL manager and xmldb classes. ```php get_manager(); // Loads ddl manager and xmldb classes. if ($oldversion < 2019031200) { // Perform the upgrade from version 2019031200 to the next version. } if ($oldversion < 2019031201) { // Perform the upgrade from version 2019031201 to the next version. } // Everything has succeeded to here. Return true. return true; } ``` -------------------------------- ### Define a Simple API Route Source: https://github.com/moodle/devdocs/blob/main/docs/apis/subsystems/routing/index.md This example demonstrates how to define a basic API route using the \core\router\route attribute. The route's full path is constructed by combining the component, route group prefix, and the defined path. It resolves to a specific URL based on the Moodle installation and route group configuration. ```php namespace mod_example\route\api; use core\router\schema\response\payload_response; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; class example { #[ core\router\route( // Resolves to https://example.com/moodle/api/rest/v2/mod_example/example path: '/example', ) ] public function example_route( ServerRequestInterface $request, ResponseInterface $response, ): ResponseInterface { return new payload_response( request: $request, response: $response, payload: [], ); } } ``` -------------------------------- ### Course Format Renderer Example Source: https://github.com/moodle/devdocs/blob/main/versioned_docs/version-5.2/apis/plugintypes/format/index.md All course format plugins must provide a renderer. This example shows the basic structure for a renderer file. ```php import Renderer from '!!raw-loader!./_examples/renderer.php'; ``` -------------------------------- ### Create a New Upgrade Note with Options Source: https://github.com/moodle/devdocs/blob/main/general/development/upgradenotes.md Pre-fill details for a new upgrade note using command-line arguments. Invalid arguments will still prompt for input. ```bash .grunt/upgradenotes.mjs create \ -i MDL-99999 \ -c core_communication \ -t improved \ -m "Added a new option to call the speaking clock" ``` -------------------------------- ### Install Grunt CLI and Dependencies Source: https://github.com/moodle/devdocs/blob/main/general/development/tools/nodejs.md Install Node.js, use the correct version, install local dependencies via npm, and globally install the Grunt command-line interface (CLI). This prepares the environment for running Grunt tasks. ```bash nvm install && nvm use npm install npm install -g grunt-cli ``` -------------------------------- ### Atto Plugin Directory Layout Example Source: https://github.com/moodle/devdocs/blob/main/docs/apis/plugintypes/atto/index.md Illustrates the typical file structure for an Atto editor plugin, using the `atto_media` plugin as an example. ```console lib/editor/atto/plugins/media |-- db | └-- upgrade.php |-- lang | └-- en | └-- atto_media.php |-- yui | └-- src | └-- button | └-- atto_media.php | ├── build.json | ├── js | │   └── button.js | └── meta | └── button.json |-- settings.php └-- version.php ```