|
| 1 | +--- |
| 2 | +title: Composer support for plugins |
| 3 | +tags: |
| 4 | + - Composer |
| 5 | + - Plugins |
| 6 | + - Package management |
| 7 | +description: How to make your Moodle plugin available via Composer, and developer tips for working with Composer-based Moodle sites. |
| 8 | +--- |
| 9 | + |
| 10 | +<Since version="5.2" issueNumber="MDL-87473" /> |
| 11 | + |
| 12 | +Moodle 5.2 introduced native support for distributing and installing Moodle plugins using [Composer](https://getcomposer.org/), the PHP package manager. Plugin developers can publish their plugins to [Packagist](https://packagist.org/) and site administrators can install them with a simple `composer require` command. |
| 13 | + |
| 14 | +The [moodle/composer-installer](https://github.com/moodle/composer-installer) Composer plugin handles placing each Moodle plugin package into the correct location within the Moodle directory structure, based on the plugin type declared in the package's `composer.json`. |
| 15 | + |
| 16 | +## Making your plugin available via Composer |
| 17 | + |
| 18 | +### Adding a composer.json |
| 19 | + |
| 20 | +Add a `composer.json` file to the root of your plugin directory with at minimum the following fields: |
| 21 | + |
| 22 | +- `name`: the Composer package name, where the package component follows the format `moodle-[plugintype]_[pluginname]` (for example, `myplugin/moodle-block_myblock`) |
| 23 | +- `type`: the Moodle plugin type in the format `moodle-[plugintype]` (for example, `moodle-block`) |
| 24 | +- `require`: the Moodle version requirement, to communicate which versions your plugin supports |
| 25 | + |
| 26 | +In `require`, include a production dependency on `moodle/composer-installer`. |
| 27 | + |
| 28 | +```json title="composer.json" |
| 29 | +{ |
| 30 | + "name": "myplugin/moodle-block_myblock", |
| 31 | + "description": "A description of my Moodle block plugin", |
| 32 | + "type": "moodle-block", |
| 33 | + "require": { |
| 34 | + "moodle/moodle": "^5.2", |
| 35 | + "moodle/composer-installer": "*" |
| 36 | + }, |
| 37 | + "license": "GPL-3.0-or-later" |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +The `type` field is what the `moodle/composer-installer` package uses to determine the installation path. For example, a package with `"type": "moodle-block"` will be installed into `blocks/myblock/` within the Moodle directory. |
| 42 | + |
| 43 | +:::tip Vendor name |
| 44 | + |
| 45 | +The vendor prefix in the `name` field (for example, `myplugin`) is your Packagist vendor name and is independent of any Moodle conventions. The package name component (`moodle-block_myblock`) follows the Moodle convention. |
| 46 | + |
| 47 | +::: |
| 48 | + |
| 49 | +### Publishing to Packagist |
| 50 | + |
| 51 | +Once your plugin has a valid `composer.json` and is in a public Git repository, you can publish it to [Packagist](https://packagist.org/): |
| 52 | + |
| 53 | +1. Visit [https://packagist.org/packages/submit](https://packagist.org/packages/submit) and submit your repository URL. |
| 54 | +2. Set up a [GitHub webhook](https://packagist.org/about#how-to-update-packages) to keep Packagist in sync whenever you push to your repository. |
| 55 | + |
| 56 | +Once published, site administrators can install your plugin with: |
| 57 | + |
| 58 | +```bash |
| 59 | +composer require myplugin/moodle-block_myblock |
| 60 | +``` |
| 61 | + |
| 62 | +The installer will automatically place the plugin into `blocks/myblock/` within their Moodle directory. |
| 63 | + |
| 64 | +## Development tips |
| 65 | + |
| 66 | +### Creating a development Moodle site |
| 67 | + |
| 68 | +The [moodle/seed](https://github.com/moodle/seed) project provides a quick way to spin up a new Moodle site using Composer. This is particularly useful for plugin developers who want a reproducible development environment. |
| 69 | + |
| 70 | +```bash |
| 71 | +composer create-project moodle/seed [yourlocation] |
| 72 | +``` |
| 73 | + |
| 74 | +The Moodle scaffolding tool will guide you through the initial site configuration. Within your `[yourlocation]` directory you will find: |
| 75 | + |
| 76 | +- a `composer.json` and `composer.lock` |
| 77 | +- a `vendor/` directory |
| 78 | +- a `moodle/` directory containing your Moodle installation |
| 79 | + |
| 80 | +To target a specific version of Moodle: |
| 81 | + |
| 82 | +```bash |
| 83 | +cd [yourlocation] |
| 84 | +composer require "moodle/moodle:~5.2.0" |
| 85 | +``` |
| 86 | + |
| 87 | +To install a plugin from Packagist: |
| 88 | + |
| 89 | +```bash |
| 90 | +cd [yourlocation] |
| 91 | +composer require myplugin/moodle-block_myblock |
| 92 | +``` |
| 93 | + |
| 94 | +### Developing a plugin with a local path repository |
| 95 | + |
| 96 | +When working on your plugin locally, you can tell Composer to use your local checkout instead of downloading from Packagist by adding a `path` repository to your site's `composer.json`: |
| 97 | + |
| 98 | +```json title="composer.json (Moodle site root)" |
| 99 | +{ |
| 100 | + "repositories": [ |
| 101 | + { |
| 102 | + "type": "path", |
| 103 | + "url": "/path/to/your/local/moodle-block_myblock", |
| 104 | + "options": { |
| 105 | + "symlink": false |
| 106 | + } |
| 107 | + } |
| 108 | + ], |
| 109 | + "require": { |
| 110 | + "moodle/composer-installer": "*", |
| 111 | + "myplugin/moodle-block_myblock": "*" |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +Do not use symlinked plugin paths with Moodle. Many PHP entry points in plugins (for example, `view.php` and `index.php`) include `config.php` using relative paths like `require_once('../../config.php')`. With symlinked plugins, PHP resolves the symlink target first, which can make those relative includes resolve outside your Moodle site. |
| 117 | + |
| 118 | +Set `"symlink": false` so Composer mirrors (copies) the plugin into the Moodle tree instead of symlinking it. This avoids relative include path issues. |
| 119 | + |
| 120 | +When developing with a mirrored path repository, re-run `composer update myplugin/moodle-block_myblock` (or remove and re-require the package) after local changes so the copied plugin is refreshed. |
| 121 | + |
| 122 | +:::note |
| 123 | + |
| 124 | +For local path repositories, use `"*"` or `"@dev"` in your `require` constraint so Composer can resolve your local development version regardless of tagged releases. |
| 125 | + |
| 126 | +::: |
| 127 | + |
| 128 | +### Declaring dependencies |
| 129 | + |
| 130 | +:::caution Current recommendation |
| 131 | + |
| 132 | +Moodle currently supports plugins installed both with Composer and without Composer. Composer-declared runtime dependencies are only guaranteed to be installed when the plugin itself is installed via Composer. |
| 133 | + |
| 134 | +For now, avoid introducing Composer-only runtime dependencies that would break non-Composer plugin installs. |
| 135 | + |
| 136 | +::: |
| 137 | + |
| 138 | +When adding Composer metadata to your plugin, these dependency rules apply: |
| 139 | + |
| 140 | +- You can declare dependencies on other Moodle plugins as Composer package requirements. |
| 141 | +- You should declare a production dependency on `moodle/composer-installer` in `require` (not `require-dev`) so Moodle package types are installed into the correct locations. |
| 142 | + |
| 143 | +```json title="composer.json with Moodle package dependencies" |
| 144 | +{ |
| 145 | + "name": "myplugin/moodle-block_myblock", |
| 146 | + "type": "moodle-block", |
| 147 | + "require": { |
| 148 | + "moodle/moodle": "^5.2", |
| 149 | + "moodle/composer-installer": "*", |
| 150 | + "abgreeve/moodle-block_stash": "^5.2" |
| 151 | + }, |
| 152 | + "license": "GPL-3.0-or-later" |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +If your plugin has required Moodle plugin dependencies, continue to declare them in `version.php` too, so dependency checks also work for non-Composer installation workflows. |
| 157 | + |
| 158 | +## See also |
| 159 | + |
| 160 | +- [`composer.json`](../../apis/commonfiles/index.mdx#composerjson) — common file reference for Moodle plugins |
| 161 | +- [moodle/composer-installer](https://github.com/moodle/composer-installer) — the Composer plugin that installs Moodle packages into the correct directory |
| 162 | +- [moodle/seed](https://github.com/moodle/seed) — a Composer project template for spinning up a new Moodle site |
| 163 | +- [Packagist](https://packagist.org/) — the main Composer package repository |
| 164 | +- [Composer documentation](https://getcomposer.org/doc/) — full Composer reference |
0 commit comments