mirror of
https://github.com/catalyst/moodle-auth_outage.git
synced 2026-05-16 21:41:31 +02:00
Issue #22 - Added setting and implemented removing elements by basic CSS selector (only simple .class and #id can be used as of now).
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
namespace auth_outage\local\controllers;
|
||||
|
||||
use auth_outage\local\outagelib;
|
||||
use coding_exception;
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
@@ -49,8 +50,10 @@ class maintenance_static_page_generator {
|
||||
|
||||
/**
|
||||
* maintenance_static_page_generator constructor.
|
||||
* @param DOMDocument|null $dom
|
||||
*
|
||||
* @param DOMDocument|null $dom
|
||||
* @param maintenance_static_page_io $io
|
||||
*
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function __construct($dom, maintenance_static_page_io $io) {
|
||||
@@ -74,6 +77,7 @@ class maintenance_static_page_generator {
|
||||
$this->update_link_stylesheet();
|
||||
$this->update_link_favicon();
|
||||
$this->update_images();
|
||||
$this->remove_configured_css_selectors();
|
||||
|
||||
$html = $this->dom->saveHTML();
|
||||
if (trim($html) == '') {
|
||||
@@ -93,7 +97,6 @@ class maintenance_static_page_generator {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove script tags from DOM.
|
||||
*/
|
||||
@@ -104,10 +107,7 @@ class maintenance_static_page_generator {
|
||||
foreach ($scripts as $node) {
|
||||
$remove[] = $node;
|
||||
}
|
||||
// All listed, now remove them.
|
||||
foreach ($remove as $node) {
|
||||
$node->parentNode->removeChild($node);
|
||||
}
|
||||
$this->remove_nodes_from_dom($remove);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,6 +135,7 @@ class maintenance_static_page_generator {
|
||||
|
||||
/**
|
||||
* Checks for urls inside filename.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $baseref
|
||||
*/
|
||||
@@ -195,4 +196,73 @@ class maintenance_static_page_generator {
|
||||
$link->setAttribute('src', $this->io->generate_file_url($src)); // Works for most image formats.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove from DOM the CSS selectores defined in the plugin settings.
|
||||
*/
|
||||
private function remove_configured_css_selectors() {
|
||||
$selectors = explode("\n", outagelib::get_config()->remove_selectors);
|
||||
|
||||
$remove = [];
|
||||
|
||||
foreach ($selectors as $selector) {
|
||||
// We only support a simple .class or #id -- if support for full selectors must be added
|
||||
// then I suggest checking http://code.google.com/p/phpquery/ on how to implement it.
|
||||
$selector = trim($selector);
|
||||
if ($selector == '') {
|
||||
continue;
|
||||
}
|
||||
$remove = array_merge($remove, $this->fetch_elements_by_selector($selector));
|
||||
}
|
||||
|
||||
$this->remove_nodes_from_dom($remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the nodes from the DOM.
|
||||
*
|
||||
* @param DOMElement[] $nodes
|
||||
*/
|
||||
private function remove_nodes_from_dom(array $nodes) {
|
||||
foreach ($nodes as $node) {
|
||||
$node->parentNode->removeChild($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all elements based on the given selector.
|
||||
*
|
||||
* @param $selector
|
||||
*
|
||||
* @return DOMElement[]
|
||||
*/
|
||||
private function fetch_elements_by_selector($selector) {
|
||||
$type = $selector[0];
|
||||
$selector = substr($selector, 1); // Remove '.' or '#'.
|
||||
if ($type == '#') {
|
||||
$element = $this->dom->getElementById($selector);
|
||||
return is_null($element) ? [] : [$element];
|
||||
} else {
|
||||
return $this->fetch_elements_by_class($selector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all elements which contains the given class.
|
||||
*
|
||||
* @param $class
|
||||
*
|
||||
* @return DOMElement[]
|
||||
*/
|
||||
private function fetch_elements_by_class($class) {
|
||||
$matches = [];
|
||||
$elements = $this->dom->getElementsByTagName('*');
|
||||
foreach ($elements as $element) {
|
||||
$elementclasses = explode(' ', $element->getAttribute('class'));
|
||||
if (in_array($class, $elementclasses)) {
|
||||
$matches[] = $element;
|
||||
}
|
||||
}
|
||||
return $matches;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class outagelib {
|
||||
|
||||
// There is a previewing or active outage.
|
||||
$CFG->additionalhtmltopofbody = renderer::get()->render_warningbar($active, $time, false, $preview).
|
||||
$CFG->additionalhtmltopofbody;
|
||||
$CFG->additionalhtmltopofbody;
|
||||
} catch (Exception $e) {
|
||||
debugging('Exception occured while injecting our code: '.$e->getMessage());
|
||||
debugging($e->getTraceAsString(), DEBUG_DEVELOPER);
|
||||
@@ -137,13 +137,14 @@ class outagelib {
|
||||
*/
|
||||
public static function get_config_defaults() {
|
||||
return [
|
||||
'allowedips' => '',
|
||||
'css' => '',
|
||||
'default_autostart' => '0',
|
||||
'default_duration' => (string)(60 * 60),
|
||||
'allowedips' => '',
|
||||
'css' => '',
|
||||
'default_autostart' => '0',
|
||||
'default_duration' => (string)(60 * 60),
|
||||
'default_warning_duration' => (string)(60 * 60),
|
||||
'default_title' => get_string('defaulttitlevalue', 'auth_outage'),
|
||||
'default_description' => get_string('defaultdescriptionvalue', 'auth_outage'),
|
||||
'default_title' => get_string('defaulttitlevalue', 'auth_outage'),
|
||||
'default_description' => get_string('defaultdescriptionvalue', 'auth_outage'),
|
||||
'remove_selectors' => '.usermenu',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -163,6 +164,7 @@ class outagelib {
|
||||
|
||||
/**
|
||||
* Calls Moodle API - set_maintenance_later() to set when the next outage starts.
|
||||
*
|
||||
* @param outage|null $outage Outage or null if no scheduled outage.
|
||||
*/
|
||||
private static function update_maintenance_later($outage) {
|
||||
@@ -204,9 +206,11 @@ class outagelib {
|
||||
|
||||
/**
|
||||
* Generates the code to put in sitedata/climaintenance.php when needed.
|
||||
* @param int $starttime Outage start time.
|
||||
* @param int $stoptime Outage stop time.
|
||||
*
|
||||
* @param int $starttime Outage start time.
|
||||
* @param int $stoptime Outage stop time.
|
||||
* @param string $allowedips List of IPs allowed.
|
||||
*
|
||||
* @return string
|
||||
* @throws invalid_parameter_exception
|
||||
*/
|
||||
@@ -255,7 +259,9 @@ EOT;
|
||||
|
||||
/**
|
||||
* Updates the static info page by (re)creating or deleting it as needed.
|
||||
*
|
||||
* @param outage|null $outage Outage or null if no scheduled outage.
|
||||
*
|
||||
* @throws coding_exception
|
||||
* @throws file_exception
|
||||
*/
|
||||
|
||||
@@ -114,6 +114,8 @@ $string['outagefinishwarning'] = 'You are about to mark this outage as finished.
|
||||
$string['outageslistfuture'] = 'Planned outages';
|
||||
$string['outageslistpast'] = 'Outage history';
|
||||
$string['pluginname'] = 'Outage manager';
|
||||
$string['removeselectors'] = 'Remove selectors';
|
||||
$string['removeselectorsdescription'] = 'CSS selectors to remove when rendering a static themed maintenance page. One selector per line.';
|
||||
$string['settingssectiondefaults'] = 'Default Outage Parameters';
|
||||
$string['settingssectiondefaultsdescription'] = 'Configure the default values used when creating new outages.';
|
||||
$string['settingssectionplugin'] = 'Plugin Configuration';
|
||||
|
||||
@@ -36,6 +36,6 @@ if (is_null($outage)) {
|
||||
}
|
||||
|
||||
$page = maintenance_static_page::create_from_outage($outage);
|
||||
$page->set_preview(true);
|
||||
$page->get_io()->set_preview(true);
|
||||
$page->generate();
|
||||
readfile($page->get_template_file());
|
||||
readfile($page->get_io()->get_template_file());
|
||||
|
||||
11
settings.php
11
settings.php
@@ -90,11 +90,9 @@ if ($hassiteconfig && is_enabled_auth('outage')) {
|
||||
// Create 'Allowed IPs' settings.
|
||||
$allowedips = outagelib::get_config()->allowedips;
|
||||
$description = '';
|
||||
|
||||
if (!isset($CFG->auth_outage_check) || !$CFG->auth_outage_check) {
|
||||
$description .= $OUTPUT->notification(get_string('allowedipsnoconfig', 'auth_outage'), 'notifyfailure');
|
||||
}
|
||||
|
||||
if (trim($allowedips) == '') {
|
||||
$message = 'allowedipsempty';
|
||||
$type = 'notifymessage';
|
||||
@@ -108,7 +106,6 @@ if ($hassiteconfig && is_enabled_auth('outage')) {
|
||||
$description .= $OUTPUT->notification(get_string($message, 'auth_outage', ['ip' => getremoteaddr()]), $type);
|
||||
|
||||
$description .= '<p>'.get_string('ipblockersyntax', 'admin').'</p>';
|
||||
|
||||
$settings->add(new admin_setting_configiplist(
|
||||
'auth_outage/allowedips',
|
||||
get_string('allowediplist', 'admin'),
|
||||
@@ -116,6 +113,14 @@ if ($hassiteconfig && is_enabled_auth('outage')) {
|
||||
$defaults['allowedips']
|
||||
));
|
||||
|
||||
// Create 'Static Page - Elements to Remove' settings.
|
||||
$settings->add(new admin_setting_configtextarea(
|
||||
'auth_outage/remove_selectors',
|
||||
get_string('removeselectors', 'auth_outage'),
|
||||
get_string('removeselectorsdescription', 'auth_outage'),
|
||||
$defaults['remove_selectors']
|
||||
));
|
||||
|
||||
// Create category for Outage.
|
||||
$ADMIN->add('authsettings', new admin_category('auth_outage', get_string('pluginname', 'auth_outage')));
|
||||
// Add settings page toconfigure defaults.
|
||||
|
||||
@@ -174,7 +174,9 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
|
||||
|
||||
/**
|
||||
* Generates the maintenance page (not using preview mode).
|
||||
*
|
||||
* @param string $html Input HTML.
|
||||
*
|
||||
* @return string Output HTML.
|
||||
*/
|
||||
private function generated_page_html($html) {
|
||||
@@ -228,7 +230,9 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
|
||||
|
||||
/**
|
||||
* Gets a fixture file for this test case.
|
||||
*
|
||||
* @param $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_fixture_path($file) {
|
||||
@@ -278,4 +282,88 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
|
||||
$this->set_expected_exception('coding_exception');
|
||||
maintenance_static_page_io::file_get_data(200);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>Content<b class="removeme">Goodbye cruel world.</b></body></html>';
|
||||
set_config('remove_selectors', '.removeme', 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertNotContains('removeme', $generated);
|
||||
self::assertNotContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector_id() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
|
||||
set_config('remove_selectors', '#removeme', 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertNotContains('removeme', $generated);
|
||||
self::assertNotContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector_with_multiline() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>'.
|
||||
'<b class="deleteme">Goodbye cruel world.</b>'.
|
||||
'<b class="removeme">Goodbye cruel world.</b>'.
|
||||
'</body></html>';
|
||||
set_config('remove_selectors', ".removeme\n.deleteme", 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertNotContains('removeme', $generated);
|
||||
self::assertNotContains('deleteme', $generated);
|
||||
self::assertNotContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector_needing_trim() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>'.
|
||||
'<b class="deleteme">Goodbye cruel world.</b>'.
|
||||
'<b class="removeme">Goodbye cruel world.</b>'.
|
||||
'</body></html>';
|
||||
set_config('remove_selectors', " .removeme \n .deleteme ", 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertNotContains('removeme', $generated);
|
||||
self::assertNotContains('deleteme', $generated);
|
||||
self::assertNotContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector_with_empty_line() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>'.
|
||||
'<b class="deleteme">Goodbye cruel world.</b>'.
|
||||
'<b class="removeme">Goodbye cruel world.</b>'.
|
||||
'</body></html>';
|
||||
set_config('remove_selectors', "\n\n.removeme\n\n\n\n.deleteme\n\n", 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertNotContains('removeme', $generated);
|
||||
self::assertNotContains('deleteme', $generated);
|
||||
self::assertNotContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
|
||||
public function test_remove_css_selector_with_invalid_id() {
|
||||
$this->resetAfterTest(true);
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
|
||||
set_config('remove_selectors', '#invalidid', 'auth_outage');
|
||||
$generated = $this->generated_page_html($html);
|
||||
|
||||
self::assertContains('removeme', $generated);
|
||||
self::assertContains('Goodbye cruel world', $generated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ class outagelib_test extends advanced_testcase {
|
||||
'default_title',
|
||||
'default_warning_duration',
|
||||
'allowedips',
|
||||
'remove_selectors',
|
||||
];
|
||||
// Set config with values.
|
||||
foreach ($keys as $k) {
|
||||
@@ -221,6 +222,7 @@ class outagelib_test extends advanced_testcase {
|
||||
'default_duration',
|
||||
'default_title',
|
||||
'default_warning_duration',
|
||||
'remove_selectors',
|
||||
];
|
||||
$defaults = outagelib::get_config_defaults();
|
||||
foreach ($keys as $k) {
|
||||
|
||||
Reference in New Issue
Block a user