diff --git a/.travis.yml b/.travis.yml
index 4fbe65c..c14a668 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,8 +4,6 @@ notifications:
email:
recipients:
- daniel.roperto@catalyst-au.net
- - brendan.heywood@gmail.com
- - marcus@boon.mx
sudo: false
@@ -17,14 +15,12 @@ php:
- 5.6
env:
- - DB=pgsql MOODLE_BRANCH=MOODLE_26_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_27_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_28_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_29_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_30_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_31_STABLE
- DB=pgsql MOODLE_BRANCH=master
- - DB=mysqli MOODLE_BRANCH=MOODLE_26_STABLE
- DB=mysqli MOODLE_BRANCH=MOODLE_27_STABLE
- DB=mysqli MOODLE_BRANCH=MOODLE_28_STABLE
- DB=mysqli MOODLE_BRANCH=MOODLE_29_STABLE
diff --git a/README.md b/README.md
index d7cebd8..4761814 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,59 @@
-# Outage Moodle Authentication Module
+# Moodle Outage manager plugin
-Moodle Outage is an auth plugin that will
-* Allow for a configurable outage notification that will be displayed to users
-* Allow for only a range of IP addresses to connect prior to the outage window
+* [What is this?](#what-is-this)
+* [Why is it an auth plugin](#why-it-is-an-auth-plugin)
+* [Installation](#installation)
+* [Feedback and issues](#feedback-and-issues)
+
+What is this?
+-------------
+
+This is a Moodle plugin which makes the student experience of planned outages nicer, and provides extra tools for administrators and testers that help before and after the outage window.
+
+The main idea is that instead of an outage being a very booleon on/off situation, this plugin creates the concept of graduated outages where at predefined times before an outage and after, different levels of warning and access can be provided to students and testers letting them know what is about to happen and why.
+
+
+Why it is an auth plugin?
+-------------------------
+
+One of the graduated stages this plugin introduces is a 'tester only' mode which disables login for most normal users. This is conceptually similar to the maintenance mode but enables testers to login and confirm the state after an upgrade without needing full admin privileges.
+
+
+Installation
+------------
+
+1. Install the plugin the same as any standard moodle plugin either via the
+Moodle plugin directory, or you can use git to clone it into your source:
+
+ ```git clone git@github.com:catalyst/moodle-auth_outage.git auth/basic```
+
+ Or install via the Moodle plugin directory:
+
+ https://moodle.org/plugins/auth_outage
+
+2. Then run the Moodle upgrade
+
+If you have issues please log them in github here:
+
+https://github.com/catalyst/moodle-auth_outage/issues
+
+3. Go to Dashboard ► Site administration ► Plugins ► Authentication ► Manage authentication and enable the auth_outage plugin and make it the very first auth plugin
+
+4. Go to Dashboard ► Site administration ► Plugins ► Authentication ► Outage ► Manage and set up your future outages
+
+
+Feedback and issues
+-------------------
+
+Please raise any issues in github:
+
+https://github.com/catalyst/moodle-auth_outage/issues
+
+Pull requests are welcome :)
+
+If you need anything urgently or would like to sponsor a feature please contact Catalyst IT Australia:
+
+https://www.catalyst-au.net/contact-us
diff --git a/auth.php b/auth.php
index 0d84e2c..b8838f9 100644
--- a/auth.php
+++ b/auth.php
@@ -46,7 +46,7 @@ class auth_plugin_outage extends auth_plugin_base
* Do not authenticate users.
* @return bool False
*/
- public function user_login() {
+ public function user_login($username, $password) {
return false;
}
}
diff --git a/change.php b/change.php
index e16fa41..af70983 100644
--- a/change.php
+++ b/change.php
@@ -41,7 +41,7 @@ if ($mform->is_cancelled()) {
$fromform = outagelib::parseformdata($fromform);
$outage = new outage($fromform);
$id = outagedb::save($outage);
- redirect('/auth/outage/list.php#auth_outage_id=' . $id);
+ redirect('/auth/outage/list.php#auth_outage_id_' . $id);
}
$id = required_param('id', PARAM_INT);
@@ -53,7 +53,7 @@ $data = get_object_vars($outage);
$data['description'] = ['text' => $data['description'], 'format' => '1'];
$mform->set_data($data);
-
+$PAGE->navbar->add($outage->title);
echo $OUTPUT->header();
echo $renderer->rendersubtitle('modifyoutage');
$mform->display();
diff --git a/classes/event/outage_created.php b/classes/event/outage_created.php
new file mode 100644
index 0000000..28ef9d1
--- /dev/null
+++ b/classes/event/outage_created.php
@@ -0,0 +1,48 @@
+.
+
+namespace auth_outage\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The auth_outage outage created class.
+ *
+ * @package auth_outage
+ * @author Daniel Thee Roperto
+ * @copyright Catalyst IT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class outage_created extends \core\event\base {
+ /**
+ * Init method.
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'auth_outage';
+ $this->data['crud'] = 'c';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ $this->context = \context_system::instance();
+ }
+
+ public function get_description() {
+ return "The user with the id '{$this->userid}' created a new outage title '{$this->other['title']}' "
+ . " with id '{$this->other['id']}'.";
+ }
+
+ public function get_url() {
+ return new \moodle_url('/auth/outage/list.php#auth_outage_id_' . $this->other['id']);
+ }
+}
diff --git a/classes/event/outage_deleted.php b/classes/event/outage_deleted.php
new file mode 100644
index 0000000..f73a516
--- /dev/null
+++ b/classes/event/outage_deleted.php
@@ -0,0 +1,48 @@
+.
+
+namespace auth_outage\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The auth_outage outage deleted class.
+ *
+ * @package auth_outage
+ * @author Daniel Thee Roperto
+ * @copyright Catalyst IT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class outage_deleted extends \core\event\base {
+ /**
+ * Init method.
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'auth_outage';
+ $this->data['crud'] = 'd';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ $this->context = \context_system::instance();
+ }
+
+ public function get_description() {
+ return "The user with the id '{$this->userid}' deleted the outage titled '{$this->other['title']}' "
+ . "with id '{$this->other['id']}'.";
+ }
+
+ public function get_url() {
+ return new \moodle_url('/auth/outage/list.php#auth_outage_id_' . $this->other['id']);
+ }
+}
diff --git a/classes/event/outage_updated.php b/classes/event/outage_updated.php
new file mode 100644
index 0000000..59a846e
--- /dev/null
+++ b/classes/event/outage_updated.php
@@ -0,0 +1,49 @@
+.
+
+namespace auth_outage\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The auth_outage outage updated class.
+ *
+ * @package auth_outage
+ * @author Daniel Thee Roperto
+ * @copyright Catalyst IT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class outage_updated extends \core\event\base {
+ /**
+ * Init method.
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'auth_outage';
+ $this->data['crud'] = 'u';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ $this->context = \context_system::instance();
+ }
+
+
+ public function get_description() {
+ return "The user with the id '{$this->userid}' updated the outage title '{$this->other['title']}' "
+ . "with id '{$this->other['id']}'.";
+ }
+
+ public function get_url() {
+ return new \moodle_url('/auth/outage/list.php');
+ }
+}
diff --git a/classes/forms/outage/edit.php b/classes/forms/outage/edit.php
index 9c511e4..3419b48 100644
--- a/classes/forms/outage/edit.php
+++ b/classes/forms/outage/edit.php
@@ -31,6 +31,8 @@ require_once($CFG->libdir . '/formslib.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit extends \moodleform {
+ const TITLE_MAX_CHARS = 100;
+
/**
* {@inheritDoc}
* @see moodleform::definition()
@@ -47,7 +49,12 @@ class edit extends \moodleform {
$mform->addElement('duration', 'warningduration', get_string('warningduration', 'auth_outage'));
- $mform->addElement('text', 'title', get_string('title', 'auth_outage'));
+ $mform->addElement(
+ 'text',
+ 'title',
+ get_string('title', 'auth_outage'),
+ 'maxlength="'.self::TITLE_MAX_CHARS.'"'
+ );
$mform->setType('title', PARAM_TEXT);
$mform->addElement('editor', 'description', get_string('description', 'auth_outage'));
@@ -65,6 +72,24 @@ class edit extends \moodleform {
public function validation($data, $files) {
$errors = parent::validation($data, $files);
+ if ($data['starttime'] <= time()) {
+ $errors['starttime'] = get_string('starttimeerrornotinfuture', 'auth_outage');
+ }
+ if ($data['stoptime'] <= $data['starttime']) {
+ $errors['stoptime'] = get_string('stoptimeerrornotafterstart', 'auth_outage');
+ }
+ if ($data['warningduration'] <= 0) {
+ $errors['warningduration'] = get_string('warningdurationerrorinvalid', 'auth_outage');
+ }
+
+ $titlelen = strlen(trim($data['title']));
+ if ($titlelen == 0) {
+ $errors['title'] = get_string('titleerrorinvalid', 'auth_outage');
+ }
+ if ($titlelen > self::TITLE_MAX_CHARS) {
+ $errors['title'] = get_string('titleerrortoolong', 'auth_outage', self::TITLE_MAX_CHARS);
+ }
+
return $errors;
}
diff --git a/classes/outagedb.php b/classes/outagedb.php
index ff0da94..59e2821 100644
--- a/classes/outagedb.php
+++ b/classes/outagedb.php
@@ -27,8 +27,7 @@ namespace auth_outage;
use auth_outage\models\outage;
-final class outagedb
-{
+final class outagedb {
/**
* Private constructor, use static methods instead.
*/
@@ -86,23 +85,29 @@ final class outagedb
// Do not change the original object.
$outage = clone $outage;
- // If new outage, set its creator.
- if ($outage->id === null) {
- $outage->createdby = $USER->id;
- }
-
// Update control fields.
$outage->modifiedby = $USER->id;
$outage->lastmodified = time();
- // If new, create it and return the id.
if ($outage->id === null) {
- return $DB->insert_record('auth_outage', $outage, true);
+ // If new outage, set its creator.
+ $outage->createdby = $USER->id;
+ // Then create it, log it and adjust its id.
+ $outage->id = $DB->insert_record('auth_outage', $outage, true);
+ \auth_outage\event\outage_created::create(
+ ['objectid' => $outage->id, 'other' => (array)$outage]
+ )->trigger();
+ } else {
+ // Remove the createdby field so it does not get updated.
+ unset($outage->createdby);
+ $DB->update_record('auth_outage', $outage);
+ // Log it.
+ \auth_outage\event\outage_updated::create(
+ ['objectid' => $outage->id, 'other' => (array)$outage]
+ )->trigger();
}
- // Clean up the class (remove creator field), then update it and return its id.
- unset($outage->createdby);
- $DB->update_record('auth_outage', $outage);
+ // All done, return the id.
return $outage->id;
}
@@ -122,6 +127,12 @@ final class outagedb
throw new \InvalidArgumentException('$id must be positive.');
}
+ // Log it.
+ $previous = $DB->get_record('auth_outage', ['id' => $id], '*', MUST_EXIST);
+ $event = \auth_outage\event\outage_deleted::create(['objectid' => $id, 'other' => (array)$previous]);
+ $event->add_record_snapshot('auth_outage', $previous);
+ $event->trigger();
+
$DB->delete_records('auth_outage', ['id' => $id]);
}
}
\ No newline at end of file
diff --git a/create.php b/create.php
index f658da1..329a938 100644
--- a/create.php
+++ b/create.php
@@ -40,9 +40,10 @@ if ($mform->is_cancelled()) {
$fromform = outagelib::parseformdata($fromform);
$outage = new outage($fromform);
$id = outagedb::save($outage);
- redirect('/auth/outage/list.php#auth_outage_id=' . $id);
+ redirect('/auth/outage/list.php#auth_outage_id_' . $id);
}
+$PAGE->navbar->add(get_string('outagecreate', 'auth_outage'));
echo $OUTPUT->header();
$mform->display();
diff --git a/db/install.xml b/db/install.xml
index 4f2297e..f375742 100644
--- a/db/install.xml
+++ b/db/install.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/lang/en/auth_outage.php b/lang/en/auth_outage.php
index 83918af..0febcae 100644
--- a/lang/en/auth_outage.php
+++ b/lang/en/auth_outage.php
@@ -24,25 +24,27 @@
*/
$string['auth_outagedescription'] = 'Auxiliary plugin that warns users about a future outage and prevents them from logging in once the outage starts.';
-$string['pluginname'] = 'Outage';
-
-$string['menudefaults'] = 'Default Settings';
-$string['menumanage'] = 'Manage';
-
-$string['defaultwarningtime'] = 'Default Warning Time';
-$string['defaultwarningtimedescription'] = 'Default warning time (in minutes) for outages.';
$string['defaultwarningmessage'] = 'Default Warning Message';
$string['defaultwarningmessagedescription'] = 'Default warning message for outages. Use [from] and [until] placeholders as required.';
$string['defaultwarningmessagevalue'] = 'There is an scheduled maintenance from [from] to [until] and our system will not be available during that time.';
-
-$string['starttime'] = 'Start date and time';
-$string['stoptime'] = 'Stop date and time';
-$string['warningduration'] = 'Warning duration';
-$string['title'] = 'Title';
+$string['defaultwarningtime'] = 'Default Warning Time';
+$string['defaultwarningtimedescription'] = 'Default warning time (in minutes) for outages.';
$string['description'] = 'Public description';
+$string['menudefaults'] = 'Default Settings';
+$string['menumanage'] = 'Manage';
+$string['modify'] = 'Modify';
$string['modifyoutage'] = 'Modify Outage';
-$string['removeoutage'] = 'Remove Outage';
-$string['removeoutagewarning'] = 'You are about to permanently remove the outage below. This cannot be undone.';
+$string['outagecreate'] = 'Create Outage';
+$string['outageremove'] = 'Remove Outage';
+$string['outageremovewarning'] = 'You are about to permanently remove the outage below. This cannot be undone.';
$string['outageslist'] = 'Outages List';
-$string['createoutage'] = 'Create Outage';
-$string['modify'] = 'Modify';
\ No newline at end of file
+$string['pluginname'] = 'Outage';
+$string['starttimeerrornotinfuture'] = 'Start time must be in the future.';
+$string['starttime'] = 'Start date and time';
+$string['stoptimeerrornotafterstart'] = 'Stop time must be after start time.';
+$string['stoptime'] = 'Stop date and 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['warningduration'] = 'Warning duration';
diff --git a/renderer.php b/renderer.php
index f95945d..0ec3f45 100644
--- a/renderer.php
+++ b/renderer.php
@@ -39,8 +39,8 @@ class auth_outage_renderer extends plugin_renderer_base
}
public function renderdeleteconfirmation(outage $outage) {
- return $this->rendersubtitle('removeoutage')
- . html_writer::tag('p', get_string('removeoutagewarning', 'auth_outage'))
+ return $this->rendersubtitle('outageremove')
+ . html_writer::tag('p', get_string('outageremovewarning', 'auth_outage'))
. $this->renderoutage($outage, false);
}
@@ -58,12 +58,13 @@ class auth_outage_renderer extends plugin_renderer_base
$url = new moodle_url('/auth/outage/create.php');
$img = html_writer::empty_tag('img',
['src' => $OUTPUT->pix_url('t/add'), 'alt' => get_string('create'), 'class' => 'iconsmall']);
- $html .= html_writer::empty_tag('br')
- . html_writer::link(
+ $html .= html_writer::tag('p',
+ html_writer::link(
$url,
- $img . ' ' . get_string('createoutage', 'auth_outage'),
- ['title' => get_string('remove')])
- . html_writer::empty_tag('br');
+ $img . ' ' . get_string('outagecreate', 'auth_outage'),
+ ['title' => get_string('remove')]
+ )
+ );
return $html;
}
diff --git a/version.php b/version.php
index 4a42a07..6a77e7d 100644
--- a/version.php
+++ b/version.php
@@ -29,8 +29,8 @@ if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); // It must be included from a Moodle page.
}
-$plugin->version = 2016090100; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2016090500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = $plugin->version; // Same as version
-$plugin->requires = 2013111811; // Requires Moodle 2.6 or later.
+$plugin->requires = 2014051200; // Requires Moodle 2.7 or later.
$plugin->component = "auth_outage";
$plugin->maturity = MATURITY_ALPHA; // Not suitable for PRODUCTION environments yet!