This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.

=== 19.1.5 ===

* Added a new set_config_value() method to \core\model\encrypted_config and \core\model\encrypted_config_plugin
  for easily encrypting and decrypting config values.
* Changed the external_generate_token function to encrypt webservice tokens upon creation.

=== 19.1.3 ===

* Added a new table 'badge_email_verify' to the badges component for increased security for email verification data storing.
* Updated password fields on badge_backpack and badge_external_backpack tables from type char to text

=== 19.1.1 ===

* The functions optional_param(), optional_param_array(), required_param(), and required_param_array() now accept a new optional boolean parameter: `secure_retrieval` (default: false).
  When set to true, the parameter ensures values are only retrieved using secure sources (e.g., avoiding GET parameters).
  This is intended for use when handling sensitive information such as tokens, passwords, or other secure request data.
* core\link\vimeo_reader updated to use \curl class rather than adhoc implementation. This should have no impact but does mean any sitewide curl restrictions will apply.

=== 19.1.0 ===
* Updated element-passwordunmask.mustache to retrieve the autocomplete value from the element instead of being hardcoded
* Added core\orm\query\query_builder_to_repository_adapter to enable the use of a query builder in contexts where only a repository is allowed.
* Data submitted to Moodleforms can now be overridden via the \core\hook\moodleform_process_submission hook.
* The GraphQL core_course_course_reference input type has been moved from lib/webapi/external/course.graphqls to
  lib/webapi/course.graphqls to allow it to be used for any GraphQL service, not just external ones.
* Updated ARIA attributes in popover_region.mustache:
  * Changed button aria-haspopup from "true" to "dialog"
  * Changed popover container role from "region" to "dialog"
* Added new optional argument to moodle_database::get_fts_subquery and build_fts_subquery to allow running a fallback search (OR field like '%term%') on the highest weighted field for FTS partial word searches.

=== 19.0 ===
* Added new optional argument to help_icon class to support language string variables
* core_renderer::help_icon now has a new optional argument to support language string variables
* Added new option to format_text(): 'class-wrapper' can be used to specify one or more CSS classes to be added to a <div> which wraps the formatted text.
  * The <div> is only added if it is not detected in the input text
  * If set to `true`, the class-wrapper value becomes 'generated-content--user legacy-rendered'
  * If set to `false`, which is usually the default, no wrapper is added
  * When the 'overflowdiv' option is set, the default for 'class-wrapper' is `true` (aka 'generated-content--user legacy-rendered')
* The 'overflowdiv' option in format_text() has been updated to only add the <div> if it is not detected in the input text
* theme_switch_links() updated to respect not only device type but also the theme itself.
* process_new_icon() updated to handle the orientation information
* Added index to course_completion_criteria to improve performance of the activity completion report
* Added a new parameter in address_in_subnet to give us the ability to check for 0.0.0.0 or not.
* Fixed incorrectly named property on require_login_course_via_coursemodule, changed $cm_id_argument_name to $cmid_argument_name. This fixes a deprecation in PHP 8.2.
* Fixed incorrectly set $precision property in xmldb_field::set_attributes() method. The property was set to $type, but was undefined and not used.
  The precision is held in the $decimals property instead. This fixes a deprecation in PHP 8.2.
* Renamed theme_config::$setting to theme_config::$settings. The property has always been set in $settings by the constructor, however the declared
  property was incorrectly named and never held a value. This fixes a deprecation in PHP 8.2.
* Added additional optional argument on html_writer::select_time() for the field name (for better accessible labels)
* core\oauth2\api::connect_system_account no longer returns a true/false, it now returns a integer constant indicating the success state.
  * core\oauth2\api::SYSTEM_USER_ERROR - System account could not be created.
  * core\oauth2\api::SYSTEM_USER_SUCCESS - System account was created successfully.
  * core\oauth2\api::SYSTEM_USER_NAMELESS - System account was created, but no user information was loaded for the system account.
* Added 'profileurl' field to lib/webapi/user.graphqls::core_user type
* Added new nullable field 'customclass' into table 'totara_navigation' to store the custom CSS classname for menu items set by the admin in the 'inspire' theme.
* Updated heading level in forgot_password.mustache template
* send_headers() has changed behaviour, the second property ($cacheable) is only applicable if $CFG->allowhttpcache is enabled.
    * Otherwise all pages will count as non-cacheable regardless of flag passed through.

=== 18.0 ===
* complete_user_login() now has two optional arguments to enable login flow with MFA:
  * $complete_login_callback Callable function executed after MFA verification has passed.
  * $persistent_login If true, MFA check is skipped
* The auth_plugin_base now has a support_mfa method that auth plugins should override when they support the new login flow with MFA
* email_to_user() now has optional argument $override_fullname_display. If true then the fullname in email will be firstname followed by lastname rather than adhering to fullnamedisplay.
* Updated field 'data' from required to optional for input type "core_user_custom_field_input" in GraphQL to support custom field value deletion.
* Added new optional field 'delete' into input type "core_user_custom_field_input" in GraphQL to allow user to delete custom field value.
* search_users() has been deprecated due to it not being used. There is no alternative or replacement for this function.
* get_users_listing() has been deprecated due to it not being used. There is no alternative or replacement for this function.
* Updated 'char' type of field 'display_string_params' from table 'notification_event_log' into 'text' type
* As we no longer support IE 11:
  * core_useragent::is_totara_legacy_browser has been deprecated
  * `theme_config::set_legacy_browser` has been deprecated
  * The "cssvars" CSS variable compiler has been deprecated
  * IE 11 JavaScript polyfills in `javascript_polyfill` have been removed
* Storage of requirements in the `page_requirements_manager` class has changed. In order to support separation of page-specific
  requirements from system-level requirements, it now tracks things such as JS to load on the page using a separate tracker class
  instead of plain arrays. If you have extended page_requirements_manager, you may need to update your code.
* Upgraded library tcpdf to 6.6.2.
* Added static method qr() to pdf allowing a base64-formatted QR code to be generated.
* Updated login.mustache to only render signup container when either instructions or identity providers are provided.
* The method \core_component::get_component_classes_in_namespace() is now deprecated, please use \core_component::get_namespace_classes() instead (please note that the format of the result differs).
* user_record_reference::get_record() does not check whether the acting user has capability to view the target user anymore. Please use user_record_reference::load_for_viewer() instead.
* Updated element-passwordunmask.mustache to render with type="password"

=== 17.1 ===

* MariaDB has a new optimizer hint to adjust the optimizer_search_depth setting for a query.

=== 17.0 ===

* The has_middleware interface is now deprecated and no longer required. The get_middleware method it declared is now included in the resolver base classes. Remove 'implements has_middleware' from all type, query and mutation resolvers and replace 'implements (type|query|mutation)_resolver' with 'extends (type|query|mutation)_resolver'.
* The type_resolver, query_resolver and mutation_resolver interfaces have been converted to abstract classes. Please
  update your type, query and mutation resolver classes to use 'extends' instead of 'implements'
* The final keyword has been removed from all core resolver classes that included it, to allow more flexibility
  for partners wanting to extend existing GraphQL services.
* The generate_uuid() function has been deprecated. Please use \core\uuid::generate() instead.
* \core\entity\user_repository::search() added 2 parameters: $filter_by_suspended = false and $filter_by_current_user = false
* Added core_string_format and core_text_format to GraphQL schema to fix introspection for fields using these formatters
* The workaround_max_input_vars() function has been deprecated.
* Loading JSON_EDITOR node definitions from weka plugins has been deprecated, please create a "jsoneditor" plugin to contain the node definitions instead.
* The property $line has been removed from xml_format_exception as it conflicted with the base Exception class definition. Use $exception->getLine() instead.
* Added new role 'apiuser' to archetypes of 'moodle/user:create' permission
* Added the ability to escape '-' character in the Oauth2 field mapping with a single backslash to allow fields like
 'year-started' to be treated as a single property.
* Added new parameter '$exclude_enrol_method' into function 'enrol_get_all_users_courses_sql()'
* \core\data_providers\users::create_active_users_provider() added optional third argument $exclude_inactive
* \core\data_providers\users::create_active_users_provider() added optional fourth argument $exclude_guest
* \core\data_providers\users::create_active_users_provider() added optional fifth argument $exclude_admin
* \core\data_providers\users::create_repository() first argument $exclude_inactive become required
* \core\data_providers\users::__construct() second argument $allowed_order_by_fields changed. Entity field 'timemodified' is allowed now
* Added an optional parameter $time to execution_context to help with testing it
* Added get_variable() and set_variable() methods to execution_context to allow storing variables that should persist
 per lifetime of the execution context

=== 16.0 ===

* Changed exception type from servicenotavailable to sessionerroruser for call_external_function() when the user is not logged in.
* Changed core/form_autocomplete_input to include a CSS class.

=== 15.3 ===
* Added optional GraphQL field "rpl" to "core_course_module" type

=== 15.2 ===

* Upgraded Vue to 2.6.14
* Updated library core-js to version 3.19.1
* Removed the following deprecated functions from javascript-static:
  - init_toggle_class_on_click
  - focus_login_form
  - focus_login_error
  - checkall
  - checknone
  - select_all_in_element_with_id
  - select_all_in
  - deselect_all_in
  - confirm_if
  - findParentNode
  - filterByParent
  - fix_column_widths
  - fix_column_width
  - stripHTML
  - M.form.init_smartselect
* Upgraded window.fetch polyfill to 3.6.2
* Added new methods add_entity_snapshot() and get_entity_snapshot() to \core\event\base
  for better abstraction when using entities rather than records in events.
* Added new method get_cloned_entity() to \core\orm\entity\model for getting a copy of entity data in entity models.
* The option $CFG->custom_context_classes no longer instantiates objects if passed in a serialized string.

=== 15.0 ===

* Added columns 'type' and 'show_default_branding' to the oauth2_issuer table, and added them as properties to core\oauth2\issuer.
* The login template (login.mustache) has been updated to support overriding the default OAuth2 IDP sign in buttons,
  allowing a custom button image to be specified with the buttonimageurl and issuertype template variables.
  The example context JSON for this template has also been updated.
* Added new method set_url() to \cm_info to allow modules to set and override their own URL.
* Fixed broken emoji support only for future conversions. Already existing records in the database are not affected and would need to be manually updated
* Added to_record() method to \core\orm\entity for better backwards compatibility with legacy APIs that do not support ORM.
* \core\entity\user::get_record() is deprecated, please use to_record() instead.
* \core\entity\enrol::to_record() has been removed, as it will fallback to the parent \core\orm\entity::to_record() method.
* \core\webapi\resolver\type\course now supports the \core\entity\course entity as input.
* Increased character limit for the name column in the course_categories table to 1333 characters.
* \core\webapi\resolver\type\category::authorize had been deprecated and should not be used publicly outside of the class, please use \core\webapi\resolver\type\category::do_authorize instead
* For security reasons, filelib has been updated so all requests now use emulated redirects.
  For this reason, manually disabling emulateredirects will no longer have any effect (and will generate a debugging message).
* enrol_get_my_courses() and enrol_get_all_users_courses() in enrollib.php now use enrol_get_cleaned_order_by_sql()
  to ensure the $sort parameter does not contain any potentially dangerous SQL statements.
* \core_user_external::create_users() and \core_user_external::update_users() can now accept more user profile fields so user
  creation/update via web service can now be very similar to the edit profile page's functionality. The new fields that have been
  added are:
  - maildisplay
  - interests
  - url
  - skype
  - institution
  - department
  - phone1
  - phone2
  - address
* Upgraded jQuery to 3.6.0
* Changed function scope to public for \core\orm\entity\filter\has_filters::apply_filters.
* The following functions are marked as deprecated and should not be used any more, there are no replacements:
  * \core\json_editor\helper\document_helper::sanitize_json()
  * \core\json_editor\helper\document_helper::sanitize_json_document
  * \core\json_editor\helper\node_helper::sanitize_raw_nodes()
  * \core\json_editor\node\node::sanitize_raw_node() and its child implementations
* Progress bar output component can now receive optional label (used for aria label)
* Added aria label to progress_bar.mustache

=== 14.0 ===

* backported https://github.com/jquery/jquery/pull/4642 to prevent a minor security issue
* core_login_process_password_reset_request() now prevents processing password reset requests by email addresses
  that are shared by multiple accounts.
* enrol_get_all_users_courses() added $limitfrom and $limitnum to support pagination
* enrol_course_delete() in enrollib.php now may receive userid as argument and check permission before removing enrolment instances
* All testing data generators must be moved from my/plugin/tests/generator/lib.php
  to \my_plugin\testing\generator classes in my/plugin/classes/testing/generator.php files
* All deprecated "trusttext" features and APIs were removed.
* Behat timeout constants behat_base::TIMEOUT, EXTENDED_TIMEOUT, and REDUCED_TIMEOUT have been
  deprecated. Please instead use the functions behat_base::get_timeout(), get_extended_timeout(),
  and get_reduced_timeout(). These allow for timeouts to be increased by a setting in config.php.
* PHPUnit has been upgraded to version 9,
  see https://phpunit.de/announcements/phpunit-9.html for more information how to fix existing tests.
* phpFlickr::getFriendlyGeodata(), which relied on a non-working web service, has been deprecated
* MNET functionality was removed in Totara 14.0
* Introduced new config variables $CFG->link_parser_allowed_hosts and $CFG->link_parser_blocked_hosts to be able to explicitly allow or block hosts
  to be parsed by the get_linkmetadata GraphQL query.
* Added format parameter to field "value" in type "core_user_card_display_field" in GraphQL
* document_helper::looks_like_json() added 2nd parameter.
* core\theme\file\theme_file::clean_draft_file_area() has been renamed to core\theme\file\theme_file::clean_draft_files
  and changed from public to protected.
* core\theme\file\theme_file::draft_file_exists() has been removed.
* \coursecat::delete_courses_and_containers() is now publicly accessible.
* core\entities\cohort has been moved to core\entity\cohort
* core\entities\cohort_filters has been moved to core\entity\cohort_filters
* core\entities\cohort_repository has been moved to core\entity\cohort_repository
* core\entities\expand has been moved to core\entity\expand
* core\entities\expandable has been moved to core\entity\expandable
* core\entities\tenant has been moved to core\entity\tenant
* core\entities\user has been moved to core\entity\user
* core\entities\user_repository has been moved to core\entity\user_repository
* Removed the output of parsing errors when handling invalid requests in ajax/service.php
* Added "action" field to input type "core_theme_file_input" in GraphQL
* Enrollment plugins used in require_login() can now be overridden via the \totara_core\hook\enrol_plugins hook.
* Upgraded chart.js to 2.9.4
* Deprecated core\json_editor\helper\document_helper::sanitize_json_document() and node::sanitize_raw_node().
  If outputting raw JSON documents in HTML, they should be escaped at output.

=== 13.0 ===

* stored_file::get_imageinfo() added 1st parameter to optionally load the orientation information on a jpeg file.
* stored_file::generate_image_thumbnail() updated to use the orientation information of a jpeg file.
* resize_image_from_image updated to handle the orientation information passed through the 2nd parameter.
* Updated alt text and title for core\output::render_user_picture method for better screen reader experience.
* plugin_renderer_base::render_navigation_node - Removed tabindex="0" from non-interactive elements of breadcrumbs.
* New methods for iteration over very large record sets were added to DML, see $DB->get_huge_recorset methods.
* PHPUnit has been upgraded to version 8.5.x,
  see https://phpunit.de/announcements/phpunit-8.html for more information how to fix existing tests.
* Custom session handlers must add new $uselocking constructor parameter and implement
  \core\session\handler::is_locking_configurable() method.
* All classes that override admin_setting::add_to_config_log() must be changed to use public access.
* \core\event\admin_settings_changed was replaced by \core\hook\admin_setting_changed for security reasons,
  code needs to be updated to use new hook instead of previous event.
* Added \core\hook\admin_setting_changed that can be used for notification of admin setting changes.
* Capability 'moodle/role:switchroles' and all related functionality is deprecated and will be removed in Totara 14
* MNET functionality is deprecated and will be removed in Totara 14
* Following columns were removed from the "user" database table: icq, yahoo, aim, msn
* Static fields in legacy forms are now automatically sanitised to prevent XSS,
  if necessary plugins that require unsafe or malformed HTML markup in static fields
  need to be updated to use $field->set_allow_xss(true).
* new function update_role(int $roleid, string $name, string $shortname, string $description, string $archetype),
  direct writes into role table are forbidden now
* function allow_override($sroleid, $troleid, bool $value = true) has new parameter $value,
  direct writes into role_allow_override table are forbidden now
* function allow_assign($fromroleid, $targetroleid, bool $value = true)
  direct writes into role_allow_assign table are forbidden now
* function allow_override($sroleid, $troleid, bool $value = true) has new parameter $value,
  direct writes into role_allow_override table are forbidden now
* function allow_assign($fromroleid, $targetroleid, bool $value = true) has new parameter $value,
  direct writes to role_allow_assign table are forbidden now
* Node.js minimum supported version has changed to Node.js 12, please use the latest NPM available
* core_collator now supports reversed order with core_collator::REVERSED flag, the value of core_collator::SORT_REGULAR
  constant was changed to 128
* core_renderer::login_info and core_renderer::user_menu are updated to remove the main menu items from the site policy page.
* All support for counted record sets was deprecated, use two separate queries instead.
* Added new moodleform element 'filetypes' and new admin setting widget 'admin_setting_filetypes'. These new widgets
  allow users to define a list of file types; either by typing them manually or selecting them from a list. The widgets
  directly support the syntax used to feed the 'accepted_types' option of the filemanager and filepicker elements. File
  types can be specified as extensions (.jpg or just jpg), mime types (text/plain) or groups (image).
* Removed accesslib private functions: load_course_context(), load_role_access_by_context(), dedupe_user_access() (MDL-49398).
* Internal "accessdata" structure format has changed to improve ability to perform role definition caching (MDL-49398).
* Role definitions are no longer cached in user session (MDL-49398).
* External function core_group_external::get_activity_allowed_groups now returns an additional field: canaccessallgroups.
  It indicates whether the user will be able to access all the activity groups.
* file_get_draft_area_info does not sum the root folder anymore when calculating the foldercount.
* The moodleform element classes can now optionally provide a public function validateSubmitValue(). This method can be
  used to perform implicit validation of submitted values - without the need to explicitly add the validation rules to
  every form. The method should accept a single parameter with the submitted value. It should return a string with the
  eventual validation error, or an empty value if the validation passes.
* New function \context->delete_capabilities() correctly handles caching when deleting all of a context's capabilities.
* New function mark_user_dirty() must be called after changing data that gets cached in user sessions. Examples:
  - Assigning roles to users.
  - Unassigning roles from users.
  - Enroling users into courses.
  - Unenroling users from courses.
* New function \context->get_parent_context_paths() efficiently returns all parent context paths for a context.
* Following functions have been deprecated, please use get_roles_used_in_context.
    - get_roles_on_exact_context()
    - get_roles_with_assignment_on_context()
* user_can_view_profile() now also checks that target user is actually enrolled in course, use user_get_profile_url()
  if you need fallback to system profiles when users not enrolled.
* Deprecated all no longer used classes in lib/googleapi.php file:
  - google_docs
  - google_picasa
  - google_oauth
* System state is now reverted after every PHPUnit test, this was required for compatiblity with parallel test execution,
  all tests that used $this->resetAfterTest(false) should be updated.
* The jQuery.extend function has had a security patch applied
* Deprecated registration_cron_task has been removed
* Deprecated course publishing has been removed
* The following deprecated capabilities have been removed:
    'moodle/community:add',
    'moodle/course:publish',
    'moodle/community:download',
    'moodle/backup:backuptargethub'
* Deprecated maintenancemodetimer YUI module has been removed
* Deprecated MForms element 'submitlink' has been removed
* The following deprecated methods have been removed:
  - core_grades_external::get_grades()
  - course_modinfo::build_section_cache()
  - cm_info::get_deprecated_group_members_only()
  - cm_info::is_user_access_restricted_by_group()
  - action_menu::do_not_enhance()
* PHPUnit has been upgraded to version 7.5.x.
  All methods removed in PHPUnit version 6 were added to basic_testcase to not hard break any third-party testcases.
  A debugging message is issued to use the new methods provided by PHPUnit 7.5.
  All PHPUnit classes are now namespaced and have been added to the totara\core\db\renamedclasses.php file.
  The dbunit package was removed because it is not maintained any more, however dataset methods in advanced_testcase are still present.
* Deprecated properties flex_icon::pix, flex_icon::component, flex_icon::attributes have been removed
* Updated render_tabobject to correctly support tabobject::linkedwhenselected
* The class admin_setting_configfilepicker has been deprecated, please use admin_setting_configstoredfile instead
* Added a new setting disableconsistentcleaning which is off by default. When off trusttext will no longer work, and all content
  is consistently sanitised to remove XSS nasties.
* Added a new allowxss option to format_text() that should be used only when absolutely necessary to avoid clean_text during formatting.
* Added a new allowxss option in file serving API that should be used only when absolutely necessary when it is required to allow
  unrestricted execution fo uploaded files (such as in SCORM module).
* Filters show now implement a protected static function is_compatible_with_clean_text() method which returns true if text can be
  cleaned after filter, and false if the filter will inject content that is not compatible with cleaning.
* markdown_to_html() now cleans the html before returning it, stripping all XSS nasties. A new second argument now exists to set options.
  There is one option so far, allowxss, which if set to true will cause markdown_to_html to not clean_text (old behaviour)
* Changes made for behat to be able to check aria-label attribute of buttons and form fields as label, which might break existing behat tests
* Added a new resolvefaviconcallback property in which themes can override the URL returned by $OUTPUT->favicon().
* Upgraded jQuery to 3.4.1
* Login template (login.mustache) has some text position and CSS changes
* Added core/popover:destroy event to popover component when using the manual trigger method
* The runTemplateJS method now returns an ES6 promise which is resolved when autoinitialise is complete (but not code in the #js mustache helper)
* Added a new protected function moodle_database::get_fts_mode() which is used to detect what mode to be used for full-text search query.
* Added a new public function moodle_database::is_fts_accent_sensitive() to check whether accent sensitive is enabled for the database or not.
* Modified the implementation of moodle_database::build_fts_subquery() in child level, which it is now accept search text with asterisk at the end of string to mark the search query as wild card search.
* Deprecated format_date() and format_text() functions in webapi execution_context introduced in Evergreen release in favour of newly introduced \totara_core\formatter\field\date_field_formatter and \totara_core\formatter\field\text_field_formatter classes.
* The DML layer now supports optimizer hints
* MariaDB has a new optimizer hint to disable materialization for a query
* Extended modal_cancel template to support different text for the cancel button
* Updated login.mustache, adding calls to prevent duplicate form submissions
* Added delay-rendering functions to core/action_menu template and actionmenu.js
* Upgraded scssphp to v1.0.5, this involves renaming classes from Leafo => ScssPhp as the namespace has changed.
* Removed support for serving chunked CSS as supported browsers do not use it.
  - styles.php and styles_debug.php no longer accept a "chunk" parameter.
  - The $chunk and $chunkurl parameters to css_store_css() are no longer used.
  - css_chunk_by_selector_count() has been deprecated and will be removed in a future version.
* Added IE 11 support for CSS var() and custom properties on :root {} within TUI SCSS.
* The internal structure of the cache 'core/coursecattree' has been changed; please refer to coursecat::get_tree()
* Moved formatter classes from \totara_core\formatter to \core\webapi\formatter namespace as they are meant to be used only for GraphQL
* New function make_content_disposition() correctly encodes the filename field of the Content-Disposition header
* file_storage::create_imagefile_preview() has been deprecated, please use \core\image\preview_helper::get_preview_content() instead.
* file_storage::create_file_preview() has been deprecated, please use \core\image\preview_helper::create_file_preview() instead.
* file_storage::get_file_preview() has been deprecated, please use \core\image\preview_helper::get_file_preview() instead.
* function file_pluginfile($relativepath, $forcedownload, $preview = null, $theme = null) has new parameter $theme to help on resizing image base on theme. If null is given, then default theme will be used.
* Added new function crop_resize_image_from_image which can be used to resize the image from original image content.
* Added \core\hook\requirejs_config_generated that can be used to manipulate RequireJS config after it has
  been generated. Allowing plugins to introduce shims and other common constructs if required.
* Function delete_course has been deprecated and will be removed in the future, please use \container_course\course::delete instead
* Deprecated $THEME->yuicssmodules. This setting is ignored when a theme inherits from legacy or ventura, and will be removed in a future version. It is recommended to set this to an empty array if you are not inheriting from legacy or ventura.
* core_renderer::standard_footer_html() now includes a once-per-session link to the mobile app (if enabled) on homepage, dashboard, or catalog if user is using a mobile device


=== 12.0 ===

* set_send_count() has been deprecated, please use \core_user\email_bounce_counter instead
* set_bounce_count() has been deprecated, please use \core_user\email_bounce_counter instead
* The user_not_fully_set_up() function has a new $strict parameter (defaulting to true) in order to decide when
  custom fields (and other checks) should be evaluated to determine if the user has been completely setup.
* updated popover_region.mustache correcting role attribute
* Upgraded jQuery to 3.3.1
* $CFG->loginhttps setting was removed, do not use it.
* $PAGE->https_required() and $PAGE->verify_https_required() are now deprecated, do not use them.
* $CFG->httpswwwroot is now deprecated and will always contain in the same value as wwwroot.
* String helpers are no longer used in the following templates, string data is passed via context data:
** lib/templates/block.mustache
** lib/templates/loading.mustache
** lib/templates/modal.mustache
** lib/templates/progress_bar.mustache
* Icon helpers are no longer used in the following templates, icon data is passed via context data:
** lib/form/templates/form_notification.mustache
** lib/templates/action_menu.mustache
** lib/templates/action_menu_item.mustache
** lib/templates/action_menu_link.mustache
** lib/templates/action_menu_trigger.mustache
** lib/templates/chooser_item.mustache
** lib/templates/help_icon.mustache
** lib/templates/inplace_editable.mustache
** lib/templates/login.mustache
** lib/templates/permissionmanager_role.mustache
* The following templates have been updated:
** lib/templates/notification_error.mustache
** lib/templates/notification_info.mustache
** lib/templates/notification_success.mustache
** lib/templates/notification_warning.mustache
* Removed deprecated completion_info::wipe_session_cache()
* Removed deprecated function_or_method_exists()
* Removed deprecated methods:
  * mysqli_native_moodle_database::is_compressed_row_format_supported()
  * mysqli_native_moodle_database::get_row_format_sql()
* Removed deprecated behat_deprecated::i_select_to_approve()
* Strings loaded into the page for Javascript now pass through M.util.add_strings()
* New mustache template for add block
** lib/templates/add_new_block.mustache
* New mustache template for add block popover
** lib/templates/add_block_popover_content.mustache
* core/login mustache template has changed, fixing an issue with a skip link
* core_renderer::render_single_button has been updated to set a primary button
* Limited subset of ES6 globals is now allowed in all supported browsers,
  see https://help.totaralearning.com/display/DEV/ES+6+functionality for more details.
* JavaScript autoinitialisation using data-core-autoinitialise and data-core-autoinitialise-amd HTML data attributes has been
  added.
* Added support for AMD modules in subdirectories (eg. core/sub/amdmodule is a valid AMD module)
* Added support for using sub directories in templates folder.
* $mform->init_javascript_enhancement() is deprecated and no longer does anything. Existing uses of smartselect enhancement
  should be switched to the searchableselector form element or other solutions.
* The method moodleform::after_definition() has been added and can now be used to add some logic
  to be performed after the form's definition was set. This is useful for intermediate subclasses.
* The mcore YUI rollup which included various YUI modules such as moodle-core-notification is no longer included on every
  page. Missing YUI dependencies may be exposed by this change (e.g. missing a requirement on moodle-core-notification when
  using M.core.dialogue).
* Return value of the validate_email() is now proper boolean as documented. Previously the function could return 1, 0 or false.
* Various legacy javascript functions have been removed:
    * M.util.focus_login_form and M.util.focus_login_error no longer do anything. Please use JavaScript instead. See
      lib/templates/login.mustache for an example.
    * Some outdated global JS functions have been removed and should be replaced with calls to jquery
      or alternative approaches:
        checkall, checknone, select_all_in_element_with_id, select_all_in, deselect_all_in, confirm_if, findParentNode,
        filterByParent, stripHTML
    * M.util.init_toggle_class_on_click has been removed.
* Following behat steps have been removed from core:
    - I click on "<element_string>" "<selector_string>" in the "<row_text_string>" table row
    - I go to notifications page
    - I add "<filename_string>" file from recent files to "<filepicker_field_string>" filepicker
    - I upload "<filepath_string>" file to "<filepicker_field_string>" filepicker
    - I create "<foldername_string>" folder in "<filepicker_field_string>" filepicker
    - I open "<foldername_string>" folder from "<filepicker_field_string>" filepicker
    - I unzip "<filename_string>" file from "<filepicker_field_string>" filepicker
    - I zip "<filename_string>" folder from "<filepicker_field_string>" filepicker
    - I delete "<file_or_folder_name_string>" from "<filepicker_field_string>" filepicker
    - I send "<message_contents_string>" message to "<username_string>"
    - I add "<user_username_string>" user to "<cohort_idnumber_string>" cohort
    - I add "<username_string>" user to "<group_name_string>" group
    - I fill in "<field_string>" with "<value_string>"
    - I select "<option_string>" from "<select_string>"
    - I select "<radio_button_string>" radio button
    - I check "<option_string>"
    - I uncheck "<option_string>"
    - the "<field_string>" field should match "<value_string>" value
    - the "<checkbox_string>" checkbox should be checked
    - the "<checkbox_string>" checkbox should not be checked
    - I fill the moodle form with:
    - "<element_string>" "<selector_string>" should exists
    - "<element_string>" "<selector_string>" should not exists
    - the following "<element_string>" exists:
* Deprecated moodle-core-form-autosubmit YUI3 module
* Added Session storage JavaScript library
* Added userdate Mustache helper - please don't use this as it has a potential XSS issue.
* Added shortentext Mustache helper
* Deprecated the following functions:
    - flexible_table::get_initial_first() - use flexible_table::print_initials_bar() instead
    - flexible_table::get_initial_last() - use flexible_table::print_initials_bar() instead
    - flexible_table::print_one_initials_bar() - use flexible_table::print_initials_bar() instead
* $OUTPUT->pix_url has been deprecated - use $OUTPUT->pix_icon() for icons or $OUTPUT->image_url() for images. In
  mustache templates, the pix helper is available (although we don't recommend using context variables inside it).
* Added renderPix method to templates JavaScript library
* Update pix_icon template, adding an "icon" class
* The cron runner now sets up a fresh PAGE and OUTPUT between each task.
* Added a lock to prevent 'coursemodinfo' cache to be built multiple times in parallel
* PHPUnit's bootstrap has been changed to use HTTPS wwwroot (https://www.example.com/moodle) from previous HTTP version. Any
  existing test expecting the old HTTP URLs will need to be switched to the new HTTPS value (reference: MDL-54901).

=== 11.0 ===

* New $mustequal parameter added to the following methods in lib/tests/behat/behat_general.php
  to control whether a table call data must 'equal' or 'contain' the data to be matched.
    - following_should_exist_in_the_table
    - row_column_of_table_should_contain
* Removed deprecated custom menu functionality
* Changed core_renderer::maintenance_warning()
* Deprecated maintenancemodetimer YUI module.
* Added support for additional context variables in modal mustache templates
* Changed modal_confirm.mustache to support different yes/no strings
* Updated tabobject so that the title attribute is no longer set if not provided
* Updated core_renderer::render_tabobject()
* registration_cron_task has been deprecated and will be removed in 12
* Link to publish course was removed as hub functionality has been deprecated.
* Hub related capabilities
    'moodle/community:add',
    'moodle/course:publish',
    'moodle/community:download',
    'moodle/backup:backuptargethub'
  have been deprecated and will be removed in 12

=== 10.1 ===

* updated progress_bar.mustache

=== 10.0 ===

* Added classes for external command execution (e.g. shell commands or external applications)
  See https://help.totaralearning.com/display/DEV/Command+execution+API for more information.
* filter_get_globally_enabled() added first argument $resetcache
* JQuery has been updated to 3.2.1. - please read
  https://jquery.com/upgrade-guide/3.0/ and update your javascript.
* get_user_capability_course() now has an additional parameter 'limit'. This can be used to return a set number of records with
  the submitted capability. The parameter 'fieldsexceptid' will now accept context fields which can be used for preloading.
* Admin setting "Show My courses expanded on Dashboard" has been removed.
* MForms element 'submitlink' has been deprecated.
* Searchable selector form element is now a wrapper for autocomplete. A "No selection" option is automatically
  added to the options list for best backwards compatibility - if you were manually adding a "no selection" option you will need
  to remove it.
* Node.js versions >=4 are now required to run grunt.
* JQuery has been updated to 3.2.1. Please read https://jquery.com/upgrade-guide/3.0/ and update your javascript.
* New option 'blanktarget' added to format_text. This option adds target="_blank" to links
* A new webservice structure `external_files` has been created which provides a standardised view of files in Moodle and
  should be used for all file return descriptions.
  Files matching this format can be retrieved via the new `external_util::get_area_files` method.
  See MDL-54951 for further information.
* The parameter $usepost of the following functions has been deprecated and is not used any more:
  - get_max_upload_file_size()
  - get_user_max_upload_file_size()
* The following classes have been removed and should not be used any more:
    - boxclient - See MDL-49599 for more information.
* The following functions have been removed and should not be used any more:
    - file_modify_html_header() - See MDL-29738 for more information.
* core_grades_external::get_grades has been deprecated. Please do not call this function any more.
  External function gradereport_user_external::get_grade_items can be used for retrieving the course grades information.
* New option 'escape' added to format_string. When true (default), escapes HTML entities from the string
* The following functions have been deprecated and are not used any more:
  - get_records_csv() Please use csv_import_reader::load_csv_content() instead.
  - put_records_csv() Please use download_as_dataformat (lib/dataformatlib.php) instead.
  - zip_files()   - See MDL-24343 for more information.
  - unzip_file()  - See MDL-24343 for more information.
  - print_log()           - See MDL-43681 for more information
  - print_log_csv()       - See MDL-43681 for more information
  - print_log_ods()       - See MDL-43681 for more information
  - print_log_xls()       - See MDL-43681 for more information
  - print_mnet_log()      - See MDL-43681 for more information
  - build_logs_array()    - See MDL-43681 for more information
  - get_logs()            - See MDL-43681 for more information
  - get_logs_usercourse() - See MDL-43681 for more information
  - get_logs_userday()    - See MDL-43681 for more information
  - prevent_form_autofill_password() Please do not use anymore.
* The password_compat library was removed as it is no longer required.
* Phpunit has been upgraded to 5.4.x and following has been deprecated and is not used any more:
  - setExpectedException(), use @expectedException or $this->expectException() and $this->expectExceptionMessage()
  - getMock(), use createMock() or getMockBuilder()->getMock()
  - UnitTestCase class is removed.
* The following methods have been finally deprecated and should no longer be used:
  - course_modinfo::build_section_cache()
  - cm_info::get_deprecated_group_members_only()
  - cm_info::is_user_access_restricted_by_group()
* The following methods in cm_info::standardmethods have also been finally deprecated and should no longer be used:
  - cm_info::get_after_edit_icons()
  - cm_info::get_after_link()
  - cm_info::get_content()
  - cm_info::get_custom_data()
  - cm_info::get_extra_classes()
  - cm_info::get_on_click()
  - cm_info::get_url()
  - cm_info::obtain_dynamic_data()
  Calling them through the magic method __call() will throw a coding exception.
* The alfresco library has been removed from core. It was an old version of
  the library which was not compatible with newer versions of Alfresco.
* Added down arrow: $OUTPUT->darrow.
* All file_packer implementations now accept an additional parameter to allow a simple boolean return value instead of
  an array of individual file statuses.
* "I set the field "field_string" to multiline:" now end with colon (:), as PyStrings is supposed to end with ":"
* New functions to support deprecation of events have been added to the base event. See MDL-46214 for further details.
* A new function `get_name_with_info` has been added to the base event. This function adds information about event
  deprecations and should be used where this information is relevant.
* Following api's have been deprecated in behat_config_manager, please use behat_config_util instead.
  - get_features_with_tags
  - get_components_steps_definitions
  - get_config_file_contents
  - merge_behat_config
  - get_behat_profile
  - profile_guided_allocate
  - merge_config
  - clean_path
  - get_behat_tests_path
* behat_util::start_test_mode() accepts 3 options now:
  - 1. Theme sute with all features: If behat should initialise theme suite with all core features.
  - 2. Parallel runs: How many parallel runs will be running.
  - 3. Run: Which process behat should be initialise for.
* behat_context_helper::set_session() has been deprecated, please use behat_context_helper::set_environment() instead.
* data-fieldtype="type" attribute has been added to form field default template.
* form elements extending MoodleQuickForm_group must call $this->createFormElement() instead of
  @MoodleQuickForm::createElement() in order to be compatible with PHP 7.1
* Relative paths in $CFG->alternateloginurl will be resolved to absolute path within moodle site. Previously they
  were resolved to absolute path within the server. That means:
  - $CFG->wwwroot: http://example.com/moodle
  - $CFG->alternateloginurl : /my/super/login.php
  - Login url will be: http://example.com/moodle/my/super/login.php (moodle root based)
* Database (DML) layer:
  - new sql_equal() method available for places where case sensitive/insensitive varchar comparisons are required.
* PostgreSQL connections now use advanced options to reduce connection overhead.  These options are not compatible
  with some connection poolers.  The dbhandlesoptions parameter has been added to allow the database to configure the
  required defaults. The parameters that are required in the database are;
    ALTER DATABASE moodle SET client_encoding = UTF8;
    ALTER DATABASE moodle SET standard_conforming_strings = on;
    ALTER DATABASE moodle SET search_path = 'moodle,public';  -- Optional, if you wish to use a custom schema.
  You can set these options against the database or the moodle user who connects.
* Some form elements have been refined to better support right-to-left languages. In RTL,
  most fields should not have their direction flipped, a URL, a path to a file, a number, ...
  are always displayed LTR. Input fields and text areas now will best guess whether they
  should be forced to be displayed in LTR based on the PARAM type associated with it. You
  can call $mform->setForceLtr($elementName, true/false) on some form fields to manually
  set the value.
* Action menus do_not_enhance() is deprecated, use a list of action_icon instead.
* The minifier library used by core_minify has been switched to https://github.com/matthiasmullie/minify - there are minor differences
  in minifier output.
* context_header additional buttons can now have a class attribute provided in the link attributes.
* The return signature for the antivirus::scan_file() function has changed.
  The calling function will now handle removal of infected files from Moodle based on the new integer return value.
* The first parameter $eventdata of both message_send() and \core\message\manager::send_message() should
  be \core\message\message. Use of stdClass is deprecated.
* The message_sent event now expects other[courseid] to be always set, exception otherwise. For BC with contrib code,
  message_sent::create_from_ids() will show a debugging notice if the \core\message\message being sent is missing
  the courseid property, defaulting to SITEID automatically. In Moodle 3.6 (MDL-55449) courseid will be fully mandatory
  for all messages sent.
* Introduced a new hook for plugin developers:
    - <component>_course_module_background_deletion_recommended()
  This hook should be used in conjunction with the existing '<component>_pre_course_module_delete($mod)'. It must
  return a boolean and is called by core to check whether a plugin's implementation of
  <component>_pre_course_module_deleted($mod) will take a long time. A plugin should therefore only implement this
  function if it also implements <component>_pre_course_module_delete($mod).
  An example in current use is recyclebin, which performs what can be a lengthy backup process in
  tool_recyclebin_pre_course_module_delete. The recyclebin, if enabled, now returns true in its implementation of
  tool_recyclebin_course_module_background_deletion_recommended(), to indicate to core that the deletion (and
  execution of tool_recyclebin_pre_course_module_delete) should be handled with an adhoc task, meaning it will not
  occur in real time.
* Webservice function core_course_search_courses accepts a new parameter 'limittoenrolled' to filter the results
  only to courses the user is enrolled in, and are visible to them.
* External functions that are not calling external_api::validate_context are buggy and will now generate
  exceptions. Previously they were only generating warnings in the webserver error log.
  See https://docs.moodle.org/dev/External_functions_API#Security
* The moodle/blog:associatecourse and moodle/blog:associatemodule capabilities has been removed.
* The following functions has been finally deprecated and can not be used any more:
    - profile_display_badges()
    - useredit_shared_definition_preferences()
    - calendar_normalize_tz()
    - get_user_timezone_offset()
    - get_timezone_offset()
    - get_list_of_timezones()
    - calculate_user_dst_table()
    - dst_changes_for_year()
    - get_timezone_record()
    - test_get_list_of_timezones()
    - test_get_timezone_offset()
    - test_get_user_timezone_offset()
* The google api library has been updated to version 1.1.7. There was some important changes
  on the SSL handling. Now the SSL version will be determined by the underlying library.
  For more information see https://github.com/google/google-api-php-client/pull/644
* The core_user::fill_properties_cache() static method has been introduced to be a reference
  and allow standard user fields data validation. Right now only type validation is supported
  checking it against the parameter (PARAM_*) type of the target user field. MDL-52781 is
  going to add support to null/not null and choices validation, replacing the existing code to
  validate the user fields in different places in a common way.
* Webservice function core_course_search_courses now returns results when the search string
  is less than 2 chars long.
* Webservice function core_course_search_courses accepts a new parameter 'requiredcapabilities' to filter the results
  by the capabilities of the current user.
* New mform element 'course' handles thousands of courses with good performance and usability.
* environment.xml file format was changed to use Totara major version numbers,
  use new TOTARA tag, for example: <TOTARA version="10" requires="9">
* environmentlib.php was partially refactored, do not use this internal API in custom code
* all incompatible Moodle plugin installation and update code and APIs were removed
* theme_config::get_all_block_regions() added argument $pagelayout
* core_renderer::render_file_picker flex-icon used for upload rather than CSS loaded image.
* CSS class 'link-as-button' has been removed. Please use "btn" instead
* core/templates method property renderIcon may alternatively be called with two parameters the second being a custom data object
* \core\output\block::from_block_contents() now always returns ->header attribute.
  As such, lib/templates/block.mustache has changed (removing the {{^header}} section).
* The redirect() function will now redirect immediately if output has not
  already started. Messages will be displayed on the subsequent page using
  session notifications. The type of message output can be configured using the
  fourth parameter to redirect().
* The specification of extra classes in the $OUTPUT->notification()
  function, and \core\output\notification renderable have been deprecated
  and will be removed in a future version.
  Notifications should use the levels found in \core\output\notification.
* The constants for NOTIFY_PROBLEM, NOTIFY_REDIRECT, and NOTIFY_MESSAGE in
  \core\output\notification have been deprecated in favour of NOTIFY_ERROR,
  NOTIFY_WARNING, and NOTIFY_INFO respectively.
* The following functions, previously used (exclusively) by upgrade steps are not available
  anymore because of the upgrade cleanup performed for this version. See MDL-51580 for more info:
    - upgrade_mysql_fix_unsigned_and_lob_columns()
    - upgrade_course_completion_remove_duplicates()
    - upgrade_save_orphaned_questions()
    - upgrade_rename_old_backup_files_using_shortname()
    - upgrade_mssql_nvarcharmax()
    - upgrade_mssql_varbinarymax()
    - upgrade_fix_missing_root_folders()
    - upgrade_course_modules_sequences()
    - upgrade_grade_item_fix_sortorder()
    - upgrade_availability_item()
* A new parameter $ajaxformdata was added to the constructor for moodleform. When building a
  moodleform in a webservice or ajax script (for example using the new fragments API) we
  cannot allow the moodleform to parse it's own data from _GET and _POST - we must pass it as
  an array.
* Plugins can extend the navigation for user by declaring the following callback:
  <frankenstyle>_extend_navigation_user(navigation_node $parentnode, stdClass $user,
                                        context_user $context, stdClass $course,
                                        context_course $coursecontext)
* The function notify() now throws a debugging message - see MDL-50269.
* Ajax calls going through lib/ajax/* now validate the return values before sending
  the response. If the validation does not pass an exception is raised. This behaviour
  is consistent with web services.
* Several changes in Moodle core, standard plugins and third party libraries to
  ensure compatibility with PHP7. All plugins are recommended to perform testing
  against PHP7 as well. Refer to https://docs.moodle.org/dev/Moodle_and_PHP7 for more
  information. The following changes may affect you:
  * Class moodleform, moodleform_mod and some module classes have been changed to use
    __construct() for the constructor. Calling parent constructors by the class
    name will display debugging message. Incorrect: parent::moodleform(),
    correct: parent::__construct()
  * All form elements have also changed the constructor syntax. No changes are
    needed for using form elements, however if plugin defines new form element it
    needs to use correct syntax. For example, incorrect: parent::HTML_QuickForm_input(),
    HTML_QuickForm_input::HTML_QuickForm_input(), $this->HTML_QuickForm_input().
    Correct: HTML_QuickForm_input::__construct() or parent::__construct().
  * profile_field_base::profile_field_base() is deprecated, use parent::__construct()
    in custom profile fields constructors. Similar deprecations in exsiting
    profile_field_* classes.
  * user_filter_type::user_filter_type() is deprecated, use parent::__construct() in
    custom user filters. Similar deprecations in existing user_filter_* classes.
  * table_default_export_format_parent::table_default_export_format_parent() is
    deprecated, use parent::__construct() in extending classes.
* groups_delete_group_members() $showfeedback parameter has been removed and is no longer
  respected. Users of this function should output their own feedback if required.
* Number of changes to Tags API, see tag/upgrade.txt for more details
* The previous events API handlers are being deprecated in favour of events 2 API, debugging messages are being displayed if
  there are 3rd party plugins using it. Switch to events 2 API please, see https://docs.moodle.org/dev/Event_2#Event_dispatching_and_observers
  Note than you will need to bump the plugin version so moodle is aware that you removed the plugin's event handlers.
* mforms validation functions are not available in the global JS namespace anymore, event listeners
  are assigned to fields and buttons through a self-contained JS function.
* Added $CFG->urlrewriteclass option to config.php allowing clean / semantic urls to
  be implemented in a plugin, eg local_cleanurls.
* $CFG->pathtoclam global setting has been moved to clamav antivirus plugin setting of the same name.
* clam_message_admins() and get_clam_error_code() have been deprecated, its functionality
  is now a part of \antivirus_clamav\scanner class methods.
* \repository::antivir_scan_file() has been deprecated, \core\antivirus\manager::scan_file() that
  applies antivirus plugins is replacing its functionality.
* Added core_text::str_max_bytes() which safely truncates multi-byte strings to a maximum number of bytes.
* Zend Framework has been removed completely.
* Any plugin can report when a scale is being used with the callback function [pluginname]_scale_used_anywhere(int $scaleid).
* Changes in file_rewrite_pluginfile_urls: Passing a new option reverse = true in the $options var will make the function to convert
  actual URLs in $text to encoded URLs in the @@PLUGINFILE@@ form.
* behat_util::is_server_running() is removed, please use behat_util::check_server_status() instead.
* Behat\Mink\Selector\SelectorsHandler::xpathLiteral() method is deprecated use behat_context_helper::escape instead
  when building Xpath, or pass the unescaped value when using the named selector.',
* table_sql download process is using the new data formats plugin which you can't use if you are buffering any output
    * flexible_table::get_download_menu(), considered private, has been deleted. Use
      $OUTPUT->download_dataformat_selector() instead.
* Add new file_is_executable(), to consistently check for executables even in Windows (PHP bug #41062).
* Introduced new hooks for plugin developers.
    - <component>_pre_course_category_delete($category)
    - <component>_pre_course_delete($course)
    - <component>_pre_course_module_delete($cm)
    - <component>_pre_block_delete($instance)
    - <component>_pre_user_delete($user)
  These hooks allow developers to use the item in question before it is deleted by core. For example, if your plugin is
  a module (plugins located in the mod folder) called 'xxx' and you wish to interact with the user object before it is
  deleted then the function to create would be mod_xxx_pre_user_delete($user) in mod/xxx/lib.php.
* Added new class breadcrumb_navigation_node
* Added plugin_renderer_base::render_breadcrumb_navigation_node()
* The get_file_url() function has been deprecated please call moodle_url::make_file_url() instead.
* Updated JavaScript Mustache implementation from 2.1.3 to 2.2.1
* Updated PHP Mustache implementation from 2.9.0 to 2.11.1
* Provided identifiers in the form of data-url attributes for user menu items
* core_renderer::render_help_icon() has changed.
* help_icon::export_for_template() includes icon, linktext, title, url in the return object
* loglevel.js has been updated 1.4.1 from 1.4.0
* Notifications are now output above the main content container by core_renderer not at the top of it by totara_core renderer.
* CSS class names used to define notification type when passed to totara_set_notification() e.g. 'notifysuccess' are now stripped
  and converted to Bootstrap equivalents. Other custom classes passed to totara_set_notification are preserved.
* completion_info::wipe_session_cache has been deprecated, tests automatically purge MUC
* progress_bar.mustache has changed
* ldap_get_entries_moodle() now always returns lower-cased attribute names in the returned entries.
  It was supposed to do so before, but it actually didn't.
* pix_icon::export_for_pix() now outputs a JSON string in the title key
* The pix mustache helper now accepts JSON as the final parameter as well as a string. If it is not a JSON object, the title
  and alt attributes will be the third parameter.
* Removed accesslib private functions: load_course_context(), load_role_access_by_context(), dedupe_user_access() (MDL-49398).
* Internal "accessdata" structure format has changed to improve ability to perform role definition caching (MDL-49398).
* user_can_view_profile() now also checks the moodle/user:viewalldetails capability.
* The caching option 'immutable' has been added to send_stored_file() and send_file().

=== 9.2 ===

* lib/templates/flex_icon.mustache context variable has changed, the property ->customdata->title sets the title of the flex icon
* lib/templates/flex_icon_stack.mustache context variable has changed, the property ->customdata->title sets the title of the flex icon
* pear::Net::GeoIP has been removed.
