Note: You are currently viewing documentation for Moodle 3.9. Up-to-date documentation for the latest stable version of Moodle may be available here: Local customisation.

Development:Local customisation: Difference between revisions

From MoodleDocs
 
(88 intermediate revisions by 14 users not shown)
Line 1: Line 1:
== General customisations ==
{{Infobox Project
|name = Local customisations
|state = Implemented
|tracker = MDL-17376, MDL-16438
|discussion = http://moodle.org/mod/forum/discuss.php?d=126017 http://moodle.org/mod/forum/discuss.php?d=86903
|assignee = [[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]], some parts were originally proposed and implemented in 1.9 by Penny Leach
}}
{{Moodle 2.0}}


Moodle has been designed with extensibility in mind. There are many plug-in points available though out Moodle to allow developers add new functionality to Moodle without modifying core code.
The recommended way to add new functionality to Moodle is to create a new standard plugin (module, block, auth, enrol, etc.).The /local/ plugins are mostly suitable for things that do not fit standard plugins.


See the [[Developer_documentation#Make_a_new_plugin|make a new plugin section of the Developer documentation page]] for the different plugin types available, and documentation on how to develop for them.
== Custom /local/ plugins ==


== local/ folder for 'hacky' customisations ==
Local plugins are used in cases when no standard plugin fits, examples are:
* event consumers communicating with external systems
* custom definitions of web services and external functions
* applications that extend moodle at the system level (hub server, amos server, etc.)
* new database tables used in core hacks (discouraged)
* new capability definitions used in core hacks
* custom admin settings
* extending the navigation block with custom menus [http://moodle.org/mod/forum/discuss.php?d=170325&parent=753095]


Sometimes it is not possible to use the available plug-in points to make your change. In situations like this then the local folder is for you. The idea is that instead of scattering your changes throughout the code base, you put them all in a folder called 'local'. Using this folder means you won't have to deal with merging problems when you upgrade the rest of your Moodle installation.
=== Standard plugin features: ===
* /local/xxx/version.php - version of script (must be incremented after changes)
* /local/xxx/db/install.xml - executed during install (new version.php found)
* /local/xxx/db/install.php - executed right after install.xml
* /local/xxx/db/uninstall.php - executed during uninstallation
* /local/xxx/db/upgrade.php - executed after version.php change
* /local/xxx/db/access.php - definition of capabilities
* /local/xxx/db/events.php - event handlers and subscripts
* /local/xxx/db/messages.php - messaging registration
* /local/xxx/db/external.php - web services and external functions descriptions
* /local/xxx/lang/en/local_pluginname.php - language file


The local folder has some of the plug-in points available which are available to other modules. Perhaps most useful the local/db/ folder can be used to make database schema changes and custom role permissions.
The ''xxx'' is used instead of your local plugin name, plugins of the same type are installed/upgraded in alphabetical order.


However, using the local folder should be absolutely the last resort. Long term, you will almost certainly find it easier to maintain your changes if you can package them up as one of the standard types of plugins.
=== List of differences from normal plugins: ===
* always executed last during install/upgrade - guaranteed by order of plugins in <code>get_plugin_types()</code>
* are expected to use event handlers - events are intended for communication core-->plugins only, local plugins are the best candidates for event handlers
* can add admin settings to any settings page - loaded last when constructing admin tree
* do not need to have any UI - other plugins are usually visible somewhere
* some extra hooks (not implemented yet)


=== Local database changes and version ===
== /local/xxx/db/messages.php ==
Example File Structure:
<code php>
<?php


If you need to make local database customisations that are not easily encapsulated by a block or module, Moodle does support the use of a local db upgrade script, and local version number.
/**
* Defines message providers (types of messages being sent)
*
* @package mod-forum
* @copyright  1999 onwards  Martin Dougiamas  http://moodle.com
* @license  http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


This is almost exactly the same as every other db/upgrade.php and version.php except for the following points:
$messageproviders = array (


==== local/version.php ====
/// Ordinary single forum posts
    'posts' => array (
    )


local/version.php must look like:
);
</code>


<code php>
== Other /local/ customisation files==
$local_version = 2008121700;
</code>


==== local/db/install.xml ====
===Customised site defaults===  


Local/ has no install.xml - only an upgrade.php. This is because often the changes that you want to make are not full tables, but just extra columns, and a local install.xml makes less sense than just upgrade.php.
Different default site settings can be stored in file /local/defaults.php.
These new defaults are used during installation, upgrade and later are
==== local/db/upgrade.php ====
displayed as default values in admin settings. This means that the content
of the defaults files is usually updated BEFORE installation or upgrade.


local/db/upgrade.php must look like:
These customised defaults are useful especially when using CLI tools
for installation and upgrade.


Sample /local/defaults.php file content:
<code php>
<code php>
function xmldb_local_upgrade($oldversion) {
<?php
    global $CFG, $db;
$defaults['moodle']['forcelogin'] = 1;  // new default for $CFG->forcelogin
 
$defaults['scorm']['maxgrade'] = 20;   // default for get_config('scorm', 'maxgrade')
    $result = true;
$defaults['moodlecourse']['numsections'] = 11;
 
$defaults['moodle']['hiddenuserfields'] = array('city', 'country');
    if ($result && $result < 2008121700) {
        $result = $result && create_table($table);
    }
    return $result;
}
</code>
</code>
First bracket contains string from column plugin of config_plugins table.
Second bracket is the name of setting. In the admin settings UI the plugin and
name of setting is separated by "|".


=== Local post-installation data insertion ===
The values usually correspond to the raw string in config table, with the exception
of comma separated lists that are usually entered as real arrays.


In discussion - see http://tracker.moodle.org/browse/MDL-17440
Please note that not all settings are converted to admin_tree,
they are mostly intended to be set directly in config.php.


=== Local capabilities ===
=== 2.0 pre-upgrade script===


Just like core and modules, Moodle supports the use of a db/access.php inside local/ to define local capabilities.
You can use /local/upgrade_pre20.php script for any code that needs to
be executed before the main upgrade to 2.0. Most probably this will
be used for undoing of old hacks that would otherwise break normal
2.0 upgrade.


The formatting is exactly the same as the other db/access.php scripts  - an array keyed by capability name, containing arrays of capability data, like so:
This file is just included directly, there does not need to be any
function inside. If the execution stops the script is executed again
during the next upgrade. The first execution of lib/db/upgrade.php
increments the version number and the pre upgrade script is not
executed any more.


<code php>
== Customisations outside of /local/ directory==  
$local_capabilities = array(
    'moodle/local:capability' => array(
        'captype'      => 'write',
        'contextlevel' => CONTEXT_SYSTEM,
        'riskbitmask'  => RISK_SPAM,
    ),


</code>
=== Forced settings===


Sometimes it is useful to force some settings and prevent any changes of these settings via the standard admin UI. It is possible to hardcode these settings in config.php.


Note that for all local capabilities you add, you'll need to add language strings.
In case of course settings it is very simply, the values are assigned directly to $CFG properties. In case of plugins the values are specified in a multidimensional array in $CFG->force_plugin_settings.
Moodle will expect to find them in local/lang/en_utf8/local.php (eg for English)
with a key (following the above example) of local:capability
 
=== Local event subscriptions ===
 
''' Pending commit '''
 
It is often very helpful to be able to write custom code that subscribes to normal events that Moodle throws.  It's also handy to be able to throw and catch your own custom events, as the Event API provides a very handy mechanism to do signal handling.
 
Local event handlers get registered at install/upgrade time just as the event handlers for modules do.  To trigger an update when you add a new event handler, you must bump the local version number.
 
Event handlers must be defined in an array, keyed by event name, with each entry in the array information about the handler, like so:


Sample code in config.php
<code php>
<code php>
    $handlers = array(
$CFG->allowobjectembed = 0;
        'some_core_event'     => array(           // eg 'user_created'
$CFG->forced_plugin_settings = array('page'=>array('displayoptions'=>5, 'requiremodintro'=>1), 'folder'=>'requiremodintro'=>1);
            'handlerfile'    => '/local/lib.php', // example
            'handlerfunction' => 'local_user_create_handler',
            'schedule'       => 'cron'
        )
    );
</code>
</code>


=== Local admin menu items and settings ===
=== Local language customisations===  
 
You can add extra configuration items to Moodle by creating a file, local/settings.php which accesses the $ADMIN variable directly and adds new items to it.  This will make them appear in the site administration block on the homepage, and create the config options that administrators can change.  You can also add whole new custom config pages (admin_externalpage).  For example:


Moodle supports other type of local customisation of standard language
packs. If you want to create your own language pack based on another
language create new dataroot directory with "_local" suffix, for example
following file with content changes string "Login" to "Sign in":
moodledata/lang/en_local
<code php>
<code php>
<?php
  $string['login'] = 'Sign in';
</code>
See also https://docs.moodle.org/en/Language_editing


$ADMIN->add('root', new admin_category($name, $title);
=== Custom script injection===
$ADMIN->add('foo', new admin_externalpage($name, $title, $url, $cap);


</code>
Very old customisation option that allows you to modify scripts by injecting
code right after the require 'config.php' call.


=== Local backup and restore hooks ===
This setting is enabled by manually setting $CFG->customscripts variable
in config.php script. The value is expected to be full path to directory
with the same structure as dirroot. Please note this hack only affects
files that actually include the config.php!


In discussion - see http://tracker.moodle.org/browse/MDL-17444
; Examples:
* disable one specific moodle page without code modification
* alter page parameters on the fly


=== Local course deletion hook ===
=== Direct code modifications===  
This is usually the last resort, if possible do not do it. And if you still do it use some version control system (preferably git).


=== Local my moodle overrides ===
=== Direct database modifications===  
Very strongly discouraged! Sometimes field lengths may be modified without side effects. Adding or removing of db fields will most probably cause major problems during future upgrades. New database tables should be added only from plugins.


=== Local stickyblocks targets ===
== Local customisations in previous versions ==
Previous versions include only partial support for customisations in /local/ directory.


=== Local user profile view hook ===
=== List of local customisations in 1.9.x: ===
* /local/cron.php - custom cron jobs
* /local/settings.php - custom admin settings
* /local/db/upgrade.php - general modifications
* /local/lang/* - custom strings
* /local/lib.php - local_delete_course()


=== Local language strings ===
=== Migration from old 1.9.x /local/: ===
* <code>local/*</code> needs to be copied to new directory
* <code>local/xxxx/db/install.php</code> is intended for first installation, originally everything was in upgrade.php
* events are used instead of hooks
* upgrade code needs to migrate old settings, events, etc. directly in core db tables - such as change component strings and capability names from db/install.php or manually before/after upgrade


==See also==
==See also==


*[http://cvs.moodle.org/moodle/lib/locallib.php?view=markup CVS:moodle/lib/locallib.php]
* [http://moodle.org/mod/forum/discuss.php?d=170325&parent=753095 Extending navigation block]
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=86903 Local Customisations] forum discussion
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=86903 Local Customisations] forum discussion
* http://cvs.moodle.org/moodle/local/readme.txt?view=markup
* [[Local customisation (Moodle 1.9)]]


[[Category:Developer|Local customisation]]
[[Category:Developer|Local customisation]]

Latest revision as of 20:51, 7 April 2011

Template:Infobox Project Template:Moodle 2.0

The recommended way to add new functionality to Moodle is to create a new standard plugin (module, block, auth, enrol, etc.).The /local/ plugins are mostly suitable for things that do not fit standard plugins.

Custom /local/ plugins

Local plugins are used in cases when no standard plugin fits, examples are:

  • event consumers communicating with external systems
  • custom definitions of web services and external functions
  • applications that extend moodle at the system level (hub server, amos server, etc.)
  • new database tables used in core hacks (discouraged)
  • new capability definitions used in core hacks
  • custom admin settings
  • extending the navigation block with custom menus [1]

Standard plugin features:

  • /local/xxx/version.php - version of script (must be incremented after changes)
  • /local/xxx/db/install.xml - executed during install (new version.php found)
  • /local/xxx/db/install.php - executed right after install.xml
  • /local/xxx/db/uninstall.php - executed during uninstallation
  • /local/xxx/db/upgrade.php - executed after version.php change
  • /local/xxx/db/access.php - definition of capabilities
  • /local/xxx/db/events.php - event handlers and subscripts
  • /local/xxx/db/messages.php - messaging registration
  • /local/xxx/db/external.php - web services and external functions descriptions
  • /local/xxx/lang/en/local_pluginname.php - language file

The xxx is used instead of your local plugin name, plugins of the same type are installed/upgraded in alphabetical order.

List of differences from normal plugins:

  • always executed last during install/upgrade - guaranteed by order of plugins in get_plugin_types()
  • are expected to use event handlers - events are intended for communication core-->plugins only, local plugins are the best candidates for event handlers
  • can add admin settings to any settings page - loaded last when constructing admin tree
  • do not need to have any UI - other plugins are usually visible somewhere
  • some extra hooks (not implemented yet)

/local/xxx/db/messages.php

Example File Structure: <?php

/**

* Defines message providers (types of messages being sent)
*
* @package mod-forum
* @copyright  1999 onwards  Martin Dougiamas  http://moodle.com
* @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$messageproviders = array (

/// Ordinary single forum posts

   'posts' => array (
   )

);

Other /local/ customisation files

Customised site defaults

Different default site settings can be stored in file /local/defaults.php. These new defaults are used during installation, upgrade and later are displayed as default values in admin settings. This means that the content of the defaults files is usually updated BEFORE installation or upgrade.

These customised defaults are useful especially when using CLI tools for installation and upgrade.

Sample /local/defaults.php file content: <?php $defaults['moodle']['forcelogin'] = 1; // new default for $CFG->forcelogin $defaults['scorm']['maxgrade'] = 20; // default for get_config('scorm', 'maxgrade') $defaults['moodlecourse']['numsections'] = 11; $defaults['moodle']['hiddenuserfields'] = array('city', 'country'); First bracket contains string from column plugin of config_plugins table. Second bracket is the name of setting. In the admin settings UI the plugin and name of setting is separated by "|".

The values usually correspond to the raw string in config table, with the exception of comma separated lists that are usually entered as real arrays.

Please note that not all settings are converted to admin_tree, they are mostly intended to be set directly in config.php.

2.0 pre-upgrade script

You can use /local/upgrade_pre20.php script for any code that needs to be executed before the main upgrade to 2.0. Most probably this will be used for undoing of old hacks that would otherwise break normal 2.0 upgrade.

This file is just included directly, there does not need to be any function inside. If the execution stops the script is executed again during the next upgrade. The first execution of lib/db/upgrade.php increments the version number and the pre upgrade script is not executed any more.

Customisations outside of /local/ directory

Forced settings

Sometimes it is useful to force some settings and prevent any changes of these settings via the standard admin UI. It is possible to hardcode these settings in config.php.

In case of course settings it is very simply, the values are assigned directly to $CFG properties. In case of plugins the values are specified in a multidimensional array in $CFG->force_plugin_settings.

Sample code in config.php $CFG->allowobjectembed = 0; $CFG->forced_plugin_settings = array('page'=>array('displayoptions'=>5, 'requiremodintro'=>1), 'folder'=>'requiremodintro'=>1);

Local language customisations

Moodle supports other type of local customisation of standard language packs. If you want to create your own language pack based on another language create new dataroot directory with "_local" suffix, for example following file with content changes string "Login" to "Sign in": moodledata/lang/en_local <?php

 $string['login'] = 'Sign in';

See also https://docs.moodle.org/en/Language_editing

Custom script injection

Very old customisation option that allows you to modify scripts by injecting code right after the require 'config.php' call.

This setting is enabled by manually setting $CFG->customscripts variable in config.php script. The value is expected to be full path to directory with the same structure as dirroot. Please note this hack only affects files that actually include the config.php!

Examples
  • disable one specific moodle page without code modification
  • alter page parameters on the fly

Direct code modifications

This is usually the last resort, if possible do not do it. And if you still do it use some version control system (preferably git).

Direct database modifications

Very strongly discouraged! Sometimes field lengths may be modified without side effects. Adding or removing of db fields will most probably cause major problems during future upgrades. New database tables should be added only from plugins.

Local customisations in previous versions

Previous versions include only partial support for customisations in /local/ directory.

List of local customisations in 1.9.x:

  • /local/cron.php - custom cron jobs
  • /local/settings.php - custom admin settings
  • /local/db/upgrade.php - general modifications
  • /local/lang/* - custom strings
  • /local/lib.php - local_delete_course()

Migration from old 1.9.x /local/:

  • local/* needs to be copied to new directory
  • local/xxxx/db/install.php is intended for first installation, originally everything was in upgrade.php
  • events are used instead of hooks
  • upgrade code needs to migrate old settings, events, etc. directly in core db tables - such as change component strings and capability names from db/install.php or manually before/after upgrade

See also