This commit is contained in:
Ilya Tregubov 2024-04-04 09:16:35 +08:00 committed by Andrew Nicols
commit ddc1c5ee9a
No known key found for this signature in database
GPG Key ID: 6D1E3157C8CFBF14
37 changed files with 1603 additions and 199 deletions

View File

@ -0,0 +1,52 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_dataprivacy;
use html_writer;
use moodle_url;
/**
* Hook callbacks for tool_dataprivacy.
*
* @package tool_dataprivacy
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* Add the privacy summary to the footer.
*
* @param \core\hook\output\before_standard_footer_html_generation $hook
*/
public static function standard_footer_html(\core\hook\output\before_standard_footer_html_generation $hook): void {
// A returned 0 means that the setting was set and disabled, false means that there is no value for the provided setting.
$showsummary = get_config('tool_dataprivacy', 'showdataretentionsummary');
if ($showsummary === false) {
// This means that no value is stored in db. We use the default value in this case.
$showsummary = true;
}
if ($showsummary) {
$url = new moodle_url('/admin/tool/dataprivacy/summary.php');
$hook->add_html(
html_writer::div(
html_writer::link($url, get_string('dataretentionsummary', 'tool_dataprivacy')),
),
);
}
}
}

View File

@ -0,0 +1,32 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook callbacks for Data privacy
*
* @package tool_dataprivacy
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_footer_html_generation::class,
'callback' => \tool_dataprivacy\hook_callbacks::class . '::standard_footer_html',
],
];

View File

@ -116,29 +116,6 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser
return false;
}
/**
* Callback to add footer elements.
*
* @return string HTML footer content
*/
function tool_dataprivacy_standard_footer_html() {
$output = '';
// A returned 0 means that the setting was set and disabled, false means that there is no value for the provided setting.
$showsummary = get_config('tool_dataprivacy', 'showdataretentionsummary');
if ($showsummary === false) {
// This means that no value is stored in db. We use the default value in this case.
$showsummary = true;
}
if ($showsummary) {
$url = new moodle_url('/admin/tool/dataprivacy/summary.php');
$output = html_writer::link($url, get_string('dataretentionsummary', 'tool_dataprivacy'));
$output = html_writer::div($output, 'tool_dataprivacy');
}
return $output;
}
/**
* Fragment to add a new purpose.
*

View File

@ -14,22 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_mobile\local\hook\output;
namespace tool_mobile;
use html_writer;
/**
* Allows plugins to add any elements to the page <head> html tag
* Allows plugins to add any elements to the footer.
*
* @package tool_mobile
* @copyright 2023 Marina Glancy
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class before_standard_head_html_generation {
class hook_callbacks {
/**
* Callback to add head elements.
*
* @param \core\hook\output\before_standard_head_html_generation $hook
*/
public static function callback(\core\hook\output\before_standard_head_html_generation $hook): void {
public static function before_standard_head_html_generation(
\core\hook\output\before_standard_head_html_generation $hook,
): void {
global $CFG, $PAGE;
// Smart App Banners meta tag is only displayed if mobile services are enabled and configured.
if (!empty($CFG->enablemobilewebservice)) {
@ -38,7 +42,7 @@ class before_standard_head_html_generation {
if (!empty($mobilesettings->iosappid)) {
$hook->add_html(
'<meta name="apple-itunes-app" content="app-id=' . s($mobilesettings->iosappid) . ', ' .
'app-argument=' . $PAGE->url->out() . '"/>'
'app-argument=' . $PAGE->url->out() . '"/>'
);
}
@ -49,4 +53,29 @@ class before_standard_head_html_generation {
}
}
}
/**
* Callback to add head elements.
*
* @param \core\hook\output\before_standard_footer_html_generation $hook
*/
public static function before_standard_footer_html_generation(
\core\hook\output\before_standard_footer_html_generation $hook,
): void {
global $CFG;
require_once(__DIR__ . '/../lib.php');
if (empty($CFG->enablemobilewebservice)) {
return;
}
$url = tool_mobile_create_app_download_url();
if (empty($url)) {
return;
}
$hook->add_html(
html_writer::link($url, get_string('getmoodleonyourmobile', 'tool_mobile'), ['class' => 'mobilelink']),
);
}
}

View File

@ -27,7 +27,11 @@ defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_head_html_generation::class,
'callback' => [\tool_mobile\local\hook\output\before_standard_head_html_generation::class, 'callback'],
'callback' => [\tool_mobile\hook_callbacks::class, 'before_standard_head_html_generation'],
],
[
'hook' => \core\hook\output\before_standard_footer_html_generation::class,
'callback' => [\tool_mobile\hook_callbacks::class, 'before_standard_footer_html_generation'],
'priority' => 0,
],
[

View File

@ -191,21 +191,6 @@ function tool_mobile_myprofile_navigation(\core_user\output\myprofile\tree $tree
}
}
/**
* Callback to add footer elements.
*
* @return str valid html footer content
* @since Moodle 3.4
*/
function tool_mobile_standard_footer_html() {
global $CFG;
$output = '';
if (!empty($CFG->enablemobilewebservice) && $url = tool_mobile_create_app_download_url()) {
$output .= html_writer::link($url, get_string('getmoodleonyourmobile', 'tool_mobile'), ['class' => 'mobilelink']);
}
return $output;
}
/**
* Callback to be able to change a message/notification data per processor.
*

View File

@ -0,0 +1,86 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_policy;
use core\hook\output\before_standard_footer_html_generation;
use core\hook\output\before_standard_top_of_body_html_generation;
use html_writer;
use moodle_url;
/**
* Allows the plugin to add any elements to the footer.
*
* @package tool_policy
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* Add the guest consent form to the top of the body.
*
* @param before_standard_top_of_body_html_generation $hook
*/
public static function before_standard_top_of_body_html_generation(before_standard_top_of_body_html_generation $hook): void {
global $CFG, $PAGE, $USER;
if (empty($CFG->sitepolicyhandler)) {
return;
}
if ($CFG->sitepolicyhandler !== 'tool_policy') {
return;
}
if (!empty($USER->policyagreed)) {
return;
}
if (!isguestuser() && isloggedin()) {
return;
}
$output = $PAGE->get_renderer('tool_policy');
try {
$page = new \tool_policy\output\guestconsent();
$hook->add_html($output->render($page));
} catch (\dml_read_exception $e) {
// During upgrades, the new plugin code with new SQL could be in place but the DB not upgraded yet.
return;
}
}
/**
* Add the user policy settings link to the footer.
*
* @param before_standard_footer_html_generation $hook
*/
public static function before_standard_footer_html_generation(before_standard_footer_html_generation $hook): void {
global $CFG, $PAGE;
if (empty($CFG->sitepolicyhandler) || $CFG->sitepolicyhandler !== 'tool_policy') {
return;
}
$policies = api::get_current_versions_ids();
if (!empty($policies)) {
$url = new moodle_url('/admin/tool/policy/viewall.php', ['returnurl' => $PAGE->url]);
$hook->add_html(
html_writer::link($url, get_string('userpolicysettings', 'tool_policy'), ['class' => 'policiesfooter']),
);
}
}
}

View File

@ -0,0 +1,38 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook callbacks for Policies
*
* @package tool_policy
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_top_of_body_html_generation::class,
'callback' => \tool_policy\hook_callbacks::class . '::before_standard_top_of_body_html_generation',
'priority' => 0,
],
[
'hook' => \core\hook\output\before_standard_footer_html_generation::class,
'callback' => [\tool_policy\hook_callbacks::class, 'before_standard_footer_html_generation'],
'priority' => 0,
],
];

View File

@ -71,54 +71,6 @@ function tool_policy_myprofile_navigation(tree $tree, $user, $iscurrentuser, $co
return true;
}
/**
* Load policy message for guests.
*
* @return string The HTML code to insert before the head.
*/
function tool_policy_before_standard_top_of_body_html() {
global $CFG, $PAGE, $USER;
$message = null;
if (!empty($CFG->sitepolicyhandler)
&& $CFG->sitepolicyhandler == 'tool_policy'
&& empty($USER->policyagreed)
&& (isguestuser() || !isloggedin())) {
$output = $PAGE->get_renderer('tool_policy');
try {
$page = new \tool_policy\output\guestconsent();
$message = $output->render($page);
} catch (dml_read_exception $e) {
// During upgrades, the new plugin code with new SQL could be in place but the DB not upgraded yet.
$message = null;
}
}
return $message;
}
/**
* Callback to add footer elements.
*
* @return string HTML footer content
*/
function tool_policy_standard_footer_html() {
global $CFG, $PAGE;
$output = '';
if (!empty($CFG->sitepolicyhandler)
&& $CFG->sitepolicyhandler == 'tool_policy') {
$policies = api::get_current_versions_ids();
if (!empty($policies)) {
$url = new moodle_url('/admin/tool/policy/viewall.php', ['returnurl' => $PAGE->url]);
$output .= html_writer::link($url, get_string('userpolicysettings', 'tool_policy'));
$output = html_writer::div($output, 'policiesfooter');
}
}
return $output;
}
/**
* Hooks redirection to policy acceptance pages before sign up.
*/
@ -235,4 +187,4 @@ function tool_policy_output_fragment_accept_on_behalf($args) {
}
return $mform->render();
}
}

View File

@ -0,0 +1,37 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_usertours;
use core\hook\output\before_footer_html_generation;
/**
* Hook callbacks for usertours.
*
* @package tool_usertours
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* Bootstrap the usertours library.
*
* @param before_footer_html_generation $hook
*/
public static function before_footer_html_generation(before_footer_html_generation $hook): void {
\tool_usertours\helper::bootstrap();
}
}

View File

@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook callbacks for User tours
*
* @package tool_usertours
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_footer_html_generation::class,
'callback' => \tool_usertours\hook_callbacks::class . '::before_footer_html_generation',
'priority' => 0,
],
];

View File

@ -67,13 +67,6 @@ function tool_usertours_extend_navigation_user() {
\tool_usertours\helper::bootstrap();
}
/**
* Add JS to bootstrap tours. Only in Moodle 3.3+
*/
function tool_usertours_before_footer() {
\tool_usertours\helper::bootstrap();
}
/**
* Map icons for font-awesome themes.
*/

View File

@ -0,0 +1,81 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
/**
* Hook to allow subscribers to add HTML content after the main region content has been generated.
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @property-read \renderer_base $renderer The page renderer object
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add any elements to the footer before JS is finalized')]
#[\core\attribute\hook\replaces_callbacks('standard_after_main_region_html')]
final class after_standard_main_region_html_generation {
/**
* Hook to allow subscribers to add HTML content after the main region content has been generated.
*
* @param renderer_base $renderer
* @param string $output Initial output
*/
public function __construct(
/** @var \renderer_base The page renderer object */
public readonly \renderer_base $renderer,
/** @var string The collected output */
private string $output = '',
) {
}
/**
* Plugins implementing callback can add any HTML to the top of the body.
*
* Must be a string containing valid html head content.
*
* @param null|string $output
*/
public function add_html(?string $output): void {
if ($output) {
$this->output .= $output;
}
}
/**
* Returns all HTML added by the plugins
*
* @return string
*/
public function get_output(): string {
return $this->output;
}
/**
* Process legacy callbacks.
*/
public function process_legacy_callbacks(): void {
$pluginswithfunction = get_plugins_with_function(function: 'standard_after_main_region_html', migratedtohook: true);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$extrafooter = $function();
if (is_string($extrafooter)) {
$this->add_html($extrafooter);
}
}
}
}
}

View File

@ -0,0 +1,81 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
/**
* Hook to allow subscribers to add HTML content to the footer.
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @property-read \renderer_base $renderer The page renderer object
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add any elements to the footer before JS is finalized')]
#[\core\attribute\hook\replaces_callbacks('before_footer')]
final class before_footer_html_generation {
/**
* Hook to allow subscribers to add HTML content to the footer.
*
* @param \renderer_base $renderer
* @param string $output Initial output
*/
public function __construct(
/** @var \renderer_base The page renderer object */
public readonly \renderer_base $renderer,
/** @var string The collected output */
private string $output = '',
) {
}
/**
* Plugins implementing callback can add any HTML to the top of the body.
*
* Must be a string containing valid html head content.
*
* @param null|string $output
*/
public function add_html(?string $output): void {
if ($output) {
$this->output .= $output;
}
}
/**
* Returns all HTML added by the plugins
*
* @return string
*/
public function get_output(): string {
return $this->output;
}
/**
* Process legacy callbacks.
*/
public function process_legacy_callbacks(): void {
$pluginswithfunction = get_plugins_with_function(function: 'before_footer', migratedtohook: true);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$extrafooter = $function();
if (is_string($extrafooter)) {
$this->add_html($extrafooter);
}
}
}
}
}

View File

@ -0,0 +1,98 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
/**
* Class before_html_attributes
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @property-read \renderer_base $renderer The page renderer object
* @property array $attributes The list of HTML attributes to be added to the tag.
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add, remove or modify any attributes of the html tag.')]
#[\core\attribute\hook\replaces_callbacks('add_htmlattributes')]
final class before_html_attributes {
/**
* Constructor for the before_html_attributes hook.
*
* @param \renderer_base $renderer The page renderer object
* @param array $attributes The list of HTML attributes initially on the tag
*/
public function __construct(
/** @var \renderer_base The page renderer */
public readonly \renderer_base $renderer,
/** @var array The list of HTML attributes initially on the tag */
private array $attributes = [],
) {
}
/**
* Add an HTML attribute to the list.
*
* @param string $name
* @param string $value
*/
public function add_attribute(string $name, string $value): void {
$this->attributes[$name] = $value;
}
/**
* Get the list of attributes.
*
* @return array
*/
public function get_attributes(): array {
return $this->attributes;
}
/**
* Remove an HTML attribute from the list.
*
* @param string $name
*/
public function remove_attribute(string $name): void {
unset($this->attributes[$name]);
}
/**
* Process legacy callbacks.
*/
public function process_legacy_callbacks(): void {
// Legacy callback 'add_htmlattributes' is deprecated since Moodle 4.4.
// This function should return an array of html attribute names => values.
$pluginswithfunction = get_plugins_with_function(
function: 'add_htmlattributes',
migratedtohook: true,
);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$newattrs = $function();
unset($newattrs['dir']);
unset($newattrs['lang']);
unset($newattrs['xmlns']);
unset($newattrs['xml:lang']);
foreach ($newattrs as $name => $value) {
$this->add_attribute($name, $value);
}
}
}
}
}

View File

@ -0,0 +1,54 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
/**
* Class before_http_headers
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @property-read \renderer_base $renderer The page renderer object
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to make changes before headers are sent')]
#[\core\attribute\hook\replaces_callbacks('before_http_headers')]
class before_http_headers {
/**
* Hook to allow subscribers to modify the process before headers are sent.
*
* @param \renderer_base $renderer
*/
public function __construct(
/** @var \renderer_base The page renderer object */
public readonly \renderer_base $renderer,
) {
}
/**
* Process legacy callbacks.
*/
public function process_legacy_callbacks(): void {
$pluginswithfunction = get_plugins_with_function(function: 'before_http_headers', migratedtohook: true);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$function();
}
}
}
}

View File

@ -0,0 +1,83 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
use renderer_base;
/**
* Hook to allow subscribers to add HTML content to the footer.
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add any elements to the page footer.')]
#[\core\attribute\hook\replaces_callbacks('standard_footer_html')]
final class before_standard_footer_html_generation {
/**
* Hook to allow subscribers to add HTML content before the footer.
*
* @param renderer_base $renderer
* @param string $output Initial output
*/
public function __construct(
/** @var renderer_base The page renderer object */
public readonly renderer_base $renderer,
/** @var string The collected output */
private string $output = '',
) {
}
/**
* Plugins implementing callback can add any HTML to the top of the body.
*
* Must be a string containing valid html head content.
*
* @param null|string $output
*/
public function add_html(?string $output): void {
if ($output) {
$this->output .= $output;
}
}
/**
* Returns all HTML added by the plugins
*
* @return string
*/
public function get_output(): string {
return $this->output;
}
/**
* Process legacy callbacks.
*
* Legacy callback 'standard_footer_html' is deprecated since Moodle 4.4
*/
public function process_legacy_callbacks(): void {
// Give plugins an opportunity to add any footer elements.
// The callback must always return a string containing valid html footer content.
$pluginswithfunction = get_plugins_with_function(function: 'standard_footer_html', migratedtohook: true);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$this->add_html($function());
}
}
}
}

View File

@ -27,13 +27,21 @@ namespace core\hook\output;
#[\core\attribute\label('Allows plugins to add any elements to the page &lt;head&gt; html tag.')]
#[\core\attribute\hook\replaces_callbacks('before_standard_html_head')]
final class before_standard_head_html_generation {
/**
* Hook to allow subscribers to add HTML content to page head tag.
*
* @param renderer_base $renderer
* @param string $output Initial output
*/
public function __construct(
/** @var \renderer_base The core_renderer instance used for the generation */
public readonly \renderer_base $renderer,
/** @var string The collected output */
private string $output = '',
) {
}
/**
* Plugins implementing callback can add any HTML to the page.
*

View File

@ -0,0 +1,101 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\output;
/**
* Hook to allow subscribers to add HTML content to the top of the page body.
*
* @package core
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @property-read \renderer_base $renderer The page renderer object
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add any elements to the page &lt;head&gt; html tag.')]
#[\core\attribute\hook\replaces_callbacks('before_standard_html_head')]
final class before_standard_top_of_body_html_generation {
/**
* Hook to allow subscribers to add HTML content to the top of the page body.
*
* @param \renderer_base $renderer
* @param string $output Initial output
*/
public function __construct(
/** @var \renderer_base The page renderer object */
public readonly \renderer_base $renderer,
/** @var string The collected output */
private string $output = '',
) {
}
/**
* Plugins implementing callback can add any HTML to the top of the body.
*
* Must be a string containing valid html head content.
*
* @param null|string $output
*/
public function add_html(?string $output): void {
if ($output) {
$this->output .= $output;
}
}
/**
* Returns all HTML added by the plugins
*
* @return string
*/
public function get_output(): string {
return $this->output;
}
/**
* Process legacy callbacks.
*
* Legacy callback 'before_standard_top_of_body_html' is deprecated since Moodle 4.4
*/
public function process_legacy_callbacks(): void {
// Give subsystems an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
foreach (\core_component::get_core_subsystems() as $name => $path) {
if ($path) {
$this->add_html(
component_callback(
component: $name,
function: 'before_standard_top_of_body_html',
default: '',
migratedtohook: true,
),
);
}
}
// Give plugins an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
$pluginswithfunction = get_plugins_with_function(
function: 'before_standard_top_of_body_html',
migratedtohook: true,
);
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$this->add_html($function() ?? '');
}
}
}
}

View File

@ -22,7 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use core\hook\output\before_standard_footer_html_generation;
/**
* This Class contains helper functions for user feedback functionality.
@ -146,6 +146,26 @@ class core_userfeedback {
return $url;
}
/**
* Callback for the before_standard_footer_html_generation hook to add a user feedback footer link if configured.
*
* @param before_standard_footer_html_generation $hook
*/
public static function before_standard_footer_html_generation(
before_standard_footer_html_generation $hook,
): void {
if (self::can_give_feedback()) {
$hook->add_html(html_writer::div(
$hook->renderer->render_from_template(
'core/userfeedback_footer_link',
[
'url' => self::make_link()->out(false),
]
)
));
}
}
/**
* Whether the current can give feedback.
*

View File

@ -93,4 +93,13 @@ $callbacks = [
'hook' => \core_enrol\hook\before_user_enrolment_remove::class,
'callback' => \core_communication\hook_listener::class . '::remove_communication_membership_for_unenrolled_user',
],
[
'hook' => \core\hook\output\before_standard_footer_html_generation::class,
'callback' => \core_userfeedback::class . '::before_standard_footer_html_generation',
],
[
'hook' => \core\hook\output\after_standard_main_region_html_generation::class,
'callback' => \core_message\hook_callbacks::class . '::add_messaging_widget',
'priority' => 0,
],
];

View File

@ -37,6 +37,12 @@
use core\di;
use core\hook\manager as hook_manager;
use core\hook\output\after_standard_main_region_html_generation;
use core\hook\output\before_footer_html_generation;
use core\hook\output\before_html_attributes;
use core\hook\output\before_http_headers;
use core\hook\output\before_standard_footer_html_generation;
use core\hook\output\before_standard_top_of_body_html_generation;
use core\output\named_templatable;
use core_completion\cm_completion_details;
use core_course\output\activity_information;
@ -654,26 +660,22 @@ class core_renderer extends renderer_base {
*/
public function htmlattributes() {
$return = get_html_lang(true);
$attributes = array();
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/before_html_attributes.php');
$hook = new before_html_attributes($this);
if ($this->page->theme->doctype !== 'html5') {
$attributes['xmlns'] = 'http://www.w3.org/1999/xhtml';
$hook->add_attribute('xmlns', 'http://www.w3.org/1999/xhtml');
}
// Give plugins an opportunity to add things like xml namespaces to the html element.
// This function should return an array of html attribute names => values.
$pluginswithfunction = get_plugins_with_function('add_htmlattributes', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$newattrs = $function();
unset($newattrs['dir']);
unset($newattrs['lang']);
unset($newattrs['xmlns']);
unset($newattrs['xml:lang']);
$attributes += $newattrs;
}
}
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
foreach ($attributes as $key => $val) {
foreach ($hook->get_attributes() as $key => $val) {
$val = s($val);
$return .= " $key=\"$val\"";
}
@ -811,22 +813,16 @@ class core_renderer extends renderer_base {
$output .= "\n".$CFG->additionalhtmltopofbody;
}
// Give subsystems an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
foreach (\core_component::get_core_subsystems() as $name => $path) {
if ($path) {
$output .= component_callback($name, 'before_standard_top_of_body_html', [], '');
}
}
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/before_standard_top_of_body_html_generation.php');
// Give plugins an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
$pluginswithfunction = get_plugins_with_function('before_standard_top_of_body_html', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$output .= $function();
}
}
// Allow components to add content to the top of the body.
$hook = new before_standard_top_of_body_html_generation($this, $output);
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
$output = $hook->get_output();
$output .= $this->maintenance_warning();
@ -877,29 +873,21 @@ class core_renderer extends renderer_base {
* @return string HTML fragment.
*/
public function standard_footer_html() {
global $CFG;
$output = '';
if (during_initial_install()) {
// Debugging info can not work before install is finished,
// in any case we do not want any links during installation!
return $output;
return '';
}
// Give plugins an opportunity to add any footer elements.
// The callback must always return a string containing valid html footer content.
$pluginswithfunction = get_plugins_with_function('standard_footer_html', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$output .= $function();
}
}
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/before_standard_footer_html_generation.php');
if (core_userfeedback::can_give_feedback()) {
$output .= html_writer::div(
$this->render_from_template('core/userfeedback_footer_link', ['url' => core_userfeedback::make_link()->out(false)])
);
}
$hook = new before_standard_footer_html_generation($this);
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
$output = $hook->get_output();
if ($this->page->devicetypeinuse == 'legacy') {
// The legacy theme is in use print the notification
@ -1121,29 +1109,23 @@ class core_renderer extends renderer_base {
*/
public function standard_after_main_region_html() {
global $CFG;
$output = '';
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/after_standard_main_region_html_generation.php');
$hook = new after_standard_main_region_html_generation($this);
if ($this->page->pagelayout !== 'embedded' && !empty($CFG->additionalhtmlbottomofbody)) {
$output .= "\n".$CFG->additionalhtmlbottomofbody;
$hook->add_html("\n");
$hook->add_html($CFG->additionalhtmlbottomofbody);
}
// Give subsystems an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
foreach (\core_component::get_core_subsystems() as $name => $path) {
if ($path) {
$output .= component_callback($name, 'standard_after_main_region_html', [], '');
}
}
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
// Give plugins an opportunity to inject extra html content. The callback
// must always return a string containing valid html.
$pluginswithfunction = get_plugins_with_function('standard_after_main_region_html', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$output .= $function();
}
}
return $output;
return $hook->get_output();
}
/**
@ -1378,14 +1360,12 @@ class core_renderer extends renderer_base {
public function header() {
global $USER, $CFG, $SESSION;
// Give plugins an opportunity touch things before the http headers are sent
// such as adding additional headers. The return value is ignored.
$pluginswithfunction = get_plugins_with_function('before_http_headers', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$function();
}
}
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/before_http_headers.php');
di::get(hook_manager::class)->dispatch(new before_http_headers($this));
if (\core\session\manager::is_loggedinas()) {
$this->page->add_body_class('userloggedinas');
@ -1428,6 +1408,7 @@ class core_renderer extends renderer_base {
if ($cutpos === false) {
throw new coding_exception('page layout file ' . $layoutfile . ' does not contain the main content placeholder, please include "<?php echo $OUTPUT->main_content() ?>" in theme layout file.');
}
$header = substr($rendered, 0, $cutpos);
$footer = substr($rendered, $cutpos + strlen($token));
@ -1502,20 +1483,16 @@ class core_renderer extends renderer_base {
public function footer() {
global $CFG, $DB, $PERF;
$output = '';
// Ensure that the callback exists prior to cache purge.
// This is a critical page path.
// TODO MDL-81134 Remove after LTS+1.
require_once(__DIR__ . '/classes/hook/output/before_footer_html_generation.php');
// Give plugins an opportunity to touch the page before JS is finalized.
$pluginswithfunction = get_plugins_with_function('before_footer', 'lib.php');
foreach ($pluginswithfunction as $plugins) {
foreach ($plugins as $function) {
$extrafooter = $function();
if (is_string($extrafooter)) {
$output .= $extrafooter;
}
}
}
$output .= $this->container_end_all(true);
$hook = new before_footer_html_generation($this);
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
$hook->add_html($this->container_end_all(true));
$output = $hook->get_output();
$footer = $this->opencontainers->pop('header/footer');

View File

@ -0,0 +1,204 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core;
use core_renderer;
use moodle_page;
/**
* Tests for \core_renderer.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_renderer
*/
final class core_renderer_test extends \advanced_testcase {
/**
* @covers \core\hook\before_standard_top_of_body_html_generation
*/
public function test_standard_top_of_body_html(): void {
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_top_of_body_html();
$this->assertIsString($html);
$this->assertStringNotContainsString('A heading can be added to the top of the body HTML', $html);
}
/**
* @covers \core\hook\before_standard_top_of_body_html_generation
*/
public function test_before_standard_top_of_body_html_generation_hooked(): void {
require_once(__DIR__ . '/fixtures/core_renderer/before_standard_top_of_body_html_generation_callbacks.php');
\core\di::set(
\core\hook\manager::class,
\core\hook\manager::phpunit_get_instance([
'test_plugin1' => __DIR__ . '/fixtures/core_renderer/before_standard_top_of_body_html_generation_hooks.php',
]),
);
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_top_of_body_html();
$this->assertIsString($html);
$this->assertStringContainsString('A heading can be added to the top of the body HTML', $html);
}
/**
* @covers \core\hook\before_footer_html_generation
*/
public function test_before_footer_html_generation(): void {
$this->resetAfterTest();
$page = new moodle_page();
$page->set_state(moodle_page::STATE_PRINTING_HEADER);
$page->set_state(moodle_page::STATE_IN_BODY);
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$page->opencontainers->push('header/footer', '</body></html>');
$html = $renderer->footer();
$this->assertIsString($html);
$this->assertStringNotContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\before_footer_html_generation
*/
public function test_before_footer_html_generation_hooked(): void {
$this->resetAfterTest();
require_once(__DIR__ . '/fixtures/core_renderer/before_footer_html_generation_callbacks.php');
\core\di::set(
\core\hook\manager::class,
\core\hook\manager::phpunit_get_instance([
'test_plugin1' => __DIR__ . '/fixtures/core_renderer/before_footer_html_generation_hooks.php',
]),
);
$page = new moodle_page();
$page->set_state(moodle_page::STATE_PRINTING_HEADER);
$page->set_state(moodle_page::STATE_IN_BODY);
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$page->opencontainers->push('header/footer', '</body></html>');
$html = $renderer->footer();
$this->assertIsString($html);
$this->assertStringContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\before_standard_footer_html_generation
*/
public function before_standard_footer_html_generation(): void {
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_footer_html();
$this->assertIsString($html);
$this->assertStringNotContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\before_standard_footer_html_generation
*/
public function test_before_standard_footer_html_generation_hooked(): void {
require_once(__DIR__ . '/fixtures/core_renderer/before_standard_footer_html_generation_callbacks.php');
\core\di::set(
\core\hook\manager::class,
\core\hook\manager::phpunit_get_instance([
'test_plugin1' => __DIR__ . '/fixtures/core_renderer/before_standard_footer_html_generation_hooks.php',
]),
);
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_footer_html();
$this->assertIsString($html);
$this->assertStringContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\after_standard_main_region_html_generation
*/
public function test_after_standard_main_region_html_generation(): void {
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_after_main_region_html();
$this->assertIsString($html);
$this->assertStringNotContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\after_standard_main_region_html_generation
*/
public function test_after_standard_main_region_html_generation_hooked(): void {
require_once(__DIR__ . '/fixtures/core_renderer/after_standard_main_region_html_generation_callbacks.php');
\core\di::set(
\core\hook\manager::class,
\core\hook\manager::phpunit_get_instance([
'test_plugin1' => __DIR__ . '/fixtures/core_renderer/after_standard_main_region_html_generation_hooks.php',
]),
);
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_after_main_region_html();
$this->assertIsString($html);
$this->assertStringContainsString('A heading can be added', $html);
}
/**
* @covers \core\hook\before_html_attributes
*/
public function test_htmlattributes(): void {
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$attributes = $renderer->htmlattributes();
$this->assertIsString($attributes);
$this->assertStringNotContainsString('data-test="test"', $attributes);
}
/**
* @covers \core\hook\before_html_attributes
*/
public function test_htmlattributes_hooked(): void {
require_once(__DIR__ . '/fixtures/core_renderer/htmlattributes_callbacks.php');
\core\di::set(
\core\hook\manager::class,
\core\hook\manager::phpunit_get_instance([
'test_plugin1' => __DIR__ . '/fixtures/core_renderer/htmlattributes_hooks.php',
]),
);
$page = new moodle_page();
$renderer = new core_renderer($page, RENDERER_TARGET_GENERAL);
$attributes = $renderer->htmlattributes();
$this->assertIsString($attributes);
$this->assertStringContainsString('data-test="test"', $attributes);
}
}

View File

@ -0,0 +1,73 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core;
/**
* Tests for \core_userfeedback
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_userfeedback
*/
final class core_userfeedback_test extends \advanced_testcase {
public function test_footer_not_added_if_disabled(): void {
$this->resetAfterTest();
$this->setAdminUser();
$page = new \moodle_page();
$renderer = new \core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_footer_html();
$this->assertStringNotContainsString(
get_string('calltofeedback_give', 'core'),
$html,
);
}
public function test_footer_added_if_enabled_loggedin(): void {
$this->resetAfterTest();
$this->setAdminUser();
set_config('enableuserfeedback', 1);;
$page = new \moodle_page();
$renderer = new \core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_footer_html();
$this->assertStringContainsString(
get_string('calltofeedback_give', 'core'),
$html,
);
}
public function test_footer_not_added_if_loggedout(): void {
$this->resetAfterTest();
set_config('enableuserfeedback', 1);;
$page = new \moodle_page();
$renderer = new \core_renderer($page, RENDERER_TARGET_GENERAL);
$html = $renderer->standard_footer_html();
$this->assertStringNotContainsString(
get_string('calltofeedback_give', 'core'),
$html,
);
}
}

View File

@ -0,0 +1,39 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace test_fixtures\core_renderer;
/**
* Hook fixture for \core_renderer::after_standard_main_region_html_generation.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class after_standard_main_region_html_generation_callbacks {
/**
* Fixture for adding a heading after the standard main region HTML generation.
*
* @param \core\hook\output\after_standard_main_region_html_generation $hook
*/
public static function after_standard_main_region_html_generation(
\core\hook\output\after_standard_main_region_html_generation $hook,
): void {
$hook->add_html("<h1>A heading can be added</h1>");
}
}

View File

@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook fixture for \core_renderer::after_standard_main_region_html_generation.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\after_standard_main_region_html_generation::class,
'callback' => \test_fixtures\core_renderer\after_standard_main_region_html_generation_callbacks::class
. '::after_standard_main_region_html_generation',
],
];

View File

@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace test_fixtures\core_renderer;
/**
* Hook fixture for \core_renderer::footer.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class before_footer_html_generation_callbacks {
/**
* Fixture for adding a heading before the footer HTML generation.
*
* @param \core\hook\output\before_footer_html_generation $hook
*/
public static function before_footer_html_generation(\core\hook\output\before_footer_html_generation $hook): void {
$hook->add_html("<h1>A heading can be added</h1>");
}
}

View File

@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook fixture for \core_renderer::standard_footer_html.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_footer_html_generation::class,
'callback' => [
\test_fixtures\core_renderer\before_footer_html_generation_callbacks::class,
'before_footer_html_generation',
],
],
];

View File

@ -0,0 +1,39 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace test_fixtures\core_renderer;
/**
* Hook fixture for \core_renderer::standard_footer_html.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class before_standard_footer_html_generation_callbacks {
/**
* Fixture for adding a heading before the standard footer HTML generation.
*
* @param \core\hook\output\before_standard_footer_html_generation $hook
*/
public static function before_standard_footer_html_generation(
\core\hook\output\before_standard_footer_html_generation $hook,
): void {
$hook->add_html("<h1>A heading can be added</h1>");
}
}

View File

@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook fixture for \core_renderer::standard_footer_html.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_footer_html_generation::class,
'callback' => [
\test_fixtures\core_renderer\before_standard_footer_html_generation_callbacks::class,
'before_standard_footer_html_generation',
],
],
];

View File

@ -0,0 +1,38 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace test_fixtures\core_renderer;
/**
* Hook fixture for \core_renderer::htmlattributes.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class before_standard_top_of_body_html_generation_callbacks {
/**
* Fixture for adding a heading to the top of the body HTML.
*
* @param \core\hook\output\before_standard_top_of_body_html_generation $hook
*/
public static function before_standard_top_of_body_html_generation(
\core\hook\output\before_standard_top_of_body_html_generation $hook,
): void {
$hook->add_html("<h1>A heading can be added to the top of the body HTML</h1>");
}
}

View File

@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook fixture for before_standard_top_of_body_html_generation.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_top_of_body_html_generation::class,
'callback' => \test_fixtures\core_renderer\before_standard_top_of_body_html_generation_callbacks::class
. '::before_standard_top_of_body_html_generation',
],
];

View File

@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace test_fixtures\core_renderer;
/**
* Hook fixture for \core_renderer::htmlattributes.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class htmlattributes {
/**
* Fixture for adding a data attribute to the HTML element.
*
* @param \core\hook\output\before_html_attributes $hook
*/
public static function before_html_attributes(\core\hook\output\before_html_attributes $hook): void {
$hook->add_attribute('data-test', 'test');
}
}

View File

@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook fixture for \core_renderer::htmlattributes.
*
* @package core
* @category test
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_html_attributes::class,
'callback' => \test_fixtures\core_renderer\htmlattributes::class . '::before_html_attributes',
],
];

View File

@ -39,6 +39,12 @@ information provided here is intended especially for developers.
* The following callbacks have been migrated to hooks:
- before_standard_html_head() -> core\hook\output\before_standard_head_html_generation
- bulk_user_actions() -> core_user\hook\extend_bulk_user_actions
- before_http_headers() -> core\hook\output\before_http_headers
- before_standard_top_of_body_html() -> core\hook\output\before_standard_top_of_body_html_generation
- standard_after_main_region_html() -> core\hook\output\after_standard_main_region_html_generation
- before_footer() -> core\hook\output\before_footer_html_generation
- standard_footer_html() -> core\hook\output\before_standard_footer_html_generation
- add_htmlattributes() -> core\hook\output\before_html_attributes
* Deprecated PARAM_ types with the exception of PARAM_CLEAN now emit a deprecation exception. These were all deprecated in Moodle 2.0.
* A new \core\attribute\deprecated attribute can be used to more clearly describe deprecated methods.
* A new \core\deprecation class can be used to inspect for deprecated attributes:

View File

@ -0,0 +1,39 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_message;
/**
* Class hook_callbacks
*
* @package core_message
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* Add messaging widgets after the main region content.
*
* @param \core\hook\output\after_standard_main_region_html_generation $hook
*/
public static function add_messaging_widget(
\core\hook\output\after_standard_main_region_html_generation $hook,
): void {
$hook->add_html(\core_message\helper::render_messaging_widget(
isdrawer: true,
));
}
}

View File

@ -798,12 +798,3 @@ function core_message_user_preferences() {
});
return $preferences;
}
/**
* Render the message drawer to be included in the top of the body of each page.
*
* @return string HTML
*/
function core_message_standard_after_main_region_html() {
return \core_message\helper::render_messaging_widget(true, null, null);
}