Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Callbacks: Difference between revisions

From MoodleDocs
Line 494: Line 494:
|-
|-
| questions_in_use
| questions_in_use
| mod
| *
|  
| since 3.7.5, 3.8.2 (previously only "mod")
|  
|  
|-  
|-  

Revision as of 17:00, 19 February 2020

Moodle does not have well-defined Hooks API but still allows plugins to hook into different processes by implementing callbacks. See also Communication Between Components.

Some old APIs that were created before object-oriented programming use only callbacks. One of them is Activity modules.

Types of callbacks in Moodle

Callback functions one-to-many

Core has a "hook point" where it allows plugins to execute some code, modify variables or return a result. Sometimes (especially for old callbacks) only plugins of a specific plugin type are allowed, however this is not recommended for the new callbacks because the list of callbacks is now cached and performance is not a constraint any more. If plugins want to implement the function for this callback they normally must place it in lib.php with the name pluginfullname_callbackname(). Here pluginname should be a full plugin name with a prefix, however activity modules can often omit the "mod_" prefix for historical reasons. Implementing this type of callback is optional and the "hook point" does not care how many and which plugins implement callback. Also "hook point" does not check if the plugin is enabled on this site, inside the callback plugins must check it themselves if it is important. Methods get_plugin_list_with_function() and get_plugins_with_function() are normally used in the "hook points" to find all plugins implementing a callback.

This document aims to cover ALL callbacks of this type that are present in Moodle core APIs or in standard Moodle plugins.

Callback functions one-to-one

Core API (or plugins such as blocks or reports) looks for and executes a method from the plugin/component that "owns" some entity, usually for checking permissions, pre-processing or providing the human-readable representation of this entity. Similar to one-to-many callbacks, the component/plugin must define a function with the name pluginfullname_callbackname() in lib.php . In some cases the function must be present or otherwise an exception is thrown or debugging message is displayed. Methods component_callback() and component_callback_exists() are normally used to find an implementation of a callback. Unlike one-to-many callbacks the implementing functions can exist not only in plugins but also in core components.

The list of one-to-one callbacks may not be 100% complete in this document, the aim is to cover the "magic" functions that are actually used despite IDE hints.

Other

  • Files in the specific location. Core APIs may look for plugins that have a file with a specific file name, for example version.php, settings.php, styles.css, module.js, files in db/ folder, etc. See Plugin files
  • Event observers. Each plugin can implement event observers that execute code when event is triggered. See Events API about how to listen to events. Event observers can not always substitute callbacks because they do not return any value and can only happen in case of event. Many "hook points" are necessary before something has happened or when nothing is happening at all, for example a report/summary is gathered. However if it is possible to achieve the desired outcome with event observer, Moodle will not accept requests for adding a "hook point".
  • Callbacks that are specified in the db/* file, for example in db/service.php developers must specify callback responsible for implementing web service, in db/tags.php developers specify callback for finding tagged items, etc. These types of callbacks are not covered on this page, information about them can be found in the respective APIs.

Callbacks and external / webservices / consumers (mobile / apps) support

The problem

Our external functions are able to perform a lot of actions against core. Those external functions use to implement their functionality reusing Core APIs. And, those APIs can contain hook points/callbacks to customize Moodle behavior.

Of course, ultimately, those external functions are used by the web services layer providing all the functionality over REST/XMLRCP/SOAP "protocols". All those "clients" consuming Moodle Webservices (integrations in general, mobile & desktop apps...) should work ok, and we must guarantee that all the code executed in those underlying external functions (that may include hook points/callbacks) is supported by them.

In the other side, some of those callbacks may be focussed entirely in the web version of Moodle and have no application outside from there. Also, sometime, there are callbacks which goal is incompatible with uses from web service consumers, mainly because the consumers don't support this or that Moodle functionality used by the callback implementations.

Imagine a callback that provides to the consumer with something that it's not able to manage (say a mustache template, or a moodle form, or any other stuff in general that only core is able to provide). It's a pretty "possible" case a we need a way to handle it in an organised way.

The solution

To be able advance with those "problematic" hooks (not being supported by web-service consumers), it has been agreed to proceed with the following points in order to allow them to work via web, avoiding them to impact to consumers and registering the need of introducing (future) viable solutions to enable consumers to work with them.

All the following points must be considered as real requirements in order to allow a new callback (called from externals/web services) to land to core.

  1. Create a linked MOBILE issue requesting the callback to be supported in the app (for the record and future reference). Clearly explaining which are the externals / web services affected, what should be supported and, ideally, a way to provide that.
  2. Clearly indicate in the issue introducing the new callback if the hook is supported or not via WebServices. Callbacks documentation (below in this page) must include the comment "Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-xxxx and MOBILE-xxxx for more info."" (where the MDL and MOBILE issues are the related ones).
  3. Add manual tests in the issue for checking that the related functionality in the mobile / desktop app is not broken and everything continues working ok.
  4. Check that the modified code or APIs do not impact on the external / WebServices API. You can just check if the modified function is used by the external API just adding a debug message and then running WebServices.
  5. If you need to add code in an API already used by the external API, you can always use the WS_SERVER constant to check if the current request comes from the WS layer to avoid its execution. With links to the corresponding MDL-xxxx and MOBILE-xxxx issues.
  6. In any case, it's the responsibility of every plugin implementing a not compatible callback to prevent any action that may affect / impact the WS layer. Core (hook points) will always perform the calls to the callbacks, unconditionally.

List of Moodle callbacks

List of one-to-many callbacks

To implement one of these callbacks plugins must add a function pluginfullname_callbackname() in lib.php unless stated otherwise. The pluginfullname is the name of the plugin with the frankenstyle prefix. For activity modules it is acceptable to omit the mod_ prefix. Refer to the linked documentation or search Moodle code by the callback name to find where it is called, what arguments are supplied and what return value is expected.

Callback Plugin type Version Comments
Navigation, see Navigation API
extend_navigation_course * before Moodle 3.0 was only supported by report and tool plugin types
extend_settings_navigation local, booktool Note, modules have a one-to-one callback with the same name, see below
extend_navigation local Note, modules have a one-to-one callback with the same name, see below
extend_navigation_user_settings * 3.0+ before Moodle 3.0 was only supported by tool plugin types
extend_navigation_category_settings * 3.0+
extend_navigation_frontpage * 3.1+
extend_navigation_user * 3.1+
Before-actions hooks
course_module_background_deletion_recommended * 3.2+ see upgrade.txt
pre_block_delete * 3.1+
pre_course_category_delete * 3.1+
pre_course_delete * 3.1+
pre_course_module_delete * 3.1+
pre_user_delete * 3.1+
Login_callbacks
after_config * 3.8+ Triggered as soon as practical on every moodle bootstrap after config has been loaded. The $USER object is available at this point too.
after_require_login * 3.7+ eg Add permissions logic across a site or course
check_password_policy * 3.6+
print_password_policy * 3.8+ (WIP)
pre_signup_requests * 3.5 eg to do actions before sign up such as acceptance of policies, validations, etc
extend_change_password_form * 3.8+ (WIP) eg Injecting form elements into the change password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
extend_set_password_form * 3.8+ (WIP) eg Injecting form elements into the set password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
extend_forgot_password_form * 3.8+ (WIP) eg Injecting form elements into the forgot password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
extend_signup_form * 3.8+ (WIP) eg Injecting form elements into the signup form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
validate_extend_change_password_form * 3.8+ (WIP) eg Adding additional validation to the change password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
validate_extend_set_password_form * 3.8+ (WIP) eg Adding additional validation to the set password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
validate_extend_forgot_password_form * 3.8+ (WIP) eg Adding additional validation to the forgot password form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
validate_extend_signup_form * 3.8+ (WIP) eg Adding additional validation to the signup form. Note: This hook is not compatible with the Webservices API or the Moodle mobile app. See MDL-66173 and MOBILE-3181 for more info.
post_change_password_requests * 3.8+ (WIP) eg Fire additional actions after a user changes password.
post_set_password_requests * 3.8+ (WIP) eg Fire additional actions after a user resets password.
post_forgot_password_requests * 3.8+ (WIP) eg Fire additional actions after a user submits a password reset request.
post_signup_requests * 3.8+ (WIP) eg Fire additional actions after a user creates an account.
Page rendering, see Output_callbacks
add_htmlattributes * 3.3+ eg Add open graph xml namespace attributes
before_footer * 3.3+ eg injecting JS across the site, like analytics
before_http_headers * 3.3+ Setting http headers across the site like CSP
before_standard_html_head * 3.3+ A better API alternative to appending to $CFG->additionalhtmlhead
before_standard_top_of_body_html * 3.3+
render_navbar_output * 3.2+
Course module edit form
coursemodule_edit_post_actions * 3.1+
coursemodule_standard_elements * 3.1+
coursemodule_validation * 3.1+
Modules
check_updates_since mod 3.2+ See NEWMODULE_Documentation
dndupload_register mod
Admin
bulk_user_actions * 3.9+ Any plugin typically an admin tool can add new bulk user actions
Other
get_fontawesome_icon_map * 3.3+ https://docs.moodle.org/dev/Moodle_icons#Font_awesome_icons
get_question_bank_search_conditions local
oauth2_system_scopes * 3.3+
rss_get_feed *
supports_logstore report
get_shortcuts ltisource 3.1+
before_launch ltisource 2.8+
control_view_profile * 3.6+
store_profiling_data * 3.6+
override_webservice_execution * 3.6+
Deprecated
cron * See Task API
delete_course mod,report,coursereport,format Replace with observer to course_contents_deleted event
print_overview mod up to 3.2 New dashboard uses Calendar API to populate events on the timeline
report_extend_navigation coursereport Plugin type coursereport is deprecated, plugin type report should be used instead

Notes:

if Moodle version is not specified, this means that callback existed for a long time and can be found in all currently supported Moodle versions

List of one-to-one callbacks

To implement one of these callbacks plugins must add a function pluginfullname_callbackname() in lib.php unless stated otherwise. The pluginfullname is the name of the plugin with the frankenstyle prefix. For activity modules it is acceptable to omit the mod_ prefix. Refer to the linked documentation or search Moodle code by the callback name to find where it is called, what arguments are supplied and what return value is expected.

Callback Plugin type Version Comments
Comments support, see Comment API
comment_add *
comment_display *
comment_permissions *
comment_template *
comment_url *
comment_validate *
Gradebook
export_%_settings_definition gradeexport % is a plugin name without prefix
import_%_settings_definition gradeimport % is a plugin name without prefix
report_%_profilereport gradereport % is a plugin name without prefix
report_%_settings_definition gradereport % is a plugin name without prefix
Groups support, see Groups API
allow_group_member_remove *
restore_group_member * For plugins that create their own groups
Installation and upgrade
xmldb_%_install * Located in db/install.php , % refer to the full plugin name, in case of modules without prefix
xmldb_%_install_recovery * Located in db/install.php , % refer to the full plugin name, in case of modules without prefix
xmldb_%_uninstall * Located in db/uninstall.php , % refer to the full plugin name, in case of modules without prefix
xmldb_%_upgrade * Located in db/upgrade.php , % refer to the full plugin name, in case of modules without prefix
LTI source
add_instance_hook ltisource
messagetype ltisource Callback name is the type of the message
Question bank support, see Question API
question_list_instances mod
question_pluginfile *
question_preview_pluginfile *
questions_in_use * since 3.7.5, 3.8.2 (previously only "mod")
Ratings support, see Rating API
rating_can_see_item_ratings * 2.9.2+
rating_can_see_item_ratings * 2.9.2+
rating_get_item_fields *
rating_permissions *
rating_validate *
Themes
$THEME->csspostprocess theme
$THEME->extralesscallback theme
$THEME->lessvariablescallback theme
page_init theme
Modules: Calendar and dashboard
core_calendar_event_action_shows_item_count mod 3.3+
core_calendar_is_event_visible mod 3.3+
core_calendar_provide_event_action mod 3.3+
Modules: Course cache
cm_info_dynamic mod
cm_info_view mod
get_coursemodule_info mod
Modules: Course reset
reset_course_form_defaults mod
reset_course_form_definition mod
reset_userdata mod
Modules
delete_instance mod
dndupload_handle mod
export_contents mod Used in WS get_course_contents
extend_settings_navigation mod,booktool
extends_navigation mod
get_completion_active_rule_descriptions mod 3.3+ Must be present for modules implementing custom completion rules
get_completion_state mod
get_extra_capabilities mod
get_file_areas mod
get_recent_mod_activity mod
get_shortcuts mod 3.1+
grade_item_update mod
grading_areas_list mod
print_recent_activity mod
print_recent_mod_activity mod
refresh_events mod
rescale_activity_grades mod 3.1+
scale_used_anywhere mod
update_grades mod
user_complete mod
user_outline mod
Glossary formats
glossary_print_entry_% for glossary formats Glossary formats is not a plugin type yet, however the list of formats is not hardcoded in the mod_glossary, instead the methods similar to callbacks are used for each subfolder in mod/glossar/format. % refer to the subfolder name, the functions are expected in lib.php
glossary_show_entry_% for glossary formats - " -
glossary_show_entry_% for glossary formats - " -
glossary_show_entry_% for glossary formats - " -
Other
global_db_replace block
inplace_editable * See Inplace editable
output_fragment_* * 3.1+ see Fragment
page_type_list * Used when displaying page types in block configuration
params_for_js atto
pluginfile * Callback checking permissions and preparing the file for serving plugin files, see File API. Note, in case of block plugins the list of arguments is slightly different
restore_role_assignment * For plugins that create their own role assignments
strings_for_js atto
supports * Required for activity modules
Deprecated
ajax_section_move format up to 2.3 See Course formats
ajax_support format up to 2.3 See Course formats
delete_course mod up to 3.1 use event observer
display_content format up to 2.3 See Course formats
get_post_actions mod,booktool Only called if legacy log is used on the site
get_section_name format up to 2.3 See Course formats
get_section_url format up to 2.3 See Course formats
get_types mod,ltisource up to 3.0 Replaced with get_shortcuts in 3.1
get_view_actions mod,booktool Only called if legacy log is used on the site
load_content format up to 2.3 See Course formats
scale_used mod up to 3.0
uses_sections format up to 2.3 See Course formats

Notes:

if Moodle version is not specified, this means that callback existed for a long time and can be found in all currently supported Moodle versions

Adding new callbacks to core

If you are preparing a patch for core which adds a new callback here are some things which should be considered.

TBA see https://tracker.moodle.org/browse/MDL-60510