From 6bb9320ef63865fdad235c8cd0ae5d43b508b131 Mon Sep 17 00:00:00 2001 From: Daniel Thee Roperto Date: Fri, 9 Sep 2016 11:39:44 +1000 Subject: [PATCH] Outage remodelled both in DB and PHP Class. Issue #17. --- classes/forms/outage/edit.php | 48 ++++++++++++++++++++++++++++++++--- classes/models/outage.php | 40 +++++++++++++++++++++++++++++ classes/outagelib.php | 17 ------------- edit.php | 8 ++---- lang/en/auth_outage.php | 4 +-- new.php | 4 +-- renderer.php | 8 +++--- tests/outagedb_test.php | 42 +++++++++++++++--------------- version.php | 2 +- 9 files changed, 115 insertions(+), 58 deletions(-) diff --git a/classes/forms/outage/edit.php b/classes/forms/outage/edit.php index 21512e5..f3132ad 100644 --- a/classes/forms/outage/edit.php +++ b/classes/forms/outage/edit.php @@ -16,6 +16,8 @@ namespace auth_outage\forms\outage; +use \auth_outage\models\outage; + if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); // It must be included from a Moodle page. } @@ -53,7 +55,7 @@ class edit extends \moodleform { 'text', 'title', get_string('title', 'auth_outage'), - 'maxlength="'.self::TITLE_MAX_CHARS.'"' + 'maxlength="' . self::TITLE_MAX_CHARS . '"' ); $mform->setType('title', PARAM_TEXT); @@ -74,8 +76,8 @@ class edit extends \moodleform { public function validation($data, $files) { $errors = parent::validation($data, $files); - if ($data['stoptime'] <= $data['starttime']) { - $errors['stoptime'] = get_string('stoptimeerrornotafterstart', 'auth_outage'); + if ($data['outageduration'] <= 0) { + $errors['outageduration'] = get_string('outagedurationerrorinvalid', 'auth_outage'); } if ($data['warningduration'] <= 0) { $errors['warningduration'] = get_string('warningdurationerrorinvalid', 'auth_outage'); @@ -92,4 +94,44 @@ class edit extends \moodleform { return $errors; } + /** + * Return submitted data if properly submitted or returns NULL if validation fails. + * @return outage submitted data; NULL if not valid or not submitted or cancelled + */ + public function get_data() { + // Fetch data and check if description is the correct format. + $data = parent::get_data(); + if (is_null($data)) { + return null; + } + if ($data->description['format'] != '1') { + debugging('Not implemented for format ' . $data->description['format'], DEBUG_DEVELOPER); + return null; + } + // Return an outage. + return new outage([ + 'id' => ($data->id === 0) ? null : $data->id, + 'starttime' => $data->starttime, + 'stoptime' => $data->starttime + $data->outageduration, + 'warntime' => $data->starttime - $data->warningduration, + 'title' => $data->title, + 'description' => $data->description['text'] + ]); + } + + /** + * Load in existing outage as form defaults. + * + * @param outage $outage outage object with default values + */ + public function set_data(outage $outage) { + $this->_form->setDefaults([ + 'id' => $outage->id, + 'starttime' => $outage->starttime, + 'outageduration' => $outage->stoptime - $outage->starttime, + 'warningduration' => $outage->starttime - $outage->warntime, + 'title' => $outage->title, + 'description' => ['text' => $outage->description, 'format' => '1'] + ]); + } } \ No newline at end of file diff --git a/classes/models/outage.php b/classes/models/outage.php index 6eb68fc..80abaed 100644 --- a/classes/models/outage.php +++ b/classes/models/outage.php @@ -97,6 +97,11 @@ class outage { throw new \InvalidArgumentException('$data must be null (default), an array or an object.'); } + /** + * Checks if the outage is happening. + * @param int|null $time Null to check if the outage is happening now or another time to use as reference. + * @return bool True if outage has started but not yet stopped. False otherwise including if in warning period. + */ public function is_ongoing($time = null) { if ($time === null) { $time = time(); @@ -110,4 +115,39 @@ class outage { return (($this->starttime <= $time) && ($time < $this->stoptime)); } + + /** + * Get the title with properly replaced placeholders such as {{start}} and {{stop}}. + * @return string Title. + */ + public function get_title() { + return $this->replace_placeholders($this->title); + } + + /** + * Get the description with properly replaced placeholders such as {{start}} and {{stop}}. + * @return string Description. + */ + public function get_description() { + return $this->replace_placeholders($this->description); + } + + /** + * Returns the input string with all placeholders replaced. + * @param $str string Input string. + * @return string Output string. + */ + private function replace_placeholders($str) { + return str_replace( + [ + '{{start}}', + '{{stop}}' + ], + [ + userdate($this->starttime, get_string('strftimedatetimeshort')), + userdate($this->stoptime, get_string('strftimedatetimeshort')), + ], + $str + ); + } } \ No newline at end of file diff --git a/classes/outagelib.php b/classes/outagelib.php index cbe46f5..7c63d02 100644 --- a/classes/outagelib.php +++ b/classes/outagelib.php @@ -98,21 +98,4 @@ class outagelib { } } } - - /** - * Parses data from the form ensuring it is valid for an outage object. - * - * @param $data stdClass The input data. - * @return stdClass The parsed data. - */ - public static function parseformdata(\stdClass $data) { - if ($data->description['format'] != '1') { - throw new \InvalidArgumentException('Not implemented for format ' . $data->description['format']); - } - if ($data->id === 0) { - $data->id = null; - } - $data->description = $data->description['text']; - return $data; - } } \ No newline at end of file diff --git a/edit.php b/edit.php index 0e44b3e..c8c177e 100644 --- a/edit.php +++ b/edit.php @@ -37,9 +37,7 @@ $mform = new \auth_outage\forms\outage\edit(); if ($mform->is_cancelled()) { redirect('/auth/outage/manage.php'); -} else if ($fromform = $mform->get_data()) { - $fromform = outagelib::parseformdata($fromform); - $outage = new outage($fromform); +} else if ($outage = $mform->get_data()) { $id = outagedb::save($outage); redirect('/auth/outage/manage.php#auth_outage_id_' . $id); } @@ -49,9 +47,7 @@ $outage = outagedb::get_by_id($id); if ($outage == null) { throw new invalid_parameter_exception('Outage #' . $id . ' not found.'); } -$data = get_object_vars($outage); -$data['description'] = ['text' => $data['description'], 'format' => '1']; -$mform->set_data($data); +$mform->set_data($outage); $PAGE->navbar->add($outage->title); echo $OUTPUT->header(); diff --git a/lang/en/auth_outage.php b/lang/en/auth_outage.php index 82cf8c9..524eef9 100644 --- a/lang/en/auth_outage.php +++ b/lang/en/auth_outage.php @@ -46,13 +46,13 @@ $string['outagecreate'] = 'Create Outage'; $string['outagedelete'] = 'Delete Outage'; $string['outagedeletewarning'] = 'You are about to permanently delete the outage below. This cannot be undone.'; $string['outageduration'] = 'Outage Duration'; +$string['outagedurationerrorinvalid'] = 'Outage duration must be positive.'; $string['outageslist'] = 'Outages List'; $string['pluginname'] = 'Outage manager'; $string['starttime'] = 'Start date and time'; -$string['stoptimeerrornotafterstart'] = 'Stop time must be after start time.'; $string['textplaceholdershint'] = 'You can use {{start}} and {{stop}} as placeholders on the title/description for the actual start/stop time.'; $string['titleerrorinvalid'] = 'Title cannot be left blank.'; $string['titleerrortoolong'] = 'Title cannot have more than {$a} characters.'; $string['title'] = 'Title'; -$string['warningdurationerrorinvalid'] = 'Warning duration cannot be zero.'; +$string['warningdurationerrorinvalid'] = 'Warning duration must be positive.'; $string['warningduration'] = 'Warning duration'; diff --git a/new.php b/new.php index b60d9d9..06a5f79 100644 --- a/new.php +++ b/new.php @@ -36,9 +36,7 @@ outagelib::pagesetup(); $mform = new \auth_outage\forms\outage\edit(); if ($mform->is_cancelled()) { redirect('/auth/outage/manage.php'); -} else if ($fromform = $mform->get_data()) { - $fromform = outagelib::parseformdata($fromform); - $outage = new outage($fromform); +} else if ($outage = $mform->get_data()) { $id = outagedb::save($outage); redirect('/auth/outage/manage.php#auth_outage_id_' . $id); } diff --git a/renderer.php b/renderer.php index c0928c9..573be9c 100644 --- a/renderer.php +++ b/renderer.php @@ -146,14 +146,12 @@ class auth_outage_renderer extends plugin_renderer_base { . html_writer::tag('b', ' Until: ') . $stop ) - . html_writer::div($outage->description) + . html_writer::div($outage->get_description()) . $admin ); } public function renderoutagebar(outage $outage) { - global $CFG; - $start = userdate($outage->starttime, get_string('strftimedatetimeshort')); $stop = userdate($outage->stoptime, get_string('strftimedatetimeshort')); @@ -164,10 +162,10 @@ class auth_outage_renderer extends plugin_renderer_base { ); return - html_writer::tag('style', $CFG->auth_outage_css) + html_writer::tag('style', get_config('auth_outage', 'css')) . html_writer::div( html_writer::div( - html_writer::div($outage->title, 'auth_outage_warningbar_box_title') + html_writer::div($outage->get_title(), 'auth_outage_warningbar_box_title') . html_writer::div( $message . ' ' . html_writer::tag('small', diff --git a/tests/outagedb_test.php b/tests/outagedb_test.php index 0c01258..c694d56 100644 --- a/tests/outagedb_test.php +++ b/tests/outagedb_test.php @@ -110,7 +110,7 @@ class outagedb_test extends advanced_testcase { $inserted = outagedb::get_by_id($id); self::assertNotNull($inserted); // Check its data. - foreach (['starttime', 'stoptime', 'warningduration', 'title', 'description'] as $field) { + foreach (['starttime', 'stoptime', 'warntime', 'title', 'description'] as $field) { self::assertSame($outage->$field, $inserted->$field, 'Field ' . $field . ' does not match.'); } // Check generated data. @@ -138,36 +138,35 @@ class outagedb_test extends advanced_testcase { // Have a consistent time for now (no seconds variation), helps debugging. $now = time(); - // Should never fail. self::assertEquals([], outagedb::get_all(), 'Ensure there are no other outages that can affect the test.'); self::assertNull(outagedb::get_active($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::saveoutage($now, 1, 2, 3, + 'An outage that starts in the future and is not in warning period.'); self::assertNull(outagedb::get_active($now), 'No active outages yet.'); - // An outage that is already in the past. - self::saveoutage($now, -3, -2, 1); + self::saveoutage($now, -3, -2, -1, + 'An outage that is already in the past.'); self::assertNull(outagedb::get_active($now), 'No active outages yet.'); - // An outage in warning period. - $activeid = self::saveoutage($now, 1, 2, 2); + $activeid = self::saveoutage($now, -2, 1, 2, + 'An outage in warning period.'); self::assertSame($activeid, outagedb::get_active($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::saveoutage($now, -1, 2, 3, + 'Another outage in warning period, but ignored as it starts after the previous one.'); self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.'); - // An ongoing outage. - $activeid = self::saveoutage($now, -2, 2, 1); + $activeid = self::saveoutage($now, -3, -2, 2, + 'An ongoing outage.'); self::assertSame($activeid, outagedb::get_active($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::saveoutage($now, -3, -1, 1, + 'Another ongoing outage but ignored because it started after the previous one.'); self::assertSame($activeid, outagedb::get_active($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::saveoutage($now, -3, -2, 1, + 'Another ongoing outage starting at the same time, but ignored as it stops before the previous one.'); self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.'); } @@ -175,17 +174,18 @@ class outagedb_test extends advanced_testcase { * Helper function to create an outage then save it to the database. * * @param $now int Timestamp for now, such as time(). + * @param $warning int In how many hours the warning starts. Can be negative. * @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. + * @param $title string Title for the outage. * @return int Id the of created outage. */ - private static function saveoutage($now, $start, $stop, $warning) { + private static function saveoutage($now, $warning, $start, $stop, $title) { return outagedb::save(new outage([ 'starttime' => $now + ($start * 60 * 60), 'stoptime' => $now + ($stop * 60 * 60), - 'warntime' => $now - ($warning * 60 * 60), - 'title' => 'Test Outage', + 'warntime' => $now + ($warning * 60 * 60), + 'title' => $title, 'description' => 'Test Outage Description.' ])); } @@ -200,7 +200,7 @@ class outagedb_test extends advanced_testcase { return new outage([ 'starttime' => $i * 100, 'stoptime' => $i * 100 + 50, - 'warningduration' => $i * 60, + 'warntime' => $i * 60, 'title' => 'The Title ' . $i, 'description' => 'A description in HTML.' ]); diff --git a/version.php b/version.php index 6a77e7d..c7db839 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); // It must be included from a Moodle page. } -$plugin->version = 2016090500; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2016090900; // The current plugin version (Date: YYYYMMDDXX). $plugin->release = $plugin->version; // Same as version $plugin->requires = 2014051200; // Requires Moodle 2.7 or later. $plugin->component = "auth_outage";