diff --git a/classes/models/outage.php b/classes/models/outage.php index aca44be..a610c5e 100644 --- a/classes/models/outage.php +++ b/classes/models/outage.php @@ -27,8 +27,7 @@ namespace auth_outage\models; use auth_outage\outagelib; -class outage -{ +class outage { /** * @var int Outage ID (auto generated by the DB). */ @@ -85,6 +84,13 @@ class outage if (is_object($data) || is_array($data)) { outagelib::data2object($data, $this); + + // FIXME types are wrong. Is this behaving as expected? + foreach (['createdby', 'id', 'lastmodified', 'modifiedby', 'starttime', 'stoptime', 'warningduration'] + as $f) { + $this->$f = ($this->$f === null) ? null : (int)$this->$f; + } + return; } diff --git a/classes/outagedb.php b/classes/outagedb.php index 59e2821..5aee078 100644 --- a/classes/outagedb.php +++ b/classes/outagedb.php @@ -135,4 +135,32 @@ final class outagedb { $DB->delete_records('auth_outage', ['id' => $id]); } -} \ No newline at end of file + + public static function getactive($time = null) { + global $DB; + + if ($time === null) { + $time = time(); + } + if (!is_int($time)) { + throw new \InvalidArgumentException('$time must be null or an int.'); + } + + // TODO Is there a way to use Moodle API instead of writing SQL (conditions not equals)? + // TODO Query not fully using indexes (starttime + 90) + // Gets any active outage (already started or during warning period). + // Gets only one record if available, the one that starts(ed) first and that stops last. + $now = time(); + $data = $DB->get_record_sql(' + SELECT * + FROM {auth_outage} + WHERE (starttime - warningduration <= :now1 AND stoptime >= :now2) + ORDER BY starttime ASC, stoptime DESC, title ASC + LIMIT 1 + ', + ['now1' => $now, 'now2' => $now] + ); + + return ($data === false) ? null : new \auth_outage\models\outage($data); + } +} diff --git a/classes/outagelib.php b/classes/outagelib.php index 8f36e08..0e1492a 100644 --- a/classes/outagelib.php +++ b/classes/outagelib.php @@ -52,6 +52,9 @@ class outagelib { return $PAGE->get_renderer('auth_outage'); } + /** + * Will check for ongoing or warning outages and will attach the message bar as required. + */ public static function initialize() { global $CFG; @@ -61,17 +64,9 @@ class outagelib { } self::$initialized = true; - // Stop if no current outage is found. - $outage = new \auth_outage\models\outage([ - 'starttime' => time() - 60, // 1 minute ago. - 'stoptime' => time() + 60 * 60, // In 1 hour. - 'warningduration' => 1, // Does not matter. - 'title' => 'Fixed Outage', - 'description' => '

This is an OUTAGE.

' - ]); - // FIXME Get from DB instead. - if (!$outage) return; - $CFG->additionalhtmltopofbody .= self::get_renderer()->renderbar($outage); + if (($active = outagedb::getactive()) == null) return; + + $CFG->additionalhtmltopofbody .= self::get_renderer()->renderbar($active); } /** diff --git a/lib.php b/lib.php index 78ccf77..7eb1e0b 100644 --- a/lib.php +++ b/lib.php @@ -29,7 +29,14 @@ function auth_outage_extend_navigation_user() { } function auth_outage_extend_navigation($data) { - // Never called? + global $CFG; + + // FIXME if function is not used, remove it completely. + if ($CFG->debugdisplay) { + var_dump($data); + throw new \Exception("Check outage/lib.php"); + } + \auth_outage\outagelib::initialize(); } diff --git a/tests/outagedb_test.php b/tests/outagedb_test.php index 5226c64..77704f1 100644 --- a/tests/outagedb_test.php +++ b/tests/outagedb_test.php @@ -29,8 +29,7 @@ use auth_outage\outagedb; defined('MOODLE_INTERNAL') || die(); -class outagedb_test extends advanced_testcase -{ +class outagedb_test extends advanced_testcase { /** * Make sure we can save and update. */ @@ -95,7 +94,6 @@ class outagedb_test extends advanced_testcase * Perform some tests on the data itself, checking values after inserted and updated. */ public function test_basiccrud() { - return; $this->resetAfterTest(true); // Create some outages. @@ -134,6 +132,64 @@ class outagedb_test extends advanced_testcase } } + public function test_getactive() { + $this->resetAfterTest(true); + + // Have a consistent time for now (no seconds variation), helps debugging. + $now = time(); + + // Should never fail. + self::assertEquals([], outagedb::getall(), 'Ensure there are no other outages that can affect the test.'); + self::assertNull(outagedb::getactive($now), 'There should be no active outage at this point.'); + + // An outage that starts in the future and is not in warning period. + self::saveoutage($now, 2, 3, 1); + self::assertNull(outagedb::getactive($now), 'No active outages yet.'); + + // An outage that is already in the past. + self::saveoutage($now, -3, -2, 1); + self::assertNull(outagedb::getactive($now), 'No active outages yet.'); + + // An outage in warning period. + $activeid = self::saveoutage($now, 1, 2, 2); + self::assertSame($activeid, outagedb::getactive($now)->id, 'Wrong active outage picked.'); + + // Another outage in warning period, but ignored as it starts after the previous one. + self::saveoutage($now, 2, 3, 3); + self::assertSame($activeid, outagedb::getactive($now)->id, 'Wrong active outage picked.'); + + // An ongoing outage. + $activeid = self::saveoutage($now, -2, 2, 1); + self::assertSame($activeid, outagedb::getactive($now)->id, 'Wrong active outage picked.'); + + // Another ongoing outage but ignored because it started after the previous one. + self::saveoutage($now, -1, 2, 1); + self::assertSame($activeid, outagedb::getactive($now)->id, 'Wrong active outage picked.'); + + // Another ongoing outage starting at the same time, but ignored as it stops before the previous one. + self::saveoutage($now, -2, 1, 1); + self::assertSame($activeid, outagedb::getactive($now)->id, 'Wrong active outage picked.'); + } + + /** + * Helper function to create an outage then save it to the database. + * + * @param $now int Timestamp for now, such as time(). + * @param $start int In how many hours this outage starts. Can be negative. + * @param $stop int In how many hours this outage finishes. Can be negative. + * @param $warning int Warning duration in hours. + * @return int Id the of created outage. + */ + private static function saveoutage($now, $start, $stop, $warning) { + return outagedb::save(new outage([ + 'starttime' => $now + ($start * 60 * 60), + 'stoptime' => $now + ($stop * 60 * 60), + 'warningduration' => ($warning * 60 * 60), + 'title' => 'Test Outage', + 'description' => 'Test Outage Description.' + ])); + } + /** * Helper function to create an outage for tests. *