diff --git a/bootstrap.php b/bootstrap.php
index 324f6d6d..13ad68de 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -69,6 +69,7 @@
}
// 3) Check for allowed scripts or IPs during outages.
+$outageinfo = false;
if (!empty($_SERVER['REQUEST_URI'])) {
$rooturl = parse_url($CFG->wwwroot);
$path = '';
diff --git a/classes/calendar/calendar.php b/classes/calendar/calendar.php
index 3cea7a08..941df2cb 100644
--- a/classes/calendar/calendar.php
+++ b/classes/calendar/calendar.php
@@ -40,16 +40,18 @@ private function __construct() {
/**
* Create an event on the calendar for this outage.
* @param outage $outage Outage to be added to the calendar.
+ * @return void
*/
- public static function create(outage $outage) {
+ public static function create(outage $outage): void {
calendar_event::create(self::create_data($outage));
}
/**
* Updates an event on the calendar based on this outage.
* @param outage $outage Outage to be updated in the calendar.
+ * @return void
*/
- public static function update(outage $outage) {
+ public static function update(outage $outage): void {
$event = self::load($outage->id);
if (is_null($event)) {
@@ -63,8 +65,9 @@ public static function update(outage $outage) {
/**
* Removes an event from the calendar related to this outage.
* @param int $outageid Id of outage to be deleted from the calendar.
+ * @return void
*/
- public static function delete($outageid) {
+ public static function delete(int $outageid): void {
$event = self::load($outageid);
// If not found (was not created before) ignore it.
diff --git a/classes/dml/outagedb.php b/classes/dml/outagedb.php
index 91d7943f..3e39238a 100644
--- a/classes/dml/outagedb.php
+++ b/classes/dml/outagedb.php
@@ -48,6 +48,7 @@ private function __construct() {
/**
* Gets all outage entries.
+ * @return outage[]
*/
public static function get_all() {
global $DB;
@@ -361,7 +362,7 @@ public static function get_ongoing($time = null) {
$data = $DB->get_records_select(
'auth_outage',
'starttime <= :datetime1 AND :datetime2 <= stoptime AND finished IS NULL',
- ['datetime1' => $time, 'datetime2' => $time, 'datetime3' => $time],
+ ['datetime1' => $time, 'datetime2' => $time],
'starttime ASC, stoptime DESC, title ASC',
'*',
0,
diff --git a/classes/form/outage/edit.php b/classes/form/outage/edit.php
index 20be069d..d54a9df5 100644
--- a/classes/form/outage/edit.php
+++ b/classes/form/outage/edit.php
@@ -67,6 +67,7 @@ public function definition() {
$mform->addHelpButton('title', 'title', 'auth_outage');
$mform->addElement('editor', 'description', get_string('description', 'auth_outage'));
+ $mform->setType('description[text]', PARAM_RAW);
$mform->addHelpButton('description', 'description', 'auth_outage');
$mform->addElement('static', 'usagehints', '', get_string('textplaceholdershint', 'auth_outage'));
@@ -79,6 +80,7 @@ public function definition() {
get_string('useaccesskey:desc', 'auth_outage'),
0
);
+ $mform->setType('useaccesskey', PARAM_BOOL);
$mform->addElement('text', 'accesskey', get_string('accesskey', 'auth_outage'));
$mform->setType('accesskey', PARAM_TEXT);
diff --git a/classes/local/cli/cli_exception.php b/classes/local/cli/cli_exception.php
index ee871d03..4b9769e0 100644
--- a/classes/local/cli/cli_exception.php
+++ b/classes/local/cli/cli_exception.php
@@ -79,6 +79,6 @@ class cli_exception extends Exception {
* @param Exception|null $previous Another exception as reference or null.
*/
public function __construct($message, $code = 1, ?Exception $previous = null) {
- parent::__construct('*ERROR* ' . $message, $code, $previous = null);
+ parent::__construct('*ERROR* ' . $message, $code, $previous);
}
}
diff --git a/classes/local/cli/clibase.php b/classes/local/cli/clibase.php
index a1cbc3a0..b3f4e458 100644
--- a/classes/local/cli/clibase.php
+++ b/classes/local/cli/clibase.php
@@ -114,7 +114,6 @@ abstract public function execute();
* Change session to admin user.
*/
protected function become_admin_user() {
- global $DB;
$user = get_admin();
unset($user->description);
unset($user->access);
diff --git a/classes/local/cli/create.php b/classes/local/cli/create.php
index 3d1588c8..3d14fefd 100644
--- a/classes/local/cli/create.php
+++ b/classes/local/cli/create.php
@@ -28,8 +28,7 @@
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class create extends clibase
-{
+class create extends clibase {
/**
* @var mixed[] Defaults to use if given option is null.
*/
@@ -99,6 +98,7 @@ public function set_defaults(array $defaults) {
/**
* Executes the CLI.
+ * @throws cli_exception
*/
public function execute() {
// Help always overrides any other parameter.
@@ -269,32 +269,4 @@ private function merge_options_check_parameters_string_nonempty($option, $param)
}
return $option;
}
-
- /**
- * Ensures the given option is or can be converted to a bool.
- * @param mixed $option The parameter to check.
- * @param string $param Name of that parameter.
- * @return bool The converted parameter.
- * @throws cli_exception
- */
- private function merge_options_check_parameters_bool($option, $param) {
- if (is_bool($option)) {
- return $option;
- }
-
- if (is_string($option)) {
- $option = strtoupper($option);
- if (in_array($option, ['0', 'FALSE', 'NO', 'N'])) {
- return false;
- }
- if (in_array($option, ['1', 'TRUE', 'YES', 'Y'])) {
- return true;
- }
- }
-
- throw new cli_exception(
- get_string('clierrorinvalidvaluenotbool', 'auth_outage', ['param' => $param]),
- cli_exception::ERROR_PARAMETER_INVALID
- );
- }
}
diff --git a/classes/local/cli/finish.php b/classes/local/cli/finish.php
index cc4a9a83..fa7fdee8 100644
--- a/classes/local/cli/finish.php
+++ b/classes/local/cli/finish.php
@@ -56,6 +56,7 @@ public function generate_shortcuts() {
/**
* Executes the CLI.
+ * @throws cli_exception
*/
public function execute() {
// Help always overrides any other parameter.
diff --git a/classes/local/cli/waitforit.php b/classes/local/cli/waitforit.php
index dd951038..555831d3 100644
--- a/classes/local/cli/waitforit.php
+++ b/classes/local/cli/waitforit.php
@@ -101,6 +101,7 @@ public function execute() {
$outage = $this->get_outage();
while ($sleep = $this->wait_for_outage_to_start($outage)) {
+ $sleep = max(1, $sleep);
if (is_null($this->sleepcallback)) {
$this->verbose('Sleeping for ' . $sleep . ' second(s).');
sleep($sleep);
diff --git a/classes/local/controllers/infopage.php b/classes/local/controllers/infopage.php
index acfe1266..3f64ff44 100644
--- a/classes/local/controllers/infopage.php
+++ b/classes/local/controllers/infopage.php
@@ -47,11 +47,6 @@ class infopage {
* @param array|null $params Parameters to use or null to get from Moodle API (request).
*/
public function __construct(?array $params = null) {
- global $CFG;
- // Enable SVG support here to make sure all SVG files
- // used in the current theme are served properly.
- $CFG->svgicons = true;
-
if (is_null($params)) {
$params = [
'id' => optional_param('id', null, PARAM_INT),
@@ -101,21 +96,29 @@ public function output() {
if (!$this->static && !has_capability('auth/outage:viewinfo', context_system::instance())) {
redirect(new moodle_url('/'));
}
+
+ // Enable SVG support here to make sure all SVG files
+ // used in the current theme are served properly.
+ $previoussvg = $CFG->svgicons ?? null;
+ $CFG->svgicons = true;
+
$PAGE->set_context(context_system::instance());
$PAGE->set_title($this->outage->get_title());
$PAGE->set_heading($this->outage->get_title());
$PAGE->set_url(new moodle_url('/auth/outage/info.php'));
- // No hooks injecting into this page, do it manually.
- echo outagelib::get_inject_code();
-
- // Inject metadata into the header before output.
+ // Inject metadata into the header before any output starts, otherwise header() will
+ // fail once outagelib::get_inject_code() below has echoed anything.
if (!empty($this->outage->metadata)) {
- header('X-Outage-Metadata: ' . $this->outage->metadata);
+ $safemeta = str_replace(["\r", "\n"], '', $this->outage->metadata);
+ header('X-Outage-Metadata: ' . $safemeta);
header('X-Outage-StartTime: ' . $this->outage->starttime);
header('X-Outage-EndTime: ' . $this->outage->stoptime);
}
+ // No hooks injecting into this page, do it manually.
+ echo outagelib::get_inject_code();
+
echo $OUTPUT->header();
$viewbag = [
'admin' => is_siteadmin(),
@@ -123,10 +126,8 @@ public function output() {
];
require($CFG->dirroot . '/auth/outage/views/info/content.php');
- // Moodle 2.7 did not check for CLI mode, which was fixed later.
- if (!($CFG->branch == '27' && CLI_SCRIPT)) {
- echo $OUTPUT->footer();
- }
+ echo $OUTPUT->footer();
+ $CFG->svgicons = $previoussvg;
}
/**
diff --git a/classes/local/controllers/maintenance_static_page.php b/classes/local/controllers/maintenance_static_page.php
index 4a6896dc..8536771b 100644
--- a/classes/local/controllers/maintenance_static_page.php
+++ b/classes/local/controllers/maintenance_static_page.php
@@ -51,7 +51,8 @@ public static function create_from_outage($outage) {
} else {
// Inject metadata into the header before output.
if (!empty($outage->metadata)) {
- header('X-Outage-Metadata: ' . $outage->metadata);
+ $safemeta = str_replace(["\r", "\n"], '', $outage->metadata);
+ header('X-Outage-Metadata: ' . $safemeta);
header('X-Outage-StartTime: ' . $outage->starttime);
header('X-Outage-EndTime: ' . $outage->stoptime);
}
diff --git a/classes/local/outagelib.php b/classes/local/outagelib.php
index 35565d34..c13a2163 100644
--- a/classes/local/outagelib.php
+++ b/classes/local/outagelib.php
@@ -51,6 +51,7 @@ class outagelib {
/**
* Fetches page.
* @param string $file file to be fetched
+ * @return array{contents: string|false, mime: string}
*/
public static function fetch_page($file) {
global $CFG;
@@ -69,6 +70,7 @@ public static function fetch_page($file) {
/**
* Resets inject called to allow the code to be regenerated.
+ * @return void
*/
public static function reset_injectcalled() {
self::$injectcalled = false;
@@ -77,6 +79,7 @@ public static function reset_injectcalled() {
/**
* Given a time, usually now, when is the next outage window?
* @param int $time time for next window
+ * @return int
*/
public static function get_next_window($time = null) {
@@ -177,6 +180,7 @@ public static function get_config_defaults() {
'default_warning_duration' => (string)(60 * 60),
'default_title' => get_string('defaulttitlevalue', 'auth_outage'),
'default_description' => get_string('defaultdescriptionvalue', 'auth_outage'),
+ 'default_metadata' => '',
'remove_selectors' => ".usermenu\n.logininfo\n.homelink",
];
}
@@ -284,7 +288,7 @@ public static function create_climaintenancephp_code($starttime, $stoptime, $all
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
// Put access key as a cookie if given. This stops the need to put it as a url param on every request.
- $urlaccesskey = optional_param('accesskey', null, PARAM_TEXT);
+ $urlaccesskey = optional_param('accesskey', null, PARAM_ALPHANUM);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
@@ -328,7 +332,8 @@ public static function create_climaintenancephp_code($starttime, $stoptime, $all
}
if ({{USEACCESSKEY}} && $accesskeyblocked) {
- echo '';
+ $safeaccesskey = htmlspecialchars($useraccesskey ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');
+ echo '';
}
if (!$isphpunit) {
diff --git a/classes/output/renderer.php b/classes/output/renderer.php
index 4fce37b1..35288ca4 100644
--- a/classes/output/renderer.php
+++ b/classes/output/renderer.php
@@ -187,8 +187,8 @@ private function renderoutage(outage $outage, $buttons) {
$outagehtml = html_writer::div(
html_writer::tag(
'blockquote',
- html_writer::div(html_writer::tag('b', $outage->get_title(), ['data-id' => $outage->id])) .
- html_writer::div(html_writer::tag('i', $outage->get_description())) .
+ html_writer::div(html_writer::tag('b', format_string($outage->get_title()), ['data-id' => $outage->id])) .
+ html_writer::div(html_writer::tag('i', format_text($outage->get_description(), FORMAT_HTML))) .
html_writer::div(
html_writer::tag('b', get_string('tableheaderwarnbefore', 'auth_outage') . ': ') .
format_time($outage->get_warning_duration())
diff --git a/classes/task/update_static_page.php b/classes/task/update_static_page.php
index 2aeff3eb..10163538 100644
--- a/classes/task/update_static_page.php
+++ b/classes/task/update_static_page.php
@@ -37,7 +37,10 @@ public function get_name() {
}
/**
- * Executes the event.
+ * Executes the task: regenerates the maintenance static page for the next scheduled outage.
+ *
+ * @throws \coding_exception
+ * @throws \file_exception
*/
public function execute() {
outagelib::prepare_next_outage();
diff --git a/db/install.xml b/db/install.xml
index 1dcc2a1e..4f11b419 100644
--- a/db/install.xml
+++ b/db/install.xml
@@ -21,9 +21,14 @@