Developing plugins for Moodle Workplace: Difference between revisions
No edit summary |
m (→Behat) |
||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Third party plugins may be developed specifically for Moodle Workplace or they can be developed so they can work on both Moodle LMS and Moodle Workplace. | Third party plugins may be developed specifically for Moodle Workplace or they can be developed so they can work on both Moodle LMS and Moodle Workplace. | ||
=== Strict dependency on Moodle Workplace plugins === | |||
If a plugin is developed to work on Moodle Workplace only, include in [https://docs.moodle.org/dev/version.php version.php] a strict dependency to the Workplace plugin that you need to use in your plugin, for example: | If a plugin is developed to work on Moodle Workplace only, include in [https://docs.moodle.org/dev/version.php version.php] a strict dependency to the Workplace plugin that you need to use in your plugin, for example: | ||
$plugin->dependencies = array( | $plugin->dependencies = array( | ||
'tool_program' => 2022031610, | 'tool_program' => 2022031610, | ||
); | ); | ||
=== Optional dependency on Moodle Workplace plugins === | |||
If you want to include optional code that should be executed only on Moodle Workplace, for example, first you need to check that the relevant Workplace plugin exists, here are some examples of how to do it: | If you want to include optional code that should be executed only on Moodle Workplace, for example, first you need to check that the relevant Workplace plugin exists, here are some examples of how to do it: | ||
// Check that specific class exists: | // Check that specific class exists: | ||
if (class_exists(' | if (class_exists('tool_certification\api')) { | ||
// .... | // .... | ||
} | } | ||
// Check if the specific plugin is installed: | // Check if the specific plugin is installed: | ||
if (\core_component::get_component_directory(' | if (\core_component::get_component_directory('tool_wp')) { | ||
// .... | // .... | ||
} | } | ||
Line 20: | Line 21: | ||
// .... | // .... | ||
} | } | ||
=== Defining conditions and actions for Dynamic rules === | |||
For Dynamic rules you can place classes in folders '''YOURPLUGINDIR/classes/tool_dynamicrule/condition/''' and '''YOURPLUGINDIR/classes/tool_dynamicrule/outcome/''' without defining any dependencies or checking if the plugin exists. These are the "magic" locations and only Dynamic rules plugin will look for classes there, Moodle LMS will ignore these classes. | |||
=== Multi-tenancy callbacks === | |||
For multi-tenancy callbacks it is convenient to use the function '''component_class_callback()''' - this function will return default value if the class or method is not found. This is the best way to filter users list based on multi-tenancy. Quick example: | For multi-tenancy callbacks it is convenient to use the function '''component_class_callback()''' - this function will return default value if the class or method is not found. This is the best way to filter users list based on multi-tenancy. Quick example: | ||
Instead of direct query that looks like that: | Instead of direct query that looks like that: | ||
$sql = "SELECT u.* FROM {user} u WHERE u.deleted = 0"; | $sql = "SELECT u.* FROM {user} u WHERE u.deleted = 0"; | ||
Use the following code: | Use the following code: | ||
$tenantcondition = component_class_callback('tool_tenant\\tenancy', 'get_users_subquery', | $tenantcondition = component_class_callback('tool_tenant\\tenancy', 'get_users_subquery', | ||
[true, true, 'u.id'], '');'' | [true, true, 'u.id'], '');'' | ||
$sql = "SELECT u.* FROM {user} u WHERE $tenantcondition u.deleted = 0" | $sql = "SELECT u.* FROM {user} u WHERE $tenantcondition u.deleted = 0" | ||
When executed on Moodle LMS (without tool_tenant) this will give exactly the same result as the original query. When executed on Workplace a condition will be added to the query filtering users not hidden by multi-tenancy. | When executed on Moodle LMS (without tool_tenant) this will give exactly the same result as the original query. When executed on Workplace a condition will be added to the query filtering users not hidden by multi-tenancy. | ||
Find more examples and explanations in the '''admin/tool/tenant/README.md''' | Find more examples and explanations in the '''admin/tool/tenant/README.md''' | ||
=== Testing === | |||
==== Unittests ==== | |||
You can skip Workplace-only unittests if they are executed on Moodle LMS, for example: | |||
public function test_can_issue_same_tenant() { | |||
// Skip tests if tool_tenant is not present. | |||
if (!class_exists('tool_tenant\tenancy')) { | |||
$this->markTestSkipped('Plugin tool_tenant not installed, skipping'); | |||
} | |||
// Continue Workplace-only testing | |||
} | |||
==== Behat ==== | |||
For Behat tests you can define a custom step in YOURPLUGINDIR/tests/behat/behat_PLUGINNAME.php : | |||
/** | |||
* This step allows to skip scenarios if tool_tenant is not installed | |||
* | |||
* @Given /^plugin PLUGINNAME is installed together with tool_tenant$/ | |||
*/ | |||
public function plugin_is_installed_together_with_tool_tenant() { | |||
if (!\core_component::get_component_directory('tool_tenant')) { | |||
throw new \Moodle\BehatExtension\Exception\SkippedException('Skipping test since tool_tenant is not found'); | |||
} | |||
} | |||
And then use it in the scenarios: | |||
Scenario: Test plugin PLUGINNAME on Workplace | |||
Given plugin PLUGINNAME is installed together with tool_tenant | |||
.... | |||
It is recommended to include the name of your plugin in the step name so that you don't accidentally use the same name as some other plugin. |
Latest revision as of 11:50, 18 May 2022
Third party plugins may be developed specifically for Moodle Workplace or they can be developed so they can work on both Moodle LMS and Moodle Workplace.
Strict dependency on Moodle Workplace plugins
If a plugin is developed to work on Moodle Workplace only, include in version.php a strict dependency to the Workplace plugin that you need to use in your plugin, for example:
$plugin->dependencies = array( 'tool_program' => 2022031610, );
Optional dependency on Moodle Workplace plugins
If you want to include optional code that should be executed only on Moodle Workplace, for example, first you need to check that the relevant Workplace plugin exists, here are some examples of how to do it:
// Check that specific class exists: if (class_exists('tool_certification\api')) { // .... }
// Check if the specific plugin is installed: if (\core_component::get_component_directory('tool_wp')) { // .... }
// Check that specific plugin is installed and the version is bigger than: if (\core_component::get_component_directory('tool_program') && get_config('version', 'tool_plugin') >= 2022031610) { // .... }
Defining conditions and actions for Dynamic rules
For Dynamic rules you can place classes in folders YOURPLUGINDIR/classes/tool_dynamicrule/condition/ and YOURPLUGINDIR/classes/tool_dynamicrule/outcome/ without defining any dependencies or checking if the plugin exists. These are the "magic" locations and only Dynamic rules plugin will look for classes there, Moodle LMS will ignore these classes.
Multi-tenancy callbacks
For multi-tenancy callbacks it is convenient to use the function component_class_callback() - this function will return default value if the class or method is not found. This is the best way to filter users list based on multi-tenancy. Quick example: Instead of direct query that looks like that:
$sql = "SELECT u.* FROM {user} u WHERE u.deleted = 0";
Use the following code:
$tenantcondition = component_class_callback('tool_tenant\\tenancy', 'get_users_subquery', [true, true, 'u.id'], ); $sql = "SELECT u.* FROM {user} u WHERE $tenantcondition u.deleted = 0"
When executed on Moodle LMS (without tool_tenant) this will give exactly the same result as the original query. When executed on Workplace a condition will be added to the query filtering users not hidden by multi-tenancy.
Find more examples and explanations in the admin/tool/tenant/README.md
Testing
Unittests
You can skip Workplace-only unittests if they are executed on Moodle LMS, for example:
public function test_can_issue_same_tenant() { // Skip tests if tool_tenant is not present. if (!class_exists('tool_tenant\tenancy')) { $this->markTestSkipped('Plugin tool_tenant not installed, skipping'); } // Continue Workplace-only testing }
Behat
For Behat tests you can define a custom step in YOURPLUGINDIR/tests/behat/behat_PLUGINNAME.php :
/** * This step allows to skip scenarios if tool_tenant is not installed * * @Given /^plugin PLUGINNAME is installed together with tool_tenant$/ */ public function plugin_is_installed_together_with_tool_tenant() { if (!\core_component::get_component_directory('tool_tenant')) { throw new \Moodle\BehatExtension\Exception\SkippedException('Skipping test since tool_tenant is not found'); } }
And then use it in the scenarios:
Scenario: Test plugin PLUGINNAME on Workplace Given plugin PLUGINNAME is installed together with tool_tenant ....
It is recommended to include the name of your plugin in the step name so that you don't accidentally use the same name as some other plugin.