Skip to content

Commit

Permalink
MDL-81144 core: Convert before_footer to hook
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewnicols committed Apr 2, 2024
1 parent e4a8ed5 commit 679001e
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 20 deletions.
37 changes: 37 additions & 0 deletions admin/tool/usertours/classes/hook_callbacks.php
@@ -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();
}
}
33 changes: 33 additions & 0 deletions admin/tool/usertours/db/hooks.php
@@ -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,
],
];
7 changes: 0 additions & 7 deletions admin/tool/usertours/lib.php
Expand Up @@ -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.
*/
Expand Down
81 changes: 81 additions & 0 deletions lib/classes/hook/output/before_footer_html_generation.php
@@ -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);
}
}
}
}
}
24 changes: 11 additions & 13 deletions lib/outputrenderers.php
Expand Up @@ -38,6 +38,7 @@
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_standard_footer_html_generation;
use core\hook\output\before_standard_top_of_body_html_generation;
Expand Down Expand Up @@ -1408,6 +1409,7 @@ public function header() {
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));

Expand Down Expand Up @@ -1482,20 +1484,16 @@ protected function render_page_layout($layoutfile) {
public function footer() {
global $CFG, $DB, $PERF;

$output = '';

// 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;
}
}
}
// 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');

$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');

Expand Down
41 changes: 41 additions & 0 deletions lib/tests/core_renderer_test.php
Expand Up @@ -62,6 +62,47 @@ public function test_before_standard_top_of_body_html_generation_hooked(): void
$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
*/
Expand Down
@@ -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>");
}
}
@@ -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',
],
],
];
5 changes: 5 additions & 0 deletions lib/upgrade.txt
Expand Up @@ -41,7 +41,12 @@ information provided here is intended especially for developers.
- 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_after_main_region_html() -> core\hook\output\after_standard_main_region_html_generation
<<<<<<< HEAD
- standard_footer_html() -> core\hook\output\before_standard_footer_html_generation
=======
- before_footer() -> core\hook\output\before_footer_html_generation
- standard_footer_html() -> core\hook\output\before_standard_footer_html_generation
>>>>>>> 3516753f3a (MDL-81144 core: Convert before_footer to hook)
- 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.
Expand Down

0 comments on commit 679001e

Please sign in to comment.