MDL-81144 core: Convert standard_footer_html to hook

This commit is contained in:
Andrew Nicols 2024-03-06 22:17:56 +08:00
parent 3105ea7dc2
commit 770e6b49f4
No known key found for this signature in database
GPG Key ID: 6D1E3157C8CFBF14
17 changed files with 400 additions and 73 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

@ -0,0 +1,53 @@
<?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_mobile;
use html_writer;
/**
* Allows plugins to add any elements to the footer.
*
* @package tool_mobile
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* 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

@ -30,4 +30,9 @@ $callbacks = [
'callback' => [\tool_mobile\local\hook\output\before_standard_head_html_generation::class, 'callback'],
'priority' => 0,
],
[
'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

@ -16,7 +16,10 @@
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.
@ -59,4 +62,25 @@ class hook_callbacks {
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

@ -30,4 +30,9 @@ $callbacks = [
'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,28 +71,6 @@ function tool_policy_myprofile_navigation(tree $tree, $user, $iscurrentuser, $co
return true;
}
/**
* 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.
*/

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

@ -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,8 @@ $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',
],
];

View File

@ -37,6 +37,7 @@
use core\di;
use core\hook\manager as hook_manager;
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;
@ -872,23 +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');
$hook = new before_standard_footer_html_generation($this);
di::get(hook_manager::class)->dispatch($hook);
$hook->process_legacy_callbacks();
$output = $hook->get_output();
if (core_userfeedback::can_give_feedback()) {
$output .= html_writer::div(

View File

@ -61,4 +61,37 @@ final class core_renderer_test extends \advanced_testcase {
$this->assertIsString($html);
$this->assertStringContainsString('A heading can be added to the top of the body HTML', $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);
}
}

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

@ -40,6 +40,8 @@ information provided here is intended especially for developers.
- before_standard_html_head() -> core\hook\output\before_standard_head_html_generation
- bulk_user_actions() -> core_user\hook\extend_bulk_user_actions
- before_standard_top_of_body_html() -> core\hook\output\before_standard_top_of_body_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: