From 18c5c75a1c5b8cb67f390082b239701782741443 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 00:58:41 +0000 Subject: [PATCH 001/142] Fix template code inclusion Override the default incorrect path to the page code directory --- source/lib/StatusBoard/Main.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/Main.class.php b/source/lib/StatusBoard/Main.class.php index 650c6ac..35d63bc 100644 --- a/source/lib/StatusBoard/Main.class.php +++ b/source/lib/StatusBoard/Main.class.php @@ -5,6 +5,7 @@ require 'smarty/Smarty.class.php'; class StatusBoard_Main extends SihnonFramework_Main { const TEMPLATE_DIR = '../source/webui/templates/'; + const CODE_DIR = '../source/webui/pages/'; protected static $instance; @@ -20,7 +21,7 @@ class StatusBoard_Main extends SihnonFramework_Main { $request_string = isset($_GET['l']) ? $_GET['l'] : ''; - $this->request = new StatusBoard_RequestParser($request_string, self::TEMPLATE_DIR); + $this->request = new StatusBoard_RequestParser($request_string, self::TEMPLATE_DIR, self::CODE_DIR); switch (StatusBoard_File) { case 'ajax': From c8eaee79a111904f02224bf467392d0e4747b9ab Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 00:59:30 +0000 Subject: [PATCH 002/142] Add entity classes Add object wrappers for the application database entities. --- source/lib/StatusBoard/Incident.class.php | 139 ++++++++++++++++++ .../lib/StatusBoard/IncidentStatus.class.php | 12 ++ source/lib/StatusBoard/Service.class.php | 99 +++++++++++++ source/lib/StatusBoard/Site.class.php | 120 +++++++++++++++ source/lib/StatusBoard/Status.class.php | 29 ++++ 5 files changed, 399 insertions(+) create mode 100644 source/lib/StatusBoard/Incident.class.php create mode 100644 source/lib/StatusBoard/IncidentStatus.class.php create mode 100644 source/lib/StatusBoard/Service.class.php create mode 100644 source/lib/StatusBoard/Site.class.php create mode 100644 source/lib/StatusBoard/Status.class.php diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php new file mode 100644 index 0000000..4bf30bf --- /dev/null +++ b/source/lib/StatusBoard/Incident.class.php @@ -0,0 +1,139 @@ +id = $id; + $this->site = $site; + $this->reference = $reference; + $this->description = $description; + $this->start_time = $start_time; + $this->estimated_end_time = $estimated_end_time; + $this->actual_end_time = $actual_end_time; + } + + public static function fromDatabaseRow($row) { + return new self( + $row['id'], + $row['site'], + $row['reference'], + $row['description'], + $row['start_time'], + $row['estimated_end_time'], + $row['actual_end_time'] + ); + } + + /** + * Load an Incident object given its ID + * + * @param int $id + * @return StatusBoard_Incident + */ + public static function fromId($id) { + $database = StatusBoard_Main::instance()->database(); + + $incident = self::fromDatabaseRow( + $database->selectOne('SELECT * FROM `incident` WHERE id=:id', array( + array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) + ) + ) + ); + + return $incident; + } + + public static function all() { + $incidents = array(); + + $database = StatusBoard_Main::instance()->database(); + foreach ($database->selectList('SELECT * FROM `incident` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { + $incidents[] = self::fromDatabaseRow($row); + } + + return $incidents; + } + + public static function open_for_site(StatusBoard_Site $site) { + $incidents = array(); + + $database = StatusBoard_Main::instance()->database(); + foreach ($database->selectList('SELECT * FROM `incident_open` WHERE `site`=:site ORDER BY `id` DESC', array( + array('name' => 'site', 'value' => $site->id(), 'type' => PDO::PARAM_INT), + )) as $row) { + $incidents[] = self::fromDatabaseRow($row); + } + + return $incidents; + } + + protected function create() { + $database = StatusBoard_Main::instance()->database(); + $database->insert( + 'INSERT INTO `service` + (`id`, `site`, `reference`, `description`, `start_time`, `estimated_end_time`, `actual_end_time`) + VALUES(NULL, :site, :reference, :description, :start_time, :estimated_end_time, :actual_end_time)', + array( + array('name' => 'site', 'value' => $this->site, 'type' => PDO::PARAM_INT), + array('name' => 'reference', 'value' => $this->reference, 'type' => PDO::PARAM_STR), + array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), + array('name' => 'start_time', 'value' => $this->start_time, 'type' => PDO::PARAM_INT), + array('name' => 'estimated_end_time', 'value' => $this->estimated_end_time, 'type' => PDO::PARAM_INT), + array('name' => 'actual_end_time', 'value' => $this->actual_end_time, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = $database->lastInsertId(); + } + + public function delete() { + $database = StatusBoard_Main::instance()->database(); + $database->update( + 'DELETE FROM `incident` WHERE `id`=:id LIMIT 1', + array( + array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = null; + } + + public function id() { + return $this->id; + } + + public function site() { + return $this->site; + } + + public function reference() { + return $this->reference; + } + + public function description() { + return $this->description; + } + + public function start_time() { + return $this->start_time; + } + + public function estimated_end_time() { + return $this->estimated_end_time; + } + + public function actual_end_time() { + return $this->actual_end_time; + } + +} + +?> diff --git a/source/lib/StatusBoard/IncidentStatus.class.php b/source/lib/StatusBoard/IncidentStatus.class.php new file mode 100644 index 0000000..2aac330 --- /dev/null +++ b/source/lib/StatusBoard/IncidentStatus.class.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/source/lib/StatusBoard/Service.class.php b/source/lib/StatusBoard/Service.class.php new file mode 100644 index 0000000..b120ae7 --- /dev/null +++ b/source/lib/StatusBoard/Service.class.php @@ -0,0 +1,99 @@ +id = $id; + $this->name = $name; + $this->description = $description; + } + + public static function fromDatabaseRow($row) { + return new self( + $row['id'], + $row['name'], + $row['description'] + ); + } + + /** + * Load a Service object given its ID + * + * @param int $id + * @return StatusBoard_Service + */ + public static function fromId($id) { + $database = StatusBoard_Main::instance()->database(); + + $service = self::fromDatabaseRow( + $database->selectOne('SELECT * FROM `service` WHERE id=:id', array( + array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) + ) + ) + ); + + return $service; + } + + public static function all() { + $services = array(); + + $database = StatusBoard_Main::instance()->database(); + foreach ($database->selectList('SELECT * FROM `service` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { + $services[] = self::fromDatabaseRow($row); + } + + return $services; + } + + protected function create() { + $database = StatusBoard_Main::instance()->database(); + $database->insert( + 'INSERT INTO `service` + (`id`, `name`, `description`) + VALUES(NULL, :name, :description)', + array( + array('name' => 'name', 'value' => $this->name, 'type' => PDO::PARAM_STR), + array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), + ) + ); + + $this->id = $database->lastInsertId(); + } + + public function delete() { + $database = StatusBoard_Main::instance()->database(); + $database->update( + 'DELETE FROM `service` WHERE `id`=:id LIMIT 1', + array( + array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = null; + } + + public function sites() { + return StatusBoard_Site::all_for_service($this); + } + + public function id() { + return $this->id; + } + + public function name() { + return $this->name; + } + + public function description() { + return $this->description; + } + + +} + +?> \ No newline at end of file diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php new file mode 100644 index 0000000..ae6e77e --- /dev/null +++ b/source/lib/StatusBoard/Site.class.php @@ -0,0 +1,120 @@ +id = $id; + $this->service = $service; + $this->name = $name; + $this->description = $description; + } + + public static function fromDatabaseRow($row) { + return new self( + $row['id'], + $row['service'], + $row['name'], + $row['description'] + ); + } + + /** + * Load a Site object given its ID + * + * @param int $id + * @return StatusBoard_Site + */ + public static function fromId($id) { + $database = StatusBoard_Main::instance()->database(); + + $site = self::fromDatabaseRow( + $database->selectOne('SELECT * FROM `site` WHERE id=:id', array( + array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) + ) + ) + ); + + return $site; + } + + public static function all() { + $sites = array(); + + $database = StatusBoard_Main::instance()->database(); + foreach ($database->selectList('SELECT * FROM `site` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { + $sites[] = self::fromDatabaseRow($row); + } + + return $sites; + } + + public function all_for_service(StatusBoard_Service $service) { + $sites = array(); + + $database = StatusBoard_Main::instance()->database(); + foreach ($database->selectList('SELECT * FROM `site` WHERE `service`=:service ORDER BY `id` DESC', array( + array('name' => 'service', 'value' => $service->id(), 'type' => PDO::PARAM_INT), + )) as $row) { + $sites[] = self::fromDatabaseRow($row); + } + + return $sites; + } + + protected function create() { + $database = StatusBoard_Main::instance()->database(); + $database->insert( + 'INSERT INTO `service` + (`id`, `service`, `name`, `description`) + VALUES(NULL, :service, :name, :description)', + array( + array('name' => 'service', 'value' => $this->service, 'type' => PDO::PARAM_INT), + array('name' => 'name', 'value' => $this->name, 'type' => PDO::PARAM_STR), + array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), + ) + ); + + $this->id = $database->lastInsertId(); + } + + public function delete() { + $database = StatusBoard_Main::instance()->database(); + $database->update( + 'DELETE FROM `site` WHERE `id`=:id LIMIT 1', + array( + array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = null; + } + + public function incidents_open() { + return StatusBoard_Incident::open_for_site($this); + } + + public function id() { + return $this->id; + } + + public function service() { + return $this->service; + } + + public function name() { + return $this->name; + } + + public function description() { + return $this->description; + } + + +} + +?> \ No newline at end of file diff --git a/source/lib/StatusBoard/Status.class.php b/source/lib/StatusBoard/Status.class.php new file mode 100644 index 0000000..7a2cc71 --- /dev/null +++ b/source/lib/StatusBoard/Status.class.php @@ -0,0 +1,29 @@ + 'The service is operating normally.', + self::STATUS_Maintenance => 'The service is undergoing scheduled maintenance.', + self::STATUS_Minor => 'The service is exeriencing minor issues affecting some customers.', + self::STATUS_Significant => 'The service is exeriencing significant issues affecting many customers.', + self::STATUS_Major => 'The service is exeriencing a major outage affecting all customers.', + ); + + public static function description($status) { + if ( ! StatusBoard_Main::isClassConstantValue(self, 'STATUS_', $status)) { + throw new StatusBoard_Exception_InvalidParameters($status); + } + + return self::$descriptions[$status]; + } + +} + +?> \ No newline at end of file From ac3cc7378404320608734782dcc368ec56d17ca1 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:00:21 +0000 Subject: [PATCH 003/142] Add bootstrap resources --- source/webui/templates/index.tpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 5c3acc6..1294b58 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -16,6 +16,10 @@ + + + + From ddee74548813be0a6cfb68e7d569fae1cd0e9e7e Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:02:32 +0000 Subject: [PATCH 004/142] Add database entity tables and helper views Add the database table for each entity, and views to return output in useful formats. --- build/schema/mysql.sql | 112 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/build/schema/mysql.sql b/build/schema/mysql.sql index 28c3ceb..8996345 100644 --- a/build/schema/mysql.sql +++ b/build/schema/mysql.sql @@ -18,10 +18,6 @@ SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- Table structure for table `settings` -- --- Creation: Sep 24, 2010 at 07:22 PM --- Last update: Dec 04, 2011 at 01:19 PM --- Last check: Aug 20, 2011 at 10:32 PM --- DROP TABLE IF EXISTS `settings`; CREATE TABLE IF NOT EXISTS `settings` ( @@ -53,8 +49,6 @@ INSERT INTO `settings` (`name`, `value`, `type`) VALUES -- -- Table structure for table `log` -- --- Creation: Aug 20, 2011 at 10:32 PM --- DROP TABLE IF EXISTS `log`; CREATE TABLE IF NOT EXISTS `log` ( @@ -71,3 +65,109 @@ CREATE TABLE IF NOT EXISTS `log` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; +-- +-- Table structure for table `service` +-- + +DROP TABLE IF EXISTS `service`; +CREATE TABLE IF NOT EXISTS `service` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(32) NOT NULL, + `description` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Table structure for table `service` +-- + +DROP TABLE IF EXISTS `site`; +CREATE TABLE IF NOT EXISTS `site` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `service` int(10) unsigned NOT NULL, + `name` varchar(32) NOT NULL, + `description` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + + +-- +-- Table structure for table `incident` +-- + +DROP TABLE IF EXISTS `incident`; +CREATE TABLE IF NOT EXISTS `incident` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `site` int(10) unsigned NOT NULL, + `reference` varchar(32) NOT NULL, + `description` text NOT NULL, + `start_time` int(10) NOT NULL, + `estimated_end_time` int(10) NULL, + `actual_end_time` int(10) NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Table structure for table `incidentstatus` +-- + +DROP TABLE IF EXISTS `incidentstatus`; +CREATE TABLE IF NOT EXISTS `incidentstatus` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `incident` int(10) unsigned NOT NULL, + `status` int(10) unsigned NOT NULL, + `ctime` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Table structure for view `incidentstatus_current_int` +-- + +DROP VIEW IF EXISTS `incidentstatus_current_int`; +CREATE VIEW `incidentstatus_current_int` AS ( + SELECT + `incidentstatus`.`incident` AS `incident`, + MAX(`incidentstatus`.`id`) AS `latest` + FROM + `incidentstatus` + GROUP BY + `incidentstatus`.`incident` +); + +-- +-- Table structure for view `incidentstatus_current` +-- + +DROP VIEW IF EXISTS `incidentstatus_current`; +CREATE VIEW `incidentstatus_current` AS ( + SELECT + `is`.`id` AS `id`, + `is`.`incident` AS `incident`, + `is`.`status` AS `status`, + `is`.`ctime` AS `ctime` + FROM ( + `incidentstatus` AS `is` + JOIN `incidentstatus_current_int` AS `isci` + ) + WHERE ( + (`isci`.`incident` = `is`.`incident`) + AND (`is`.`id` = `isci`.`latest`) + ) +); + +-- +-- Table structure for view `incidentstatus_open` +-- + +DROP VIEW IF EXISTS `incident_open`; +CREATE VIEW `incident_open` AS ( + SELECT + `i`.* + FROM + `incident` AS `i` + JOIN `incidentstatus_current` AS `isc` + ON `i`.`id` = `isc`.`incident` + WHERE + `isc`.`status` IN (1,2,3,4) +); From a783317fdf24d9ebd3614a15eb8bf29423ec7a05 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:03:13 +0000 Subject: [PATCH 005/142] Add example database contents Populates the database with useful test data, not meant for production. --- build/schema/mysql.demo.sql | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 build/schema/mysql.demo.sql diff --git a/build/schema/mysql.demo.sql b/build/schema/mysql.demo.sql new file mode 100644 index 0000000..7fead5f --- /dev/null +++ b/build/schema/mysql.demo.sql @@ -0,0 +1,28 @@ +-- phpMyAdmin SQL Dump +-- version 3.1.4 +-- http://www.phpmyadmin.net +-- +-- Host: localhost:3306 +-- Generation Time: Dec 16, 2011 at 01:27 AM +-- Server version: 5.1.53 +-- PHP Version: 5.3.6-pl1-gentoo + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; + +-- +-- Database: `status-board` +-- + +-- -------------------------------------------------------- + +-- +-- Dumping data for table `service` +-- + +INSERT INTO `service` (`id`, `name`, `description`) VALUES +(1, 'Internet', 'Shared Internet connection.'), +(2, 'Web', 'Hosted web servers'), +(3, 'Email', 'Hosted email services'), +(4, 'DNS', 'Hosted DNS services'), +(5, 'LDAP', 'Hosted directory services'); + From 95d1bcd28e53504b4822c24d14b3f5a7134b5e8e Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:04:05 +0000 Subject: [PATCH 006/142] Add basic service/site/incident listings to the homepage. Basic functionality to serve as a test case for core class development. --- public/styles/normal.css | 16 ++++++++++++++++ source/webui/pages/home.php | 7 +++++++ source/webui/templates/home.tpl | 21 ++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 source/webui/pages/home.php diff --git a/public/styles/normal.css b/public/styles/normal.css index 9f4e8eb..e28ef70 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -89,4 +89,20 @@ label { background: lightcyan; color: darkblue; margin: 1em; +} + +/** + * Page specific content + */ + +div.service { + border-top: 1px solid grey; +} + +div.site { + margin-left: 5em; +} + +div.incident { + margin-left: 2em; } \ No newline at end of file diff --git a/source/webui/pages/home.php b/source/webui/pages/home.php new file mode 100644 index 0000000..7d6468e --- /dev/null +++ b/source/webui/pages/home.php @@ -0,0 +1,7 @@ +smarty->assign('services', $services); + +?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 30404ce..93649b4 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -1 +1,20 @@ -TODO \ No newline at end of file +
+ {foreach from=$services item=service} +
+ {$service->name()} + {foreach from=$service->sites() item=site} + {assign var=incidents value=$site->incidents_open()} +
+ {$site->name()} ({$incidents|count}) + {foreach from=$incidents item=incident} +
+ {$incident->description()} +
+ {/foreach} +
+ {foreachelse} + + {/foreach} +
+ {/foreach} +
From 75fe16ed0fce19c31bfb1bfb46bf82a10ee33a6d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:19:05 +0000 Subject: [PATCH 007/142] Add template code for error pages --- source/webui/pages/errors/404.php | 9 +++++++++ source/webui/pages/errors/unhandled-exception.php | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 source/webui/pages/errors/404.php create mode 100644 source/webui/pages/errors/unhandled-exception.php diff --git a/source/webui/pages/errors/404.php b/source/webui/pages/errors/404.php new file mode 100644 index 0000000..956189c --- /dev/null +++ b/source/webui/pages/errors/404.php @@ -0,0 +1,9 @@ +request(); + +$this->smarty->assign('requested_page', htmlspecialchars($req->request_string())); + + +?> \ No newline at end of file diff --git a/source/webui/pages/errors/unhandled-exception.php b/source/webui/pages/errors/unhandled-exception.php new file mode 100644 index 0000000..95bbc07 --- /dev/null +++ b/source/webui/pages/errors/unhandled-exception.php @@ -0,0 +1,10 @@ +config(); + +$this->smarty->assign('display_exceptions', $config->get('debug.display_exceptions')); +$this->smarty->assign('exception', $exception); +$this->smarty->assign('exception_type', get_class($exception)); + +?> \ No newline at end of file From 367749757bcfee28ff4230067f756599af115aab Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:19:40 +0000 Subject: [PATCH 008/142] Add status names Add a method for retrieving a short name for each status. --- source/lib/StatusBoard/Status.class.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/Status.class.php b/source/lib/StatusBoard/Status.class.php index 7a2cc71..035fd22 100644 --- a/source/lib/StatusBoard/Status.class.php +++ b/source/lib/StatusBoard/Status.class.php @@ -8,6 +8,14 @@ class StatusBoard_Status { const STATUS_Significant = 3; const STATUS_Major = 4; + protected static $names = array( + self::STATUS_Resolved => 'Resolved', + self::STATUS_Maintenance => 'Planned Maintenance', + self::STATUS_Minor => 'Minor Incident', + self::STATUS_Significant => 'Significant Incident', + self::STATUS_Major => 'Major Incident', + ); + protected static $descriptions = array( self::STATUS_Resolved => 'The service is operating normally.', self::STATUS_Maintenance => 'The service is undergoing scheduled maintenance.', @@ -16,8 +24,16 @@ class StatusBoard_Status { self::STATUS_Major => 'The service is exeriencing a major outage affecting all customers.', ); + public static function name($status) { + if ( ! StatusBoard_Main::isClassConstantValue(get_called_class(), 'STATUS_', $status)) { + throw new StatusBoard_Exception_InvalidParameters($status); + } + + return self::$names[$status]; + } + public static function description($status) { - if ( ! StatusBoard_Main::isClassConstantValue(self, 'STATUS_', $status)) { + if ( ! StatusBoard_Main::isClassConstantValue(get_called_class(), 'STATUS_', $status)) { throw new StatusBoard_Exception_InvalidParameters($status); } From 64e7a9ce841b14fde3dc7ea73583a0ad60395247 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:20:43 +0000 Subject: [PATCH 009/142] Fix bug in StatusBoard_Site::all_for_service() definition Function should have been defined statically. --- source/lib/StatusBoard/Site.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php index ae6e77e..2d5f0c9 100644 --- a/source/lib/StatusBoard/Site.class.php +++ b/source/lib/StatusBoard/Site.class.php @@ -53,7 +53,7 @@ class StatusBoard_Site { return $sites; } - public function all_for_service(StatusBoard_Service $service) { + public static function all_for_service(StatusBoard_Service $service) { $sites = array(); $database = StatusBoard_Main::instance()->database(); From 62d6982d71b02eaa5e9792e8b92dbb8cfda9b556 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:21:16 +0000 Subject: [PATCH 010/142] Add method to retrieve current status of incident --- source/lib/StatusBoard/Incident.class.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index 4bf30bf..023a33f 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -75,6 +75,16 @@ class StatusBoard_Incident { return $incidents; } + public function status() { + $database = StatusBoard_Main::instance()->database(); + $row = $database->selectOne('SELECT `status` FROM `incidentstatus_current` WHERE `incident`=:incident', array( + array('name' => 'incident', 'value' => $this->id(), 'type' => PDO::PARAM_INT), + ) + ); + + return $row['status']; + } + protected function create() { $database = StatusBoard_Main::instance()->database(); $database->insert( From 63fd852beb1d545a70e2c72d9e2bb6444025372f Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:22:00 +0000 Subject: [PATCH 011/142] Display additional detail for each incident. Display the incident status next to the description. --- source/webui/templates/home.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 93649b4..f4f6b16 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -8,7 +8,7 @@ {$site->name()} ({$incidents|count}) {foreach from=$incidents item=incident}
- {$incident->description()} + {StatusBoard_Status::name($incident->status())}: {$incident->description()}
{/foreach} From 326997c418897e44f219994ac353655b749241b4 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 01:37:15 +0000 Subject: [PATCH 012/142] Update 3rdparty less framework Imports the latest copy into the code tree and fixes the script/sheet inclusion in the default template. --- public/less/bootstrap.less | 0 public/scripts/3rdparty/less-1.1.5.min.js | 16 ++++++++++++++++ source/webui/templates/index.tpl | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 public/less/bootstrap.less create mode 100644 public/scripts/3rdparty/less-1.1.5.min.js diff --git a/public/less/bootstrap.less b/public/less/bootstrap.less new file mode 100644 index 0000000..e69de29 diff --git a/public/scripts/3rdparty/less-1.1.5.min.js b/public/scripts/3rdparty/less-1.1.5.min.js new file mode 100644 index 0000000..92930af --- /dev/null +++ b/public/scripts/3rdparty/less-1.1.5.min.js @@ -0,0 +1,16 @@ +// +// LESS - Leaner CSS v1.1.5 +// http://lesscss.org +// +// Copyright (c) 2009-2011, Alexis Sellier +// Licensed under the Apache 2.0 License. +// +// +// LESS - Leaner CSS v1.1.5 +// http://lesscss.org +// +// Copyright (c) 2009-2011, Alexis Sellier +// Licensed under the Apache 2.0 License. +// +(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e=["
    ",'
  • {0}
  • ',"
  • {current}
  • ",'
  • {2}
  • ',"
"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="

"+(a.message||"There is an error in your .less file")+"

"+'

'+b+" ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+":

"+e.replace(/\[(-?\d)\]/g,function(b,c){return parseInt(a.line)+parseInt(c)||""}).replace(/\{(\d)\}/g,function(b,c){return a.extract[parseInt(c)]||""}).replace(/\{current\}/,a.extract[1].slice(0,a.column)+''+a.extract[1].slice(a.column)+"")),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #ee4444;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.ctx {","color: #dd4444;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d>>0,c=new Array(b),d=arguments[1];for(var e=0;e>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c=b)return-1;c<0&&(c+=b);for(;ck&&(j[f]=j[f].slice(c-k),k=c)}function s(a){var d,e,g,h,i,m,n,o;if(a instanceof Function)return a.call(l.parsers);if(typeof a=="string")d=b.charAt(c)===a?a:null,g=1,r();else{r();if(d=a.exec(j[f]))g=d[0].length;else return null}if(d){o=c+=g,m=c+j[f].length-g;while(c0)throw{type:"Syntax",message:"Missing closing `}`",filename:a.filename};return c.map(function(a){return a.join("")})}([[]]),h=new e.Ruleset([],s(this.parsers.primary)),h.root=!0,h.toCSS=function(c){var d,f,g;return function(g,h){function n(a){return a?(b.slice(0,a).match(/\n/g)||"").length:null}var i=[];g=g||{},typeof h=="object"&&!Array.isArray(h)&&(h=Object.keys(h).map(function(a){var b=h[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),i=[new e.Ruleset(null,h)]);try{var j=c.call(this,{frames:i}).toCSS([],{compress:g.compress||!1})}catch(k){f=b.split("\n"),d=n(k.index);for(var l=k.index,m=-1;l>=0&&b.charAt(l)!=="\n";l--)m++;throw{type:k.type,message:k.message,filename:a.filename,index:k.index,line:typeof d=="number"?d+1:null,callLine:k.call&&n(k.call)+1,callExtract:f[n(k.call)],stack:k.stack,column:m,extract:[f[d-1],f[d],f[d+1]]}}return g.compress?j.replace(/(\s)+/g,"$1"):j}}(h.eval);if(c=0&&b.charAt(v)!=="\n";v--)w++;u={name:"ParseError",message:"Syntax Error on line "+p,index:c,filename:a.filename,line:p,column:w,extract:[q[p-2],q[p-1],q[p]]}}this.imports.queue.length>0?n=function(){g(u,h)}:g(u,h)},parsers:{primary:function(){var a,b=[];while((a=s(this.mixin.definition)||s(this.rule)||s(this.ruleset)||s(this.mixin.call)||s(this.comment)||s(this.directive))||s(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(c)!=="/")return;if(b.charAt(c+1)==="/")return new e.Comment(s(/^\/\/.*/),!0);if(a=s(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)!=='"'&&b.charAt(d)!=="'")return;f&&s("~");if(a=s(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],f)},keyword:function(){var a;if(a=s(/^[_A-Za-z-][_A-Za-z0-9-]*/))return new e.Keyword(a)},call:function(){var a,b,d=c;if(!(a=/^([\w-]+|%)\(/.exec(j[f])))return;a=a[1].toLowerCase();if(a==="url")return null;c+=a.length;if(a==="alpha")return s(this.alpha);s("("),b=s(this.entities.arguments);if(!s(")"))return;if(a)return new e.Call(a,b,d)},arguments:function(){var a=[],b;while(b=s(this.expression)){a.push(b);if(!s(","))break}return a},literal:function(){return s(this.entities.dimension)||s(this.entities.color)||s(this.entities.quoted)},url:function(){var a;if(b.charAt(c)!=="u"||!s(/^url\(/))return;a=s(this.entities.quoted)||s(this.entities.variable)||s(this.entities.dataURI)||s(/^[-\w%@$\/.&=:;#+?~]+/)||"";if(!s(")"))throw new Error("missing closing ) for url()");return new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),o.paths)},dataURI:function(){var a;if(s(/^data:/)){a={},a.mime=s(/^[^\/]+\/[^,;)]+/)||"",a.charset=s(/^;\s*charset=[^,;)]+/)||"",a.base64=s(/^;\s*base64/)||"",a.data=s(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var a,d=c;if(b.charAt(c)==="@"&&(a=s(/^@@?[\w-]+/)))return new e.Variable(a,d)},color:function(){var a;if(b.charAt(c)==="#"&&(a=s(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,d=b.charCodeAt(c);if(d>57||d<45||d===47)return;if(a=s(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,d=c,f;b.charAt(d)==="~"&&(d++,f=!0);if(b.charAt(d)!=="`")return;f&&s("~");if(a=s(/^`([^`]*)`/))return new e.JavaScript(a[1],c,f)}},variable:function(){var a;if(b.charAt(c)==="@"&&(a=s(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!t(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=s(this.entity))&&s("/")&&(b=s(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var a=[],d,f,g,h=c,i=b.charAt(c);if(i!=="."&&i!=="#")return;while(d=s(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))a.push(new e.Element(f,d,c)),f=s(">");s("(")&&(g=s(this.entities.arguments))&&s(")");if(a.length>0&&(s(";")||t("}")))return new e.mixin.Call(a,g,h)},definition:function(){var a,d=[],f,g,h,i;if(b.charAt(c)!=="."&&b.charAt(c)!=="#"||t(/^[^{]*(;|})/))return;if(f=s(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=f[1];while(h=s(this.entities.variable)||s(this.entities.literal)||s(this.entities.keyword)){if(h instanceof e.Variable)if(s(":"))if(i=s(this.expression))d.push({name:h.name,value:i});else throw new Error("Expected value");else d.push({name:h.name});else d.push({value:h});if(!s(","))break}if(!s(")"))throw new Error("Expected )");g=s(this.block);if(g)return new e.mixin.Definition(a,d,g)}}},entity:function(){return s(this.entities.literal)||s(this.entities.variable)||s(this.entities.url)||s(this.entities.call)||s(this.entities.keyword)||s(this.entities.javascript)||s(this.comment)},end:function(){return s(";")||t("}")},alpha:function(){var a;if(!s(/^\(opacity=/i))return;if(a=s(/^\d+/)||s(this.entities.variable)){if(!s(")"))throw new Error("missing closing ) for alpha()");return new e.Alpha(a)}},element:function(){var a,b,d;d=s(this.combinator),a=s(/^(?:\d+\.\d+|\d+)%/)||s(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||s("*")||s(this.attribute)||s(/^\([^)@]+\)/);if(a)return new e.Element(d,a,c);if(d.value&&d.value.charAt(0)==="&")return new e.Element(d,null,c)},combinator:function(){var a,d=b.charAt(c);if(d===">"||d==="+"||d==="~"){c++;while(b.charAt(c)===" ")c++;return new e.Combinator(d)}if(d==="&"){a="&",c++,b.charAt(c)===" "&&(a="& ");while(b.charAt(c)===" ")c++;return new e.Combinator(a)}if(d===":"&&b.charAt(c+1)===":"){c+=2;while(b.charAt(c)===" ")c++;return new e.Combinator("::")}return b.charAt(c-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,d,f=[],g,h;while(d=s(this.element)){g=b.charAt(c),f.push(d);if(g==="{"||g==="}"||g===";"||g===",")break}if(f.length>0)return new e.Selector(f)},tag:function(){return s(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||s("*")},attribute:function(){var a="",b,c,d;if(!s("["))return;if(b=s(/^[a-zA-Z-]+/)||s(this.entities.quoted))(d=s(/^[|~*$^]?=/))&&(c=s(this.entities.quoted)||s(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!s("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(s("{")&&(a=s(this.primary))&&s("}"))return a},ruleset:function(){var a=[],b,d,f;p();while(b=s(this.selector)){a.push(b),s(this.comment);if(!s(","))break;s(this.comment)}if(a.length>0&&(d=s(this.block)))return new e.Ruleset(a,d);i=c,q()},rule:function(){var a,d,g=b.charAt(c),k,l;p();if(g==="."||g==="#"||g==="&")return;if(a=s(this.variable)||s(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(j[f]))?(c+=l[0].length-1,d=new e.Anonymous(l[1])):a==="font"?d=s(this.font):d=s(this.value),k=s(this.important);if(d&&s(this.end))return new e.Rule(a,d,k,h);i=c,q()}},"import":function(){var a;if(s(/^@import\s+/)&&(a=s(this.entities.quoted)||s(this.entities.url))&&s(";"))return new e.Import(a,o)},directive:function(){var a,d,f,g;if(b.charAt(c)!=="@")return;if(d=s(this["import"]))return d;if(a=s(/^@media|@page/)||s(/^@(?:-webkit-|-moz-)?keyframes/)){g=(s(/^[^{]+/)||"").trim();if(f=s(this.block))return new e.Directive(a+" "+g,f)}else if(a=s(/^@[-a-z]+/))if(a==="@font-face"){if(f=s(this.block))return new e.Directive(a,f)}else if((d=s(this.entity))&&s(";"))return new e.Directive(a,d)},font:function(){var a=[],b=[],c,d,f,g;while(g=s(this.shorthand)||s(this.entity))b.push(g);a.push(new e.Expression(b));if(s(","))while(g=s(this.expression)){a.push(g);if(!s(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=s(this.expression)){b.push(a);if(!s(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(c)==="!")return s(/^! *important/)},sub:function(){var a;if(s("(")&&(a=s(this.expression))&&s(")"))return a},multiplication:function(){var a,b,c,d;if(a=s(this.operand)){while((c=s("/")||s("*"))&&(b=s(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,d,f,g;if(a=s(this.multiplication)){while((f=s(/^[-+]\s+/)||b.charAt(c-1)!=" "&&(s("+")||s("-")))&&(d=s(this.multiplication)))g=new e.Operation(f,[g||a,d]);return g||a}},operand:function(){var a,d=b.charAt(c+1);b.charAt(c)==="-"&&(d==="@"||d==="(")&&(a=s("-"));var f=s(this.sub)||s(this.entities.dimension)||s(this.entities.color)||s(this.entities.variable)||s(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),f]):f},expression:function(){var a,b,c=[],d;while(a=s(this.addition)||s(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=s(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){a.charAt(0)!=="/"&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},c,!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)}}}(c("../tree")),function(a){a.Directive=function(b,c){this.name=b,Array.isArray(c)?this.ruleset=new a.Ruleset([],c):this.value=c},a.Directive.prototype={toCSS:function(a,b){return this.ruleset?(this.ruleset.root=!0,this.name+(b.compress?"{":" {\n ")+this.ruleset.toCSS(a,b).trim().replace(/\n/g,"\n ")+(b.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(a){return a.frames.unshift(this),this.ruleset=this.ruleset&&this.ruleset.eval(a),a.frames.shift(),this},variable:function(b){return a.Ruleset.prototype.variable.call(this.ruleset,b)},find:function(){return a.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(c("../tree")),function(a){a.Element=function(b,c,d){this.combinator=b instanceof a.Combinator?b:new a.Combinator(b),this.value=c?c.trim():"",this.index=d},a.Element.prototype.toCSS=function(a){return this.combinator.toCSS(a||{})+this.value},a.Combinator=function(a){a===" "?this.value=" ":a==="& "?this.value="& ":this.value=a?a.trim():""},a.Combinator.prototype.toCSS=function(a){return{"":""," ":" ","&":"","& ":" ",":":" :","::":"::","+":a.compress?"+":" + ","~":a.compress?"~":" ~ ",">":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c){var d=this;this._path=b,b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(a){if(!a)throw new Error("Error parsing "+d.path);d.root=a})},a.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(b){var c;if(this.css)return this;c=new a.Ruleset(null,this.root.rules.slice(0));for(var d=0;d0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;g0&&c>this.params.length)return!1;d=Math.min(c,this.arity);for(var e=0;ee.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":g.length>3?",\n":", "),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l0&&typeof a!="undefined"&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b){this.name=a,this.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("../tree")),c("./tree").find=function(a,b){for(var c=0,d;c1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c){a&&p(a.toCSS(),b,c.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k - - + + From d842fda253d818b6fdc37d62797935ef699d0593 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:36:29 +0000 Subject: [PATCH 013/142] Add load/create/delete methods to StatusBoard_IncidentStatus --- .../lib/StatusBoard/IncidentStatus.class.php | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/IncidentStatus.class.php b/source/lib/StatusBoard/IncidentStatus.class.php index 2aac330..4639f6f 100644 --- a/source/lib/StatusBoard/IncidentStatus.class.php +++ b/source/lib/StatusBoard/IncidentStatus.class.php @@ -5,7 +5,78 @@ class StatusBoard_IncidentStatus { protected $id; protected $incident; protected $status; - protected $time; + protected $ctime; + + protected function __construct($id, $incident, $status, $ctime) { + $this->id = $id; + $this->incident = $incident; + $this->status = $status; + $this->ctime = $ctime; + } + + /** + * Load an Incident object given its ID + * + * @param int $id + * @return StatusBoard_Incident + */ + public static function fromId($id) { + $database = StatusBoard_Main::instance()->database(); + + $incident_status = self::fromDatabaseRow( + $database->selectOne('SELECT * FROM `incidentstatus` WHERE id=:id', array( + array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) + ) + ) + ); + + return $incident_status; + } + + protected function create() { + $database = StatusBoard_Main::instance()->database(); + $database->insert( + 'INSERT INTO `incidentstatus` + (`id`, `incident`, `status`, `ctime`) + VALUES(NULL, :incident, :status, :ctime)', + array( + array('name' => 'incident', 'value' => $this->incident, 'type' => PDO::PARAM_INT), + array('name' => 'status', 'value' => $this->status, 'type' => PDO::PARAM_STR), + array('name' => 'ctime', 'value' => $this->ctime, 'type' => PDO::PARAM_STR), + ) + ); + + $this->id = $database->lastInsertId(); + } + + public function delete() { + $database = StatusBoard_Main::instance()->database(); + $database->update( + 'DELETE FROM `incidentstatus` WHERE `id`=:id LIMIT 1', + array( + array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = null; + } + + public function id() { + return $this->id; + } + + public function incident() { + return $this->incident; + } + + public function status() { + return $this->status; + } + + public function ctime() { + return $this->ctime; + } + } From 13924c0b56752a562ec3de1179cbd6d21038a8c5 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:37:23 +0000 Subject: [PATCH 014/142] Add status comparison function Simply checks the numerical value of status for now. If more statuses are added in future, this check may need to be made more complex. --- source/lib/StatusBoard/Status.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/lib/StatusBoard/Status.class.php b/source/lib/StatusBoard/Status.class.php index 035fd22..e778191 100644 --- a/source/lib/StatusBoard/Status.class.php +++ b/source/lib/StatusBoard/Status.class.php @@ -40,6 +40,10 @@ class StatusBoard_Status { return self::$descriptions[$status]; } + public static function isMoreSevere($base, $test) { + return ($test > $base); + } + } ?> \ No newline at end of file From 3f7f84d47c459af69003676d766c22e604bde7d0 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:40:31 +0000 Subject: [PATCH 015/142] Add caching to StatusBoard_Incident::currentStatus() Also renamed from status to currentStatus to better describe function. --- source/lib/StatusBoard/Incident.class.php | 42 +++++++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index 023a33f..ed800d8 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -9,6 +9,8 @@ class StatusBoard_Incident { protected $start_time; protected $estimated_end_time; protected $actual_end_time; + + protected $current_status; protected function __construct($id, $site, $reference, $description, $start_time, $estimated_end_time, $actual_end_time) { $this->id = $id; @@ -75,14 +77,40 @@ class StatusBoard_Incident { return $incidents; } - public function status() { - $database = StatusBoard_Main::instance()->database(); - $row = $database->selectOne('SELECT `status` FROM `incidentstatus_current` WHERE `incident`=:incident', array( - array('name' => 'incident', 'value' => $this->id(), 'type' => PDO::PARAM_INT), - ) - ); + public function currentStatus($ignore_cache = false) { + if ($this->current_status === null || $ignore_cache) { + $database = StatusBoard_Main::instance()->database(); + $row = $database->selectOne('SELECT `status` FROM `incidentstatus_current` WHERE `incident`=:incident', array( + array('name' => 'incident', 'value' => $this->id(), 'type' => PDO::PARAM_INT), + ) + ); - return $row['status']; + $this->current_status = $row['status']; + } + + return $this->current_status; + } + + /** + * Returns the status of the most severe incident in the given set + * + * @param array(StatusBoard_Incident) $incidents + */ + public static function highestSeverityStatus(array $incidents) { + if ( ! $incidents) { + return StatusBoard_Status::STATUS_Resolved; + } + + // Check for the highest severity incident. + $status = StatusBoard_Status::STATUS_Maintenance; + foreach ($incidents as $incident) { + $incident_status = $incident->currentStatus(); + if (StatusBoard_Status::isMoreSevere($status, $incident_status)) { + $status = $incident_status; + } + } + + return $status; } protected function create() { From 42ca2a1a5caf35bc620f87ece03a938e140b3bdf Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:41:23 +0000 Subject: [PATCH 016/142] Add caching to site incident retrieval. Add site status function. --- source/lib/StatusBoard/Site.class.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php index 2d5f0c9..666e1cf 100644 --- a/source/lib/StatusBoard/Site.class.php +++ b/source/lib/StatusBoard/Site.class.php @@ -7,6 +7,9 @@ class StatusBoard_Site { protected $name; protected $description; + protected $incidents; + protected $incidents_open; + protected function __construct($id, $service, $name, $description) { $this->id = $id; $this->service = $service; @@ -94,8 +97,16 @@ class StatusBoard_Site { $this->id = null; } - public function incidents_open() { - return StatusBoard_Incident::open_for_site($this); + public function openIncidents() { + if ($this->incidents_open === null || $ignore_cache) { + $this->incidents_open = StatusBoard_Incident::open_for_site($this); + } + + return $this->incidents_open; + } + + public function status() { + return StatusBoard_Incident::highestSeverityStatus($this->openIncidents()); } public function id() { From f2541774cfd048189546edadd1e543ce5f5f32d7 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:42:02 +0000 Subject: [PATCH 017/142] Add caching to service site list --- source/lib/StatusBoard/Service.class.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/lib/StatusBoard/Service.class.php b/source/lib/StatusBoard/Service.class.php index b120ae7..ef003b4 100644 --- a/source/lib/StatusBoard/Service.class.php +++ b/source/lib/StatusBoard/Service.class.php @@ -6,6 +6,8 @@ class StatusBoard_Service { protected $name; protected $description; + protected $sites; + protected function __construct($id, $name, $description) { $this->id = $id; $this->name = $name; @@ -77,8 +79,12 @@ class StatusBoard_Service { $this->id = null; } - public function sites() { - return StatusBoard_Site::all_for_service($this); + public function sites($ignore_cache = false) { + if ($this->sites === null || $ignore_cache) { + $this->sites = StatusBoard_Site::all_for_service($this); + } + + return $this->sites; } public function id() { From 6b53bf11bd6d7c74311deed24bf09666492e9003 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 17 Dec 2011 12:42:25 +0000 Subject: [PATCH 018/142] Update with changes made to core classes. --- source/webui/templates/home.tpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index f4f6b16..b883b16 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -3,12 +3,12 @@
{$service->name()} {foreach from=$service->sites() item=site} - {assign var=incidents value=$site->incidents_open()} + {assign var=incidents value=$site->openIncidents()}
- {$site->name()} ({$incidents|count}) + {$site->name()} ({StatusBoard_Status::name($site->status())}) {foreach from=$incidents item=incident}
- {StatusBoard_Status::name($incident->status())}: {$incident->description()} + {StatusBoard_Status::name($incident->currentStatus())}: {$incident->description()}
{/foreach}
From 8e55d57b55c0a29b4dacdaab8cad58d07457d4af Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 12:21:39 +0000 Subject: [PATCH 019/142] Update status board classes to use new DatabaseObject base Updated schema to include new views --- build/schema/mysql.demo.sql | 41 +++++ build/schema/mysql.sql | 148 ++++++++++++++++++ source/lib/StatusBoard/Incident.class.php | 146 ++--------------- .../lib/StatusBoard/IncidentStatus.class.php | 85 +--------- source/lib/StatusBoard/Service.class.php | 97 +----------- source/lib/StatusBoard/Site.class.php | 118 ++------------ 6 files changed, 229 insertions(+), 406 deletions(-) diff --git a/build/schema/mysql.demo.sql b/build/schema/mysql.demo.sql index 7fead5f..ddcd079 100644 --- a/build/schema/mysql.demo.sql +++ b/build/schema/mysql.demo.sql @@ -26,3 +26,44 @@ INSERT INTO `service` (`id`, `name`, `description`) VALUES (4, 'DNS', 'Hosted DNS services'), (5, 'LDAP', 'Hosted directory services'); +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`id`, `username`, `password`, `fullname`, `email`, `last_login`, `last_password_change`) VALUES +(2, 'guest', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 'Guest', NULL, NULL, 1324211553); + +-- +-- Dumping data for table `group` +-- + +INSERT INTO `group` (`id`, `name`, `description`) VALUES +(2, 'readonly', 'Basic group with read only access to the status boards.'); + +-- +-- Dumping data for table `usergroup` +-- + +INSERT INTO `usergroup` (`id`, `user`, `group`, `added`) VALUES +(1, 1, 1, 1324211572), +(2, 2, 2, 1324211572); + +-- +-- Dumping data for table `permission` +-- + +INSERT INTO `permission` (`id`, `name`, `description`) VALUES +(2, 'Update Status Boards', 'Permission to add/edit/delete any service or site.'); +(3, 'Update Incidents', 'Permission to create and update the status of any incident.'), +(4, 'View Status Boards', 'Permission to view the status of all services and sites, and details of any incident.'), + +-- +-- Dumping data for table `grouppermissions` +-- + +INSERT INTO `grouppermissions` (`id`, `group`, `permission`, `added`) VALUES +(2, 1, 2, 1324211935), +(3, 1, 3, 1324211935), +(4, 1, 4, 1324211935), +(5, 2, 4, 1324211935); + diff --git a/build/schema/mysql.sql b/build/schema/mysql.sql index 8996345..950d814 100644 --- a/build/schema/mysql.sql +++ b/build/schema/mysql.sql @@ -34,6 +34,7 @@ CREATE TABLE IF NOT EXISTS `settings` ( INSERT INTO `settings` (`name`, `value`, `type`) VALUES ('debug.display_exceptions', '1', 'bool'), ('cache.base_dir', '/dev/shm/status-board/', 'string'), +('auth', 'Database', 'string'), ('logging.plugins', 'Database\nFlatFile', 'array(string)'), ('logging.Database', 'webui', 'array(string)'), ('logging.Database.webui.table', 'log', 'string'), @@ -171,3 +172,150 @@ CREATE VIEW `incident_open` AS ( WHERE `isc`.`status` IN (1,2,3,4) ); + +-- +-- Table structure for table `user` +-- + +DROP TABLE IF EXISTS `user`; +CREATE TABLE IF NOT EXISTS `user` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `username` varchar(255) NOT NULL, + `password` char(40) NOT NULL, + `fullname` varchar(255) NULL, + `email` varchar(255) NULL, + `last_login` int(10) NULL, + `last_password_change` int(10) NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`id`, `username`, `password`, `fullname`, `email`, `last_login`, `last_password_change`) VALUES +(1, 'admin', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 'Administrator', NULL, NULL, 1324211456); + +-- +-- Table structure for table `group` +-- + +DROP TABLE IF EXISTS `group`; +CREATE TABLE IF NOT EXISTS `group` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Dumping data for table `group` +-- + +INSERT INTO `group` (`id`, `name`, `description`) VALUES +(1, 'admins', 'Administrative users will full control over the status boards.'); + +-- +-- Table structure for table `usergroup` +-- + +DROP TABLE IF EXISTS `usergroup`; +CREATE TABLE IF NOT EXISTS `usergroup` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user` int(10) unsigned NOT NULL, + `group` int(10) unsigned NOT NULL, + `added` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Dumping data for table `usergroup` +-- + +INSERT INTO `usergroup` (`id`, `user`, `group`, `added`) VALUES +(1, 1, 1, 1324211572); + +-- +-- Table structure for view `groups_by_user` +-- + +DROP VIEW IF EXISTS `groups_by_user`; +CREATE VIEW `groups_by_user` AS ( + SELECT + `u`.`id` AS `user`, + `g`.* + FROM + `usergroup` as `ug` + LEFT JOIN `user` AS `u` ON `ug`.`user`=`u`.`id` + LEFT JOIN `group` AS `g` ON `ug`.`group`=`g`.`id` +); + +-- +-- Table structure for table `permission` +-- + +DROP TABLE IF EXISTS `permission`; +CREATE TABLE IF NOT EXISTS `permission` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` text NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Dumping data for table `permission` +-- + +INSERT INTO `permission` (`id`, `name`, `description`) VALUES +(1, 'Administrator', 'Full administrative rights.'); + + +-- +-- Table structure for table `grouppermissions` +-- + +DROP TABLE IF EXISTS `grouppermission`; +CREATE TABLE IF NOT EXISTS `grouppermission` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `group` int(10) unsigned NOT NULL, + `permission` int(10) unsigned NOT NULL, + `added` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- +-- Dumping data for table `grouppermissions` +-- + +INSERT INTO `grouppermissions` (`id`, `group`, `permission`, `added`) VALUES +(1, 1, 1, 1324211935); + +-- +-- Table structure for view `permissions_by_group` +-- + +DROP VIEW IF EXISTS `permissions_by_group`; +CREATE VIEW `permissions_by_group` AS ( + SELECT + `g`.`id` AS `group`, + `p`.* + FROM + `grouppermission` as `gp` + LEFT JOIN `group` AS `g` ON `gp`.`group`=`g`.`id` + LEFT JOIN `permission` AS `p` on `gp`.`permission`=`p`.`id` +); + +-- +-- Table structure for view `permissions_by_user` +-- + +DROP VIEW IF EXISTS `permissions_by_user`; +CREATE VIEW `permissions_by_user` AS ( + SELECT + `u`.`id` AS `user`, + `p`.* + FROM + `usergroup` as `ug` + LEFT JOIN `user` AS `u` ON `ug`.`user`=`u`.`id` + LEFT JOIN `permissions_by_group` AS `p` on `ug`.`group`=`p`.`group` +); diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index ed800d8..5010116 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -1,87 +1,28 @@ id = $id; - $this->site = $site; - $this->reference = $reference; - $this->description = $description; - $this->start_time = $start_time; - $this->estimated_end_time = $estimated_end_time; - $this->actual_end_time = $actual_end_time; - } - - public static function fromDatabaseRow($row) { - return new self( - $row['id'], - $row['site'], - $row['reference'], - $row['description'], - $row['start_time'], - $row['estimated_end_time'], - $row['actual_end_time'] - ); - } - - /** - * Load an Incident object given its ID - * - * @param int $id - * @return StatusBoard_Incident - */ - public static function fromId($id) { - $database = StatusBoard_Main::instance()->database(); - - $incident = self::fromDatabaseRow( - $database->selectOne('SELECT * FROM `incident` WHERE id=:id', array( - array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) - ) - ) - ); - - return $incident; - } - - public static function all() { - $incidents = array(); - - $database = StatusBoard_Main::instance()->database(); - foreach ($database->selectList('SELECT * FROM `incident` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { - $incidents[] = self::fromDatabaseRow($row); - } - - return $incidents; - } - public static function open_for_site(StatusBoard_Site $site) { - $incidents = array(); - - $database = StatusBoard_Main::instance()->database(); - foreach ($database->selectList('SELECT * FROM `incident_open` WHERE `site`=:site ORDER BY `id` DESC', array( - array('name' => 'site', 'value' => $site->id(), 'type' => PDO::PARAM_INT), - )) as $row) { - $incidents[] = self::fromDatabaseRow($row); - } - - return $incidents; + return static::all_for('site', $site->id, 'incident_open'); } public function currentStatus($ignore_cache = false) { if ($this->current_status === null || $ignore_cache) { $database = StatusBoard_Main::instance()->database(); $row = $database->selectOne('SELECT `status` FROM `incidentstatus_current` WHERE `incident`=:incident', array( - array('name' => 'incident', 'value' => $this->id(), 'type' => PDO::PARAM_INT), + array('name' => 'incident', 'value' => $this->id, 'type' => PDO::PARAM_INT), ) ); @@ -113,65 +54,6 @@ class StatusBoard_Incident { return $status; } - protected function create() { - $database = StatusBoard_Main::instance()->database(); - $database->insert( - 'INSERT INTO `service` - (`id`, `site`, `reference`, `description`, `start_time`, `estimated_end_time`, `actual_end_time`) - VALUES(NULL, :site, :reference, :description, :start_time, :estimated_end_time, :actual_end_time)', - array( - array('name' => 'site', 'value' => $this->site, 'type' => PDO::PARAM_INT), - array('name' => 'reference', 'value' => $this->reference, 'type' => PDO::PARAM_STR), - array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), - array('name' => 'start_time', 'value' => $this->start_time, 'type' => PDO::PARAM_INT), - array('name' => 'estimated_end_time', 'value' => $this->estimated_end_time, 'type' => PDO::PARAM_INT), - array('name' => 'actual_end_time', 'value' => $this->actual_end_time, 'type' => PDO::PARAM_INT), - ) - ); - - $this->id = $database->lastInsertId(); - } - - public function delete() { - $database = StatusBoard_Main::instance()->database(); - $database->update( - 'DELETE FROM `incident` WHERE `id`=:id LIMIT 1', - array( - array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), - ) - ); - - $this->id = null; - } - - public function id() { - return $this->id; - } - - public function site() { - return $this->site; - } - - public function reference() { - return $this->reference; - } - - public function description() { - return $this->description; - } - - public function start_time() { - return $this->start_time; - } - - public function estimated_end_time() { - return $this->estimated_end_time; - } - - public function actual_end_time() { - return $this->actual_end_time; - } - } -?> +?> \ No newline at end of file diff --git a/source/lib/StatusBoard/IncidentStatus.class.php b/source/lib/StatusBoard/IncidentStatus.class.php index 4639f6f..ba32a91 100644 --- a/source/lib/StatusBoard/IncidentStatus.class.php +++ b/source/lib/StatusBoard/IncidentStatus.class.php @@ -1,83 +1,14 @@ id = $id; - $this->incident = $incident; - $this->status = $status; - $this->ctime = $ctime; - } - - /** - * Load an Incident object given its ID - * - * @param int $id - * @return StatusBoard_Incident - */ - public static function fromId($id) { - $database = StatusBoard_Main::instance()->database(); - - $incident_status = self::fromDatabaseRow( - $database->selectOne('SELECT * FROM `incidentstatus` WHERE id=:id', array( - array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) - ) - ) - ); - - return $incident_status; - } - - protected function create() { - $database = StatusBoard_Main::instance()->database(); - $database->insert( - 'INSERT INTO `incidentstatus` - (`id`, `incident`, `status`, `ctime`) - VALUES(NULL, :incident, :status, :ctime)', - array( - array('name' => 'incident', 'value' => $this->incident, 'type' => PDO::PARAM_INT), - array('name' => 'status', 'value' => $this->status, 'type' => PDO::PARAM_STR), - array('name' => 'ctime', 'value' => $this->ctime, 'type' => PDO::PARAM_STR), - ) - ); - - $this->id = $database->lastInsertId(); - } - - public function delete() { - $database = StatusBoard_Main::instance()->database(); - $database->update( - 'DELETE FROM `incidentstatus` WHERE `id`=:id LIMIT 1', - array( - array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), - ) - ); - - $this->id = null; - } - - public function id() { - return $this->id; - } - - public function incident() { - return $this->incident; - } - - public function status() { - return $this->status; - } - - public function ctime() { - return $this->ctime; - } - - + protected $_db_id; + protected $_db_incident; + protected $_db_status; + protected $_db_ctime; + } ?> \ No newline at end of file diff --git a/source/lib/StatusBoard/Service.class.php b/source/lib/StatusBoard/Service.class.php index ef003b4..64c1589 100644 --- a/source/lib/StatusBoard/Service.class.php +++ b/source/lib/StatusBoard/Service.class.php @@ -1,84 +1,15 @@ id = $id; - $this->name = $name; - $this->description = $description; - } - - public static function fromDatabaseRow($row) { - return new self( - $row['id'], - $row['name'], - $row['description'] - ); - } - - /** - * Load a Service object given its ID - * - * @param int $id - * @return StatusBoard_Service - */ - public static function fromId($id) { - $database = StatusBoard_Main::instance()->database(); - - $service = self::fromDatabaseRow( - $database->selectOne('SELECT * FROM `service` WHERE id=:id', array( - array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) - ) - ) - ); - - return $service; - } - - public static function all() { - $services = array(); - - $database = StatusBoard_Main::instance()->database(); - foreach ($database->selectList('SELECT * FROM `service` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { - $services[] = self::fromDatabaseRow($row); - } - - return $services; - } - - protected function create() { - $database = StatusBoard_Main::instance()->database(); - $database->insert( - 'INSERT INTO `service` - (`id`, `name`, `description`) - VALUES(NULL, :name, :description)', - array( - array('name' => 'name', 'value' => $this->name, 'type' => PDO::PARAM_STR), - array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), - ) - ); - - $this->id = $database->lastInsertId(); - } - - public function delete() { - $database = StatusBoard_Main::instance()->database(); - $database->update( - 'DELETE FROM `service` WHERE `id`=:id LIMIT 1', - array( - array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), - ) - ); - - $this->id = null; - } + protected $_db_id; + protected $_db_name; + protected $_db_description; + protected $sites = null; + public function sites($ignore_cache = false) { if ($this->sites === null || $ignore_cache) { $this->sites = StatusBoard_Site::all_for_service($this); @@ -86,19 +17,7 @@ class StatusBoard_Service { return $this->sites; } - - public function id() { - return $this->id; - } - - public function name() { - return $this->name; - } - - public function description() { - return $this->description; - } - + } diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php index 666e1cf..30ac219 100644 --- a/source/lib/StatusBoard/Site.class.php +++ b/source/lib/StatusBoard/Site.class.php @@ -1,101 +1,20 @@ id = $id; - $this->service = $service; - $this->name = $name; - $this->description = $description; - } - - public static function fromDatabaseRow($row) { - return new self( - $row['id'], - $row['service'], - $row['name'], - $row['description'] - ); - } - - /** - * Load a Site object given its ID - * - * @param int $id - * @return StatusBoard_Site - */ - public static function fromId($id) { - $database = StatusBoard_Main::instance()->database(); - - $site = self::fromDatabaseRow( - $database->selectOne('SELECT * FROM `site` WHERE id=:id', array( - array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) - ) - ) - ); - - return $site; - } - - public static function all() { - $sites = array(); - - $database = StatusBoard_Main::instance()->database(); - foreach ($database->selectList('SELECT * FROM `site` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { - $sites[] = self::fromDatabaseRow($row); - } - - return $sites; - } + protected $incidents = null; + protected $incidents_open = null; public static function all_for_service(StatusBoard_Service $service) { - $sites = array(); - - $database = StatusBoard_Main::instance()->database(); - foreach ($database->selectList('SELECT * FROM `site` WHERE `service`=:service ORDER BY `id` DESC', array( - array('name' => 'service', 'value' => $service->id(), 'type' => PDO::PARAM_INT), - )) as $row) { - $sites[] = self::fromDatabaseRow($row); - } - - return $sites; - } - - protected function create() { - $database = StatusBoard_Main::instance()->database(); - $database->insert( - 'INSERT INTO `service` - (`id`, `service`, `name`, `description`) - VALUES(NULL, :service, :name, :description)', - array( - array('name' => 'service', 'value' => $this->service, 'type' => PDO::PARAM_INT), - array('name' => 'name', 'value' => $this->name, 'type' => PDO::PARAM_STR), - array('name' => 'description', 'value' => $this->description, 'type' => PDO::PARAM_STR), - ) - ); - - $this->id = $database->lastInsertId(); - } - - public function delete() { - $database = StatusBoard_Main::instance()->database(); - $database->update( - 'DELETE FROM `site` WHERE `id`=:id LIMIT 1', - array( - array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), - ) - ); - - $this->id = null; - } + return static::all_for('service', $service->id); + } public function openIncidents() { if ($this->incidents_open === null || $ignore_cache) { @@ -108,23 +27,6 @@ class StatusBoard_Site { public function status() { return StatusBoard_Incident::highestSeverityStatus($this->openIncidents()); } - - public function id() { - return $this->id; - } - - public function service() { - return $this->service; - } - - public function name() { - return $this->name; - } - - public function description() { - return $this->description; - } - } From e110d99ddf507d74f1604a088de655809760d4dc Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 12:55:53 +0000 Subject: [PATCH 020/142] Imported changes to status board display --- source/webui/pages/home.php | 7 ++++ source/webui/pages/navigation.php | 18 ++++++++ source/webui/templates/home.tpl | 59 +++++++++++++++++++-------- source/webui/templates/index.tpl | 4 +- source/webui/templates/navigation.tpl | 23 +++++++++-- 5 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 source/webui/pages/navigation.php diff --git a/source/webui/pages/home.php b/source/webui/pages/home.php index 7d6468e..2f3accf 100644 --- a/source/webui/pages/home.php +++ b/source/webui/pages/home.php @@ -2,6 +2,13 @@ $services = StatusBoard_Service::all(); +for ($i = 1; $i <= 6; ++$i){ + $day = 'day'.$i; + $date = date("M. d", strtotime("-{$i}day")); + + $this->smarty->assign($day, $date); +} + $this->smarty->assign('services', $services); ?> \ No newline at end of file diff --git a/source/webui/pages/navigation.php b/source/webui/pages/navigation.php new file mode 100644 index 0000000..5d61883 --- /dev/null +++ b/source/webui/pages/navigation.php @@ -0,0 +1,18 @@ +auth(); +if ($auth->isAuthenticated()) { + $display_login = false; +} + +if ($auth->isAdministrator()) { + $display_admin = true; +} + +$this->smarty->assign('display_login', $display_login); +$this->smarty->assign('display_admin', $display_admin); + +?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index b883b16..38f94b4 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -1,20 +1,45 @@
- {foreach from=$services item=service} -
- {$service->name()} - {foreach from=$service->sites() item=site} - {assign var=incidents value=$site->openIncidents()} -
- {$site->name()} ({StatusBoard_Status::name($site->status())}) - {foreach from=$incidents item=incident} -
- {StatusBoard_Status::name($incident->currentStatus())}: {$incident->description()} -
- {/foreach} -
- {foreachelse} - + + + + + + + + + + + + + + + {foreach from=$services item=service} + + + + {foreach from=$service->sites() item=site} + {assign var=incidents value=$site->openIncidents()} + + + + + + + + + + + {foreachelse} + + + {/foreach} {/foreach} - - {/foreach} + +
ServiceCurrent{$day1}{$day2}{$day3}{$day4}{$day5}{$day6}
+ {$service->name} +
+ {$site->name} + + {StatusBoard_Status::name($site->status())} + goodgoodgoodgoodgoodgood
diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 803279f..a168634 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -30,13 +30,13 @@
diff --git a/source/webui/templates/navigation.tpl b/source/webui/templates/navigation.tpl index 96cbfc9..031bb6b 100644 --- a/source/webui/templates/navigation.tpl +++ b/source/webui/templates/navigation.tpl @@ -1,4 +1,19 @@ - \ No newline at end of file +StatusBoard + + + +

+ Logged in as username +

\ No newline at end of file From bdb7c0467507208eceb79a650951ffec8a809f1d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 12:57:38 +0000 Subject: [PATCH 021/142] Added logout page --- source/webui/pages/logout.php | 8 ++++++++ source/webui/templates/logout.tpl | 1 + 2 files changed, 9 insertions(+) create mode 100644 source/webui/pages/logout.php create mode 100644 source/webui/templates/logout.tpl diff --git a/source/webui/pages/logout.php b/source/webui/pages/logout.php new file mode 100644 index 0000000..0e8fa0d --- /dev/null +++ b/source/webui/pages/logout.php @@ -0,0 +1,8 @@ +auth(); +$auth->deauthenticate(); + +StatusBoard_Page::redirect('home'); + +?> \ No newline at end of file diff --git a/source/webui/templates/logout.tpl b/source/webui/templates/logout.tpl new file mode 100644 index 0000000..30404ce --- /dev/null +++ b/source/webui/templates/logout.tpl @@ -0,0 +1 @@ +TODO \ No newline at end of file From 116140ee1775dd2e888179f31d6852aae3148191 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 13:47:21 +0000 Subject: [PATCH 022/142] Fixed gui on main page Signed-off-by: Nathan Booth --- source/webui/templates/index.tpl | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index a168634..df300f8 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -19,27 +19,27 @@ + -
+
+
+
+ {$page->include_template('navigation')} +
+
+
+ - - - - -
- - - -
+
+ +
{if $messages}
From 1f2d8fec99903bbbacd1cecac10d0ce616cad3e2 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 14:10:00 +0000 Subject: [PATCH 023/142] Updated generation of previous days in heading on home template, now looped into array then passed to smarty Signed-off-by: Nathan Booth --- source/webui/pages/home.php | 7 ++----- source/webui/templates/home.tpl | 10 ++++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/source/webui/pages/home.php b/source/webui/pages/home.php index 2f3accf..2e190c6 100644 --- a/source/webui/pages/home.php +++ b/source/webui/pages/home.php @@ -3,12 +3,9 @@ $services = StatusBoard_Service::all(); for ($i = 1; $i <= 6; ++$i){ - $day = 'day'.$i; - $date = date("M. d", strtotime("-{$i}day")); - - $this->smarty->assign($day, $date); + $tbl_header_date[] = date("M. d", strtotime("-{$i}day")); } - +$this->smarty->assign('days', $tbl_header_date); $this->smarty->assign('services', $services); ?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 38f94b4..49dee50 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -4,12 +4,10 @@ Service Current - {$day1} - {$day2} - {$day3} - {$day4} - {$day5} - {$day6} + {foreach from=$days key="ind" item="day"} + {$day} + {/foreach} + From ac8199f4dc9c4aaf2c8134477736c21976bcfe4c Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 14:18:01 +0000 Subject: [PATCH 024/142] Added images for service status Signed-off-by: Nathan Booth --- public/images/Status_Icons/cross-circle.png | Bin 0 -> 729 bytes public/images/Status_Icons/exclamation.png | Bin 0 -> 654 bytes public/images/Status_Icons/tick-circle.png | Bin 0 -> 724 bytes public/images/Status_Icons/traffic-cone.png | Bin 0 -> 688 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 public/images/Status_Icons/cross-circle.png create mode 100755 public/images/Status_Icons/exclamation.png create mode 100755 public/images/Status_Icons/tick-circle.png create mode 100755 public/images/Status_Icons/traffic-cone.png diff --git a/public/images/Status_Icons/cross-circle.png b/public/images/Status_Icons/cross-circle.png new file mode 100755 index 0000000000000000000000000000000000000000..20d6f5ea032148de928c22c640158b61cbff6fca GIT binary patch literal 729 zcmV;~0w(>5P)|LfiOHS}TjIms%#6R5$ctGV!9nIUnSg*o zp)I8?o>K~e#W!#AZEt(e=X=k+_gvdxFo6GQ96esxY{251WCIAIcCovG3R!XAQ6F%s z9O_EP57IN7oV#ZD*e(d^@bYprxU}RIW@jCgq1&isZ^YqnMo5fHo*1lh7yVBZ&4KP=5pqg_YMz16h%|irxrUn01-_VB9W** z+^69ZG=N8Lzu#MLHsNJ73QtQVP!t71`}-hC5|r?pVHkLwOoH8R2jASBml#B!GnT=k z!7vUD*X?$>AnWr%p-_NowQ3sK@RZ&l%+o3L`=CgYgP6$-K*IqQ)0Hp_mtg?QvgT|& z&zrh2vD+-hYF6LOpbzjvtksl3y$*t|L+to?3g$QtQpF-T={N{bRfU+b0lK}fRVocP z1};v(pV!vl)5?lzK-wsmO@p>9H;I`v$bD-x%D7YV<<^!7pCNn;$4Do!n3?XoNCXVS zkSo1jiI}m0f#uoN^~}e5z2F6qzpk&tZTv4-qW%fO9)$CqPC+t^3^Byos8nf}DJY56 zc!y!qah{LHc;4$_SqBCE(RHP$s?CC`mM##^V-;Rf0TOE&&}q!0d{|zA1id}Pu@ z(oAB&G-+BVp@?&h7-R51O%wzHZd~N74Eds*N4@`RobQ9q2Ty+W z!u>k}oGy<{em#}Hyb8eJ)4Rv_`1s+dAacq82!j3aT^*-VY$2IFHUo0}CDuxC8J z9o~Z11wi<6F2pC!lnHUQX1fk%YYS?%8Z;UW@FfSB>;lNHrbIJkjP2_PK15Ce1bI1; zDNQwZUxF7jL82~vHE)N=v=c%F3!QZhZ3li(YS@tOMc+n^0eWwaa-#U<2=w$0XZ#Y91- zyOc3J(ci^o@7xUg*3Q%Y@0SAAv*U%=ugo>kZiD;c`F5R~>%%Yo?jI|W*P$!mP2ei= o8aXoB|5CxYL=P9paefLg0E1^Tq`^>r;Q#;t07*qoM6N<$f_6(T2LJ#7 literal 0 HcmV?d00001 diff --git a/public/images/Status_Icons/tick-circle.png b/public/images/Status_Icons/tick-circle.png new file mode 100755 index 0000000000000000000000000000000000000000..210b1a6c3ccefb387a9f902b012f61aa83eb775e GIT binary patch literal 724 zcmV;_0xSKAP)OzWUn z0;LtWZ01tXg<8j;Z_I_HKrTI+R#Ne#91TW8JU`7;ul=m;PH$CyJhs|ao-Hj8WYC4r z1T7}-!!nc)MnE)Beai(YB()laHos380a;w!sv)P1YS!k&(92_2?TrT5v`X%=E_V8$E7MsOQc!no)rgsMpO$rb~ znx$SzTE!+Dt2H= zl6+;~PXSRD8)o5><1;;jHvL`Gj?8DJ7yk74_!t{^`ruUtU*NUq$R?J_nf?quR*&`@ zqAX(S``lm9hd(j+Vh`pr|L6_Q^cyTSck9~%h(SgPu5Ui*zy$`64#J-28dg=`=1kAP zqZLDKHmWT90Rma-8uIs5= znihsAI#{OzYTe<8M8d^#IrUjl3ZvSWJi-1%0zUS7Z_jv=$w2>E$B)Z#6u*2ma?hVh zlfr(2?P_&w@J%onTU%aUVvM0f9n|Y}B;$!CFc#ac)&4cSIKB&)xm?Tqs_z?icX4r;jH31Z;J_`0!{~cZ ztK#?iI(?8~T9W(z!+R~uvP9Ba7;L3D(v6l*Bw{Y7)5j-s+U<7V#CrV~z(n7*D_3J& zH@;=Z$M*5PJ$rVxS=rr%F+UGE8b!NQf>&&2SypAKD4{VhmuF)|2vhJU&o0euNnrXL0D+h6?z& zj_WOZ=k5U64Dc8OLlnYKcnEpWolZ1}*2quv5qSH7u~))ij*oEQ|AXggkkR@d0R{jD Wo&7aKPiAWX0000 Date: Mon, 19 Dec 2011 14:51:15 +0000 Subject: [PATCH 025/142] Updated logic for table output Signed-off-by: Nathan Booth --- source/webui/templates/home.tpl | 16 ++++------------ source/webui/templates/index.tpl | 3 +++ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 49dee50..cf6f43e 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -3,6 +3,7 @@ Service + Sites Current {foreach from=$days key="ind" item="day"} {$day} @@ -13,28 +14,19 @@ {foreach from=$services item=service} - + {$service->name} - {foreach from=$service->sites() item=site} {assign var=incidents value=$site->openIncidents()} - {$site->name} {StatusBoard_Status::name($site->status())} - - good - good - good - good - good - good - + {foreachelse} - + {/foreach} {/foreach} diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index df300f8..6726618 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -23,6 +23,9 @@ body { padding-top: 60px; } + table th, table td { + text-align: center; + } From f3f98eb000139071ccc5281abee81f2f284ded57 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 15:05:33 +0000 Subject: [PATCH 026/142] Add bootstrap JS, and move things from template into external resource files --- public/scripts/3rdparty/bootstrap-alerts.js | 113 ++++++++++++++++++++ public/scripts/main.js | 12 ++- public/styles/normal.css | 2 + source/webui/templates/index.tpl | 8 +- 4 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 public/scripts/3rdparty/bootstrap-alerts.js diff --git a/public/scripts/3rdparty/bootstrap-alerts.js b/public/scripts/3rdparty/bootstrap-alerts.js new file mode 100644 index 0000000..37bb430 --- /dev/null +++ b/public/scripts/3rdparty/bootstrap-alerts.js @@ -0,0 +1,113 @@ +/* ========================================================== + * bootstrap-alerts.js v1.4.0 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2011 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function( $ ){ + + "use strict" + + /* CSS TRANSITION SUPPORT (https://gist.github.com/373874) + * ======================================================= */ + + var transitionEnd + + $(document).ready(function () { + + $.support.transition = (function () { + var thisBody = document.body || document.documentElement + , thisStyle = thisBody.style + , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined + return support + })() + + // set CSS transition event type + if ( $.support.transition ) { + transitionEnd = "TransitionEnd" + if ( $.browser.webkit ) { + transitionEnd = "webkitTransitionEnd" + } else if ( $.browser.mozilla ) { + transitionEnd = "transitionend" + } else if ( $.browser.opera ) { + transitionEnd = "oTransitionEnd" + } + } + + }) + + /* ALERT CLASS DEFINITION + * ====================== */ + + var Alert = function ( content, options ) { + this.settings = $.extend({}, $.fn.alert.defaults, options) + this.$element = $(content) + .delegate(this.settings.selector, 'click', this.close) + } + + Alert.prototype = { + + close: function (e) { + var $element = $(this).parent('.alert-message') + + e && e.preventDefault() + $element.removeClass('in') + + function removeElement () { + $element.remove() + } + + $.support.transition && $element.hasClass('fade') ? + $element.bind(transitionEnd, removeElement) : + removeElement() + } + + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + $.fn.alert = function ( options ) { + + if ( options === true ) { + return this.data('alert') + } + + return this.each(function () { + var $this = $(this) + + if ( typeof options == 'string' ) { + return $this.data('alert')[options]() + } + + $(this).data('alert', new Alert( this, options )) + + }) + } + + $.fn.alert.defaults = { + selector: '.close' + } + + $(document).ready(function () { + new Alert($('body'), { + selector: '.alert-message[data-alert] .close' + }) + }) + +}( window.jQuery || window.ender ); \ No newline at end of file diff --git a/public/scripts/main.js b/public/scripts/main.js index e089232..ee9b978 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -2,4 +2,14 @@ * StatusBoard main script file * * - */ \ No newline at end of file + */ + +var sb = { + + init: function() { + $('.alert-data').alert(); + } + +}; + +$('document').ready(sb.init); diff --git a/public/styles/normal.css b/public/styles/normal.css index e28ef70..7793a73 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -7,6 +7,8 @@ body { margin: 0em; + margin-top: 60px; + padding: 0em; font-family: verdana, helvetica, sans-serif; } diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index df300f8..cde16ed 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -19,12 +19,8 @@ - - + + From a850ed911d476c0490f2498eb1f985740c8cf2b8 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 15:05:47 +0000 Subject: [PATCH 027/142] Add login page. --- source/webui/pages/login.php | 30 ++++++++++++++++++++++++++++++ source/webui/templates/login.tpl | 17 +++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 source/webui/pages/login.php create mode 100644 source/webui/templates/login.tpl diff --git a/source/webui/pages/login.php b/source/webui/pages/login.php new file mode 100644 index 0000000..1452db1 --- /dev/null +++ b/source/webui/pages/login.php @@ -0,0 +1,30 @@ +request(); +$auth = $main->auth(); + +$authenticated = false; +$authentication_failed = false; + +if ($request->exists('do')) { + $username = StatusBoard_Main::issetelse($_POST['username'], Sihnon_Exception_InvalidParameters); + $password = StatusBoard_Main::issetelse($_POST['username'], Sihnon_Exception_InvalidParameters); + + try { + $auth->authenticate($username, $password); + $authenticated = true; + + StatusBoard_Page::redirect('home'); + + } catch (Sihnon_Exception_UnknownUser $e) { + $authentication_failed = true; + } catch (Sihnon_Exception_IncorrectPassword $e) { + $authentication_failed = true; + } +} + +$this->smarty->assign('authentication', $authenticated); +$this->smarty->assign('authentication_failed', $authentication_failed); + +?> \ No newline at end of file diff --git a/source/webui/templates/login.tpl b/source/webui/templates/login.tpl new file mode 100644 index 0000000..8cf530a --- /dev/null +++ b/source/webui/templates/login.tpl @@ -0,0 +1,17 @@ +{if $authentication_failed} + +
+ Incorrect username/password combination entered. +
+ +{/if} + +
+ + + + + + + +
\ No newline at end of file From 01aedf02aa86f91f39faf79851081ac821ef756a Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 15:21:21 +0000 Subject: [PATCH 028/142] Fixed display error with nav bar Signed-off-by: Nathan Booth --- public/styles/normal.css | 4 ++-- source/webui/templates/index.tpl | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/public/styles/normal.css b/public/styles/normal.css index 91d6cd7..2f34a22 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -2,13 +2,13 @@ * StatusBoard normal stylesheet * */ - +@import url('http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css'); @CHARSET "UTF-8"; body { margin: 0em; margin-top: 60px; - + padding-top: 40px; padding: 0em; font-family: verdana, helvetica, sans-serif; } diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index c521952..45516a1 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -16,13 +16,11 @@ - - - I can +
From 4c80bd0d8e45e947b4a05fb9ab2d86245aa5e0b5 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 15:43:07 +0000 Subject: [PATCH 029/142] update to login page Signed-off-by: Nathan Booth --- source/webui/templates/login.tpl | 37 ++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/source/webui/templates/login.tpl b/source/webui/templates/login.tpl index 8cf530a..bba3e64 100644 --- a/source/webui/templates/login.tpl +++ b/source/webui/templates/login.tpl @@ -5,13 +5,32 @@
{/if} - -
- - +
Password - - - - \ No newline at end of file +
+
+
+ Administrator Login +
+ +
+ +
+
+
+ +
+ +
+
+
+
+   +
+
+
+
+
+
+
\ No newline at end of file From b7c7eb75851109423cccdc96baa9c3e83b953e36 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 15:49:17 +0000 Subject: [PATCH 030/142] Fixed login page --- source/webui/pages/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/pages/login.php b/source/webui/pages/login.php index 1452db1..719acaf 100644 --- a/source/webui/pages/login.php +++ b/source/webui/pages/login.php @@ -9,7 +9,7 @@ $authentication_failed = false; if ($request->exists('do')) { $username = StatusBoard_Main::issetelse($_POST['username'], Sihnon_Exception_InvalidParameters); - $password = StatusBoard_Main::issetelse($_POST['username'], Sihnon_Exception_InvalidParameters); + $password = StatusBoard_Main::issetelse($_POST['password'], Sihnon_Exception_InvalidParameters); try { $auth->authenticate($username, $password); From 96b16df845b333f4b53802bc9e4eb0340ecf4ac9 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 15:49:34 +0000 Subject: [PATCH 031/142] Fixed status board table layout and row banding --- public/styles/normal.css | 9 +++++++ source/webui/templates/home.tpl | 42 ++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/public/styles/normal.css b/public/styles/normal.css index 2f34a22..a8579cf 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -112,3 +112,12 @@ div.incident { table th, table td { text-align: center; } + +th.service { + text-align: left; + background-color: #dddddd; +} + +.odd_row { + background-color: #eeeeee; +} \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index cf6f43e..8cdf1ce 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -1,35 +1,55 @@
- +
- {foreach from=$days key="ind" item="day"} - + {/foreach} - {foreach from=$services item=service} - - + + {foreach from=$service->sites() item=site} - {assign var=incidents value=$site->openIncidents()} + {assign var=incidents value=$site->openIncidents()} + - {foreachelse} - - - {/foreach} + + + + + + + + {/foreach} {/foreach}
ServiceSites Current{$day}{$day}
+
{$service->name}
{$site->name} {StatusBoard_Status::name($site->status())}
+ TODO + + TODO + + TODO + + TODO + + TODO + + TODO +
+ + From fed73e2268c5c6351ecb7857f8401f602596c48d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 17:21:08 +0000 Subject: [PATCH 032/142] Remove undefined variable warning in Site. --- source/lib/StatusBoard/Site.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php index 30ac219..7688ccc 100644 --- a/source/lib/StatusBoard/Site.class.php +++ b/source/lib/StatusBoard/Site.class.php @@ -16,7 +16,7 @@ class StatusBoard_Site extends StatusBoard_DatabaseObject { return static::all_for('service', $service->id); } - public function openIncidents() { + public function openIncidents($ignore_cache = false) { if ($this->incidents_open === null || $ignore_cache) { $this->incidents_open = StatusBoard_Incident::open_for_site($this); } From 6ab5f683e9e609861f94a2beaa142eba82e58253 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 17:21:54 +0000 Subject: [PATCH 033/142] Fix misc login and display issues --- source/webui/pages/login.php | 5 +++-- source/webui/pages/navigation.php | 16 +++++++--------- source/webui/templates/navigation.tpl | 21 +++++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/webui/pages/login.php b/source/webui/pages/login.php index 719acaf..f8a4da8 100644 --- a/source/webui/pages/login.php +++ b/source/webui/pages/login.php @@ -3,13 +3,14 @@ $main = StatusBoard_Main::instance(); $request = $main->request(); $auth = $main->auth(); +$log = $main->log(); $authenticated = false; $authentication_failed = false; if ($request->exists('do')) { - $username = StatusBoard_Main::issetelse($_POST['username'], Sihnon_Exception_InvalidParameters); - $password = StatusBoard_Main::issetelse($_POST['password'], Sihnon_Exception_InvalidParameters); + $username = StatusBoard_Main::issetelse($_POST['username'], 'Sihnon_Exception_InvalidParameters'); + $password = StatusBoard_Main::issetelse($_POST['password'], 'Sihnon_Exception_InvalidParameters'); try { $auth->authenticate($username, $password); diff --git a/source/webui/pages/navigation.php b/source/webui/pages/navigation.php index 5d61883..7a7cbf6 100644 --- a/source/webui/pages/navigation.php +++ b/source/webui/pages/navigation.php @@ -1,18 +1,16 @@ auth(); if ($auth->isAuthenticated()) { - $display_login = false; + $authenticated = true; + $user = $auth->authenticatedUser(); } -if ($auth->isAdministrator()) { - $display_admin = true; -} - -$this->smarty->assign('display_login', $display_login); -$this->smarty->assign('display_admin', $display_admin); +$this->smarty->assign('authenticated', $authenticated); +$this->smarty->assign('auth', $auth); +$this->smarty->assign('user', $user); ?> \ No newline at end of file diff --git a/source/webui/templates/navigation.tpl b/source/webui/templates/navigation.tpl index 031bb6b..51df6ee 100644 --- a/source/webui/templates/navigation.tpl +++ b/source/webui/templates/navigation.tpl @@ -3,17 +3,18 @@ -

- Logged in as username -

\ No newline at end of file +{if $authenticated} +

+ Logged in as {$user->username} +

+{/if} \ No newline at end of file From a75814da920e72f0f6310a81ff722512d0b48473 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 17:47:21 +0000 Subject: [PATCH 034/142] Fix display on login error messages. --- source/webui/templates/login.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/templates/login.tpl b/source/webui/templates/login.tpl index bba3e64..ce6fe03 100644 --- a/source/webui/templates/login.tpl +++ b/source/webui/templates/login.tpl @@ -1,6 +1,6 @@ {if $authentication_failed} -
+
Incorrect username/password combination entered.
From edb0a56decf79201440d637fa63acae6a4b6aef2 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 17:54:12 +0000 Subject: [PATCH 035/142] Fix indentation on the login form --- source/webui/templates/login.tpl | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/source/webui/templates/login.tpl b/source/webui/templates/login.tpl index ce6fe03..cdde48b 100644 --- a/source/webui/templates/login.tpl +++ b/source/webui/templates/login.tpl @@ -5,32 +5,32 @@
{/if} -
-
-
- Administrator Login -
- -
- -
-
-
- -
- -
-
-
-
-   -
-
-
-
-
-
+ +
+
+
+
+
+ Administrator Login +
+ +
+ +
+
+
+ +
+ +
+
+
+
+   +
+
+
+
+
+
\ No newline at end of file From 9fd382dddce27c0125556620c7b750786b6e5ed3 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 17:57:41 +0000 Subject: [PATCH 036/142] Fix labels for form elements --- source/webui/templates/login.tpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/webui/templates/login.tpl b/source/webui/templates/login.tpl index cdde48b..8bcfbd6 100644 --- a/source/webui/templates/login.tpl +++ b/source/webui/templates/login.tpl @@ -15,11 +15,11 @@
- +
- +
From bd676e558e6050944044ba14d6f5a46aab8de423 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 18:11:04 +0000 Subject: [PATCH 037/142] Popovers on main page showing status Signed-off-by: Nathan Booth --- public/scripts/3rdparty/bootstrap-popover.js | 90 ++++++ public/scripts/3rdparty/bootstrap-twipsy.js | 321 +++++++++++++++++++ public/scripts/main.js | 10 + source/webui/templates/home.tpl | 4 +- source/webui/templates/index.tpl | 22 +- 5 files changed, 434 insertions(+), 13 deletions(-) create mode 100644 public/scripts/3rdparty/bootstrap-popover.js create mode 100644 public/scripts/3rdparty/bootstrap-twipsy.js diff --git a/public/scripts/3rdparty/bootstrap-popover.js b/public/scripts/3rdparty/bootstrap-popover.js new file mode 100644 index 0000000..c637784 --- /dev/null +++ b/public/scripts/3rdparty/bootstrap-popover.js @@ -0,0 +1,90 @@ +/* =========================================================== + * bootstrap-popover.js v1.4.0 + * http://twitter.github.com/bootstrap/javascript.html#popover + * =========================================================== + * Copyright 2011 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================================================== */ + + +!function( $ ) { + + "use strict" + + var Popover = function ( element, options ) { + this.$element = $(element) + this.options = options + this.enabled = true + this.fixTitle() + } + + /* NOTE: POPOVER EXTENDS BOOTSTRAP-TWIPSY.js + ========================================= */ + + Popover.prototype = $.extend({}, $.fn.twipsy.Twipsy.prototype, { + + setContent: function () { + var $tip = this.tip() + $tip.find('.title')[this.options.html ? 'html' : 'text'](this.getTitle()) + $tip.find('.content p')[this.options.html ? 'html' : 'text'](this.getContent()) + $tip[0].className = 'popover' + } + + , hasContent: function () { + return this.getTitle() || this.getContent() + } + + , getContent: function () { + var content + , $e = this.$element + , o = this.options + + if (typeof this.options.content == 'string') { + content = $e.attr(this.options.content) + } else if (typeof this.options.content == 'function') { + content = this.options.content.call(this.$element[0]) + } + + return content + } + + , tip: function() { + if (!this.$tip) { + this.$tip = $('
') + .html(this.options.template) + } + return this.$tip + } + + }) + + + /* POPOVER PLUGIN DEFINITION + * ======================= */ + + $.fn.popover = function (options) { + if (typeof options == 'object') options = $.extend({}, $.fn.popover.defaults, options) + $.fn.twipsy.initWith.call(this, options, Popover, 'popover') + return this + } + + $.fn.popover.defaults = $.extend({} , $.fn.twipsy.defaults, { + placement: 'right' + , content: 'data-content' + , template: '

' + }) + + $.fn.twipsy.rejectAttrOptions.push( 'content' ) + +}( window.jQuery || window.ender ); \ No newline at end of file diff --git a/public/scripts/3rdparty/bootstrap-twipsy.js b/public/scripts/3rdparty/bootstrap-twipsy.js new file mode 100644 index 0000000..5ebbddd --- /dev/null +++ b/public/scripts/3rdparty/bootstrap-twipsy.js @@ -0,0 +1,321 @@ +/* ========================================================== + * bootstrap-twipsy.js v1.4.0 + * http://twitter.github.com/bootstrap/javascript.html#twipsy + * Adapted from the original jQuery.tipsy by Jason Frame + * ========================================================== + * Copyright 2011 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function( $ ) { + + "use strict" + + /* CSS TRANSITION SUPPORT (https://gist.github.com/373874) + * ======================================================= */ + + var transitionEnd + + $(document).ready(function () { + + $.support.transition = (function () { + var thisBody = document.body || document.documentElement + , thisStyle = thisBody.style + , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined + return support + })() + + // set CSS transition event type + if ( $.support.transition ) { + transitionEnd = "TransitionEnd" + if ( $.browser.webkit ) { + transitionEnd = "webkitTransitionEnd" + } else if ( $.browser.mozilla ) { + transitionEnd = "transitionend" + } else if ( $.browser.opera ) { + transitionEnd = "oTransitionEnd" + } + } + + }) + + + /* TWIPSY PUBLIC CLASS DEFINITION + * ============================== */ + + var Twipsy = function ( element, options ) { + this.$element = $(element) + this.options = options + this.enabled = true + this.fixTitle() + } + + Twipsy.prototype = { + + show: function() { + var pos + , actualWidth + , actualHeight + , placement + , $tip + , tp + + if (this.hasContent() && this.enabled) { + $tip = this.tip() + this.setContent() + + if (this.options.animate) { + $tip.addClass('fade') + } + + $tip + .remove() + .css({ top: 0, left: 0, display: 'block' }) + .prependTo(document.body) + + pos = $.extend({}, this.$element.offset(), { + width: this.$element[0].offsetWidth + , height: this.$element[0].offsetHeight + }) + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + + placement = maybeCall(this.options.placement, this, [ $tip[0], this.$element[0] ]) + + switch (placement) { + case 'below': + tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'above': + tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'left': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset} + break + case 'right': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset} + break + } + + $tip + .css(tp) + .addClass(placement) + .addClass('in') + } + } + + , setContent: function () { + var $tip = this.tip() + $tip.find('.twipsy-inner')[this.options.html ? 'html' : 'text'](this.getTitle()) + $tip[0].className = 'twipsy' + } + + , hide: function() { + var that = this + , $tip = this.tip() + + $tip.removeClass('in') + + function removeElement () { + $tip.remove() + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip.bind(transitionEnd, removeElement) : + removeElement() + } + + , fixTitle: function() { + var $e = this.$element + if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') + } + } + + , hasContent: function () { + return this.getTitle() + } + + , getTitle: function() { + var title + , $e = this.$element + , o = this.options + + this.fixTitle() + + if (typeof o.title == 'string') { + title = $e.attr(o.title == 'title' ? 'data-original-title' : o.title) + } else if (typeof o.title == 'function') { + title = o.title.call($e[0]) + } + + title = ('' + title).replace(/(^\s*|\s*$)/, "") + + return title || o.fallback + } + + , tip: function() { + return this.$tip = this.$tip || $('
').html(this.options.template) + } + + , validate: function() { + if (!this.$element[0].parentNode) { + this.hide() + this.$element = null + this.options = null + } + } + + , enable: function() { + this.enabled = true + } + + , disable: function() { + this.enabled = false + } + + , toggleEnabled: function() { + this.enabled = !this.enabled + } + + , toggle: function () { + this[this.tip().hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* TWIPSY PRIVATE METHODS + * ====================== */ + + function maybeCall ( thing, ctx, args ) { + return typeof thing == 'function' ? thing.apply(ctx, args) : thing + } + + /* TWIPSY PLUGIN DEFINITION + * ======================== */ + + $.fn.twipsy = function (options) { + $.fn.twipsy.initWith.call(this, options, Twipsy, 'twipsy') + return this + } + + $.fn.twipsy.initWith = function (options, Constructor, name) { + var twipsy + , binder + , eventIn + , eventOut + + if (options === true) { + return this.data(name) + } else if (typeof options == 'string') { + twipsy = this.data(name) + if (twipsy) { + twipsy[options]() + } + return this + } + + options = $.extend({}, $.fn[name].defaults, options) + + function get(ele) { + var twipsy = $.data(ele, name) + + if (!twipsy) { + twipsy = new Constructor(ele, $.fn.twipsy.elementOptions(ele, options)) + $.data(ele, name, twipsy) + } + + return twipsy + } + + function enter() { + var twipsy = get(this) + twipsy.hoverState = 'in' + + if (options.delayIn == 0) { + twipsy.show() + } else { + twipsy.fixTitle() + setTimeout(function() { + if (twipsy.hoverState == 'in') { + twipsy.show() + } + }, options.delayIn) + } + } + + function leave() { + var twipsy = get(this) + twipsy.hoverState = 'out' + if (options.delayOut == 0) { + twipsy.hide() + } else { + setTimeout(function() { + if (twipsy.hoverState == 'out') { + twipsy.hide() + } + }, options.delayOut) + } + } + + if (!options.live) { + this.each(function() { + get(this) + }) + } + + if (options.trigger != 'manual') { + binder = options.live ? 'live' : 'bind' + eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus' + eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur' + this[binder](eventIn, enter)[binder](eventOut, leave) + } + + return this + } + + $.fn.twipsy.Twipsy = Twipsy + + $.fn.twipsy.defaults = { + animate: true + , delayIn: 0 + , delayOut: 0 + , fallback: '' + , placement: 'above' + , html: false + , live: false + , offset: 0 + , title: 'title' + , trigger: 'hover' + , template: '
' + } + + $.fn.twipsy.rejectAttrOptions = [ 'title' ] + + $.fn.twipsy.elementOptions = function(ele, options) { + var data = $(ele).data() + , rejects = $.fn.twipsy.rejectAttrOptions + , i = rejects.length + + while (i--) { + delete data[rejects[i]] + } + + return $.extend({}, options, data) + } + +}( window.jQuery || window.ender ); \ No newline at end of file diff --git a/public/scripts/main.js b/public/scripts/main.js index ee9b978..7a890d2 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -13,3 +13,13 @@ var sb = { }; $('document').ready(sb.init); + + $(function () { + $("a[rel=popover]") + .popover({ + offset: 10 + }) + .click(function(e) { + e.preventDefault() + }) + }) \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 8cdf1ce..f2297d4 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -23,10 +23,10 @@ {$site->name} - {StatusBoard_Status::name($site->status())} + - TODO + TODO diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 45516a1..094f15a 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -19,6 +19,8 @@ + + @@ -26,9 +28,9 @@
{$page->include_template('navigation')} -
-
-
+
+
+
@@ -40,19 +42,17 @@ {foreach from=$messages item=message} {$message} {/foreach} -
+
{/if} {$page_content} -
+
-
+
+

Powered by StatusBoard {$version}. Written by Ben Roberts and Nathan Booth.

+
- - -
+
From 0567763fba2fca844c96c8c4feaafc368beb720e Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 19:30:35 +0000 Subject: [PATCH 038/142] Add user control panel and ability to change own password --- public/scripts/main.js | 26 +++++++++++ source/webui/pages/usercp.php | 47 ++++++++++++++++++++ source/webui/templates/navigation.tpl | 2 +- source/webui/templates/usercp.tpl | 62 +++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 source/webui/pages/usercp.php create mode 100644 source/webui/templates/usercp.tpl diff --git a/public/scripts/main.js b/public/scripts/main.js index 7a890d2..2e0c625 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -8,6 +8,32 @@ var sb = { init: function() { $('.alert-data').alert(); + }, + + usercp: { + + init: function() { + $('#usercp_newpassword,#usercp_confirmpassword').bind('keyup', sb.usercp.checkPassword); + + }, + + checkPassword: function() { + password = $('#usercp_newpassword'); + confirm = $('#usercp_confirmpassword'); + + confirm_container = confirm.parent().parent(); + + if (password.val() == confirm.val()) { + console.log("passwords match"); + confirm_container.removeClass('error').addClass('success'); + $('#usercp_confirmpassword_help').hide(); + } else { + console.log("passwords do not match"); + confirm_container.addClass('error').removeClass('success'); + $('#usercp_confirmpassword_help').show(); + } + } + } }; diff --git a/source/webui/pages/usercp.php b/source/webui/pages/usercp.php new file mode 100644 index 0000000..25a4cf7 --- /dev/null +++ b/source/webui/pages/usercp.php @@ -0,0 +1,47 @@ +request(); +$auth = $main->auth(); + +$activity = null; +$success = true; +$errors = array(); +$successes = array(); + +if ($request->exists('do')) { + $activity = $request->get('do'); + switch ($activity) { + + case 'change-password': { + $current_password = StatusBoard_Main::issetelse($_POST['currentpassword'], 'Sihnon_Exception_InvalidParameters'); + $new_password = StatusBoard_Main::issetelse($_POST['newpassword'], 'Sihnon_Exception_InvalidParameters'); + $confirm_password = StatusBoard_Main::issetelse($_POST['confirmpassword'], 'Sihnon_Exception_InvalidParameters'); + + $user = $auth->authenticatedUser(); + if ($user->checkPassword($current_password)) { + if ($new_password == $confirm_password) { + $auth->changePassword($new_password); + $successes[] = 'The password has been changed successfully.'; + } else { + $success = false; + $errors[] = 'The passwords did not match.'; + } + } else { + $success = false; + $errors[] = 'The current password was incorrect.'; + } + } break; + + default: { + $success = false; + $errors[] = "The activity '{$activity}' was not recognised."; + } break; + } +} + +$this->smarty->assign('activity', $activity); +$this->smarty->assign('successes', $successes); +$this->smarty->assign('errors', $errors); + +?> \ No newline at end of file diff --git a/source/webui/templates/navigation.tpl b/source/webui/templates/navigation.tpl index 51df6ee..d5eb43a 100644 --- a/source/webui/templates/navigation.tpl +++ b/source/webui/templates/navigation.tpl @@ -15,6 +15,6 @@ {if $authenticated}

- Logged in as {$user->username} + Logged in as {$user->username}

{/if} \ No newline at end of file diff --git a/source/webui/templates/usercp.tpl b/source/webui/templates/usercp.tpl new file mode 100644 index 0000000..aad4ad9 --- /dev/null +++ b/source/webui/templates/usercp.tpl @@ -0,0 +1,62 @@ +
+ +{if $activity} + {if $successes} + {foreach from=$successes item=message} +
+ {$message|escape:html} +
+ {/foreach} + {/if} + {if $errors} + {foreach from=$errors item=message} +
+ {$message|escape:html} +
+ {/foreach} + {/if} +{/if} + + +
+
+
+
+ Change Password + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+
+   +
+
+
+
+
+
+
+ + \ No newline at end of file From c0571fb1d543c7fee1a15cb51ac444f08e70d778 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Mon, 19 Dec 2011 21:54:40 +0000 Subject: [PATCH 039/142] Fixed current page highlight in nab, fixed output of pobox on homepage to display dynamic content Signed-off-by: Nathan Booth --- source/webui/pages/home.php | 1 + source/webui/pages/navigation.php | 1 - source/webui/pages/usercp.php | 1 + source/webui/templates/home.tpl | 4 +++- source/webui/templates/navigation.tpl | 14 ++++++++++++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/webui/pages/home.php b/source/webui/pages/home.php index 2e190c6..745c8fa 100644 --- a/source/webui/pages/home.php +++ b/source/webui/pages/home.php @@ -7,5 +7,6 @@ for ($i = 1; $i <= 6; ++$i){ } $this->smarty->assign('days', $tbl_header_date); $this->smarty->assign('services', $services); +$this->smarty->assign('requested_page', $this->page); ?> \ No newline at end of file diff --git a/source/webui/pages/navigation.php b/source/webui/pages/navigation.php index 7a7cbf6..a2c3dc4 100644 --- a/source/webui/pages/navigation.php +++ b/source/webui/pages/navigation.php @@ -12,5 +12,4 @@ if ($auth->isAuthenticated()) { $this->smarty->assign('authenticated', $authenticated); $this->smarty->assign('auth', $auth); $this->smarty->assign('user', $user); - ?> \ No newline at end of file diff --git a/source/webui/pages/usercp.php b/source/webui/pages/usercp.php index 25a4cf7..55826b4 100644 --- a/source/webui/pages/usercp.php +++ b/source/webui/pages/usercp.php @@ -43,5 +43,6 @@ if ($request->exists('do')) { $this->smarty->assign('activity', $activity); $this->smarty->assign('successes', $successes); $this->smarty->assign('errors', $errors); +$this->smarty->assign('requested_page', $this->page); ?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index f2297d4..08dd7c1 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -23,10 +23,12 @@ {$site->name} - + + + TODO diff --git a/source/webui/templates/navigation.tpl b/source/webui/templates/navigation.tpl index d5eb43a..0b9d8a4 100644 --- a/source/webui/templates/navigation.tpl +++ b/source/webui/templates/navigation.tpl @@ -1,11 +1,21 @@ StatusBoard

Users and Permissions

From f918970ab317ff82e17c005672e38e8eb3f64dfe Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Wed, 21 Dec 2011 15:22:47 +0000 Subject: [PATCH 080/142] Updated edit button on services to work Signed-off-by: Nathan Booth --- source/webui/templates/admin.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 458a839..42d18f9 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -31,7 +31,7 @@ {foreach from=$services item=service} {$service->name|escape:html} {$service->description|escape:html} - + {/foreach} From c5d8429465c1a090f7863078b0cfd2598e4a136e Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Wed, 21 Dec 2011 16:51:41 +0000 Subject: [PATCH 081/142] Update to guy for Services and admin page structure Signed-off-by: Nathan Booth --- source/webui/templates/admin.tpl | 115 ++++++++++++++++++------------- 1 file changed, 68 insertions(+), 47 deletions(-) diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 42d18f9..2d28571 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -1,4 +1,4 @@ - -
-
+
+
+

TODO

-
- -
+
+
+ +
+

Services

-

Click on a Service to edit its properties, or access any of the sites defined under it.

-
-
- - - - - - - - {if $services} - - - {foreach from=$services item=service} - - - - {/foreach} - - -
ServiceDescriptionAction
{$service->name|escape:html}{$service->description|escape:html}
+
+
+

Current Services

+

Click on a Service to edit its properties, or access any of the sites defined under it.

+
+
+ + + + + + + + {if $services} + {foreach from=$services item=service} + + + + + + {/foreach} + +
ServiceDescriptionAction
+ {$service->name|escape:html} + + {$service->description|escape:html} + + +
{else} You haven't created any services yet. Create some with the button below. {/if} - +
+
+
+
+

Add New Service

+

Use this form to define a new service

+
+
- Add Service -
-
+
- -
+ +
-
-
+
+
-
-
-
+
+
+
+ -
+
+

Users and Permissions

Click on a User to edit its properties. @@ -85,8 +103,10 @@

+
+

Settings

Quick access to important settings. Please use the full settings @@ -101,32 +121,33 @@

-
+

-
+
-
+
  -
-
+ + - - + + + + From 0261de4c10bec5272e6c4a6f7b32707be55f7cf4 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 19:27:47 +0000 Subject: [PATCH 087/142] Make confirm_delete modal generic --- public/scripts/main.js | 16 ++++++++-------- source/webui/templates/admin.tpl | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/public/scripts/main.js b/public/scripts/main.js index 6311953..fd35a10 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -24,22 +24,22 @@ var sb = { admin: { init: function() { - $('#confirm_delete_service').modal({ + $('#confirm_delete').modal({ backdrop: true, keyboard: true }); + $('#confirm_delete_cancel').click(function() { + $('#confirm_delete').modal('hide'); + }); }, - deleteService: function(url) { - $('#confirm_delete_service_do').click(function() { + deleteItem: function(url) { + $('#confirm_delete_do').click(function() { location.href = url; }); - $('#confirm_delete_service_cancel').click(function() { - $('#confirm_delete_service').modal('hide'); - }); - $('#confirm_delete_service').modal('show'); - } + $('#confirm_delete').modal('show'); + }, }, diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index a97f1e6..5354bf9 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -42,7 +42,7 @@ - + {/foreach} @@ -52,7 +52,7 @@ You haven't created any services yet. Create some with the button below. {/if} - From ca1fc52be2a73d723e34ad32f473ff6610635e7e Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 19:28:46 +0000 Subject: [PATCH 088/142] Fix indentation --- source/webui/templates/index.tpl | 63 ++++++++++++++++---------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 18f1109..73a7193 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -27,44 +27,43 @@ -
-
-
- {$page->include_template('navigation')} -
-
-
+
+
+
+ {$page->include_template('navigation')} +
+
+
-
- -
+
+
- {if $messages} -
- {foreach from=$messages item=message} - {if is_array($message)} - {$severity=$message['severity']} -
- {$message['content']|escape:html} -
- {else} -
- {$message|escape:html} -
- {/if} - {/foreach} -
- {/if} + {if $messages} +
+ {foreach from=$messages item=message} + {if is_array($message)} + {$severity=$message['severity']} +
+ {$message['content']|escape:html} +
+ {else} +
+ {$message|escape:html} +
+ {/if} + {/foreach} +
+ {/if} - {$page_content} + {$page_content} -
+
-
-

Powered by StatusBoard {$version} ({$version_codename}). Written by Ben Roberts and Nathan Booth.

-
+
+

Powered by StatusBoard {$version} ({$version_codename}). Written by Ben Roberts and Nathan Booth.

+
- + \ No newline at end of file From a041081f3b48d56c99d02462be03a03c84c1aad4 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 19:29:56 +0000 Subject: [PATCH 089/142] Add admin backend for deleting sites --- source/webui/pages/admin/service.php | 20 +++ source/webui/templates/admin/service.tpl | 220 ++++++++++++----------- 2 files changed, 138 insertions(+), 102 deletions(-) diff --git a/source/webui/pages/admin/service.php b/source/webui/pages/admin/service.php index 204710d..b531a1e 100644 --- a/source/webui/pages/admin/service.php +++ b/source/webui/pages/admin/service.php @@ -58,6 +58,26 @@ if ($request->exists('do')) { } break; + case 'delete-site': { + $site_id = $request->get('site', 'Sihnon_Exception_InvalidParameters'); + + try { + $site = StatusBoard_Site::fromId($site_id); + $site->delete(); + + $messages[] = array( + 'severity' => 'success', + 'content' => 'The Site was deleted successfully.', + ); + } catch (Sihnon_Exception_ResultCountMismatch $e) { + $messages[] = array( + 'severity' => 'error', + 'content' => 'The Site was not deleted as the object requested could not be found.', + ); + } + + } break; + default: { $messages[] = array( 'severity' => 'warning', diff --git a/source/webui/templates/admin/service.tpl b/source/webui/templates/admin/service.tpl index 2e5d73e..c03727b 100644 --- a/source/webui/templates/admin/service.tpl +++ b/source/webui/templates/admin/service.tpl @@ -3,110 +3,126 @@
  • Service {$service->name|escape:html}
  • - -
    -
    -
    -

    Service {$service->name|escape:html}

    -
    -
    -

    Edit Service

    -

    Use this form to update the existing Service

    -
    -
    -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    -   -
    -
    -
    -
    -
    -
    - -
    -
    -

    Existing Sites

    -

    Currently the following sites that are defined for the service {$service->name|escape:html}, Edit the site or delete it from the service here, to add a new one use the form below

    -
    -
    - - - - - - - - {if $sites} - {foreach from=$sites item=site} - - - - - - {/foreach} - -
    SitesDescriptionAction
    - {$site->name|escape:html} - - {$site->description|escape:html} - - -
    - {else} - You haven't created any sites for this service yet. Create some with the button below. - {/if} +
    +
    +

    Service {$service->name|escape:html}

    -
    - -
    -
    -

    Add Site

    -

    Use this form to define a new site to the service {$service->name|escape:html}

    +
    +
    +
    +

    Edit Service

    +

    Use this form to update the existing Service

    -
    -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    -   -
    -
    -
    -
    +
    +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    -
    -
    - +
    +
    +   +
    +
    + + +
    +
    + +
    +
    +

    Existing Sites

    +

    Currently the following sites that are defined for the service {$service->name|escape:html}, Edit the site or delete it from the service here, to add a new one use the form below

    +
    +
    + {if $sites} + + + + + + + + {foreach from=$sites item=site} + + + + + + {/foreach} + +
    SitesDescriptionAction
    + {$site->name|escape:html} + + {$site->description|escape:html} + + + +
    + {else} + You haven't created any sites for this service yet. Create some with the button below. + {/if} + +
    +
    + +
    +
    +

    Add Site

    +

    Use this form to define a new site to the service {$service->name|escape:html}

    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +   +
    +
    +
    +
    +
    +
    + + \ No newline at end of file From 2aa20ddb64679b2e9f35e4fa394542ca651445a0 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Wed, 21 Dec 2011 19:33:59 +0000 Subject: [PATCH 090/142] Updates to generate last 7 days Signed-off-by: Nathan Booth --- source/webui/pages/status.php | 6 ++++ source/webui/templates/status.tpl | 53 +++++++++++++++++++------------ 2 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 source/webui/pages/status.php diff --git a/source/webui/pages/status.php b/source/webui/pages/status.php new file mode 100644 index 0000000..22216e9 --- /dev/null +++ b/source/webui/pages/status.php @@ -0,0 +1,6 @@ +smarty->assign('services', $services); + +?> \ No newline at end of file diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 9762f48..c69abb1 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -1,14 +1,17 @@
    -

    Site Status History {$service->name|escape:html}LDAP - External{$site->name|escape:html}

    +

    Site Status History {$service->name|escape:html}-{$site->name|escape:html}

    This page details the incident history for a Site related to a Service

    -
    -
    -

    Today 21/12/11

    -

    x incidents

    -
    -
    + {foreach from=array(0,1,2,3,4,5,6) item=day} + {if $day == 0} +
    +
    +

    Today {mktime(0,0,0,date("n"),date("j"))|date_format:"d M Y"}

    +

    x incidents

    +
    + +
    @@ -33,14 +36,16 @@
    Incident
    -
    -
    -
    -
    -

    Yesterday 20/12/11

    -

    x incidents

    -
    -
    +
    +
    + {else} +
    +
    +

    {mktime(0,0,0,date("n"),date("j")-$day)|date_format:"d M Y"}

    +

    x incidents

    +
    + +
    @@ -54,13 +59,21 @@ - - + + + + + + + +
    Incident123456 Loss of power on remote site 14:00Resolved15:00Major Incident-
    123457Loss of power on remote site14:00Major Incident-
    -
    -
    - +
    +
    + {/if} + {/foreach} +
    \ No newline at end of file From b6e20e2203efb5fc14c536292bef9e9e4c6dd9a4 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Wed, 21 Dec 2011 21:24:16 +0000 Subject: [PATCH 091/142] Backed and Gui coding for site status page, made the hyperlink on homepage link correctly to status Signed-off-by: Nathan Booth --- source/webui/pages/status.php | 17 +- .../webui/templates/fragments/site-status.tpl | 2 +- source/webui/templates/status.tpl | 161 ++++++++++-------- 3 files changed, 103 insertions(+), 77 deletions(-) diff --git a/source/webui/pages/status.php b/source/webui/pages/status.php index 22216e9..90a8ac2 100644 --- a/source/webui/pages/status.php +++ b/source/webui/pages/status.php @@ -1,6 +1,19 @@ request(); +$service_id = $request->get('service', 'Sihnon_Exception_InvalidParameters'); +$site_id = $request->get('id', 'Sihnon_Exception_InvalidParameters'); +$service = null; +$site = null; + +try { + $service = StatusBoard_Service::fromId($service_id); + $site = StatusBoard_Site::fromId($site_id); +} catch (Sihnon_Exception_ResultCountMismatch $e) { + throw new StatusBoard_Exception_FileNotFound(); +} $services = StatusBoard_Service::all(); -$this->smarty->assign('services', $services); - +$this->smarty->assign('service', $service); +$this->smarty->assign('site', $site); ?> \ No newline at end of file diff --git a/source/webui/templates/fragments/site-status.tpl b/source/webui/templates/fragments/site-status.tpl index 46164c1..c1f667a 100644 --- a/source/webui/templates/fragments/site-status.tpl +++ b/source/webui/templates/fragments/site-status.tpl @@ -15,6 +15,6 @@ {assign var=img_src value="{$base_uri}images/Status_Icons/cross-circle.png"} {/case} {/switch} - + \ No newline at end of file diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index c69abb1..4134ed4 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -1,79 +1,92 @@
    -
    -
    -

    Site Status History {$service->name|escape:html}-{$site->name|escape:html}

    -

    This page details the incident history for a Site related to a Service

    +
    +
    +

    Site Status History: {$service->name|escape:html} - {$site->name|escape:html}

    +

    This page details the incident history for a site

    {foreach from=array(0,1,2,3,4,5,6) item=day} - {if $day == 0} -
    -
    -

    Today {mktime(0,0,0,date("n"),date("j"))|date_format:"d M Y"}

    -

    x incidents

    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    IncidentDescriptionTime OpenedStatusTime Closed
    123456Loss of power on remote site14:00Major Incident-
    123457Loss of power on remote site14:00Major Incident-
    -
    -
    - {else} + {if $day == 0} +
    +
    +

    Today {mktime(0,0,0,date("n"),date("j"))|date_format:"d M Y"}

    +

    x incidents

    +
    +
    + {$start=mktime(0,0,0,date("n"),date("j")-$day)} + {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} + {$incidentsDuring=$site->openIncidentsDuring($start, $end)} + {if $incidentsDuring} + + + + + + + + + + {foreach from=$incidentsDuring item=incident} + + + + + + + + {/foreach} + {else} +

    There were no recorded incidents on this day

    + {/if} + +
    IncidentDescriptionTime OpenedStatusTime Closed
    {$incident->reference|escape:html}{$incident->description|truncate|escape:html}{date('d-M H:i', $incident->start_time)}{StatusBoard_Status::name($incident->currentStatus())}{if $incident->actual_end_time} + {date('d-M H:i', $incident->actual_end_time)} + {else} + Still Open + {/if} +
    +
    +
    + {else}
    -
    -

    {mktime(0,0,0,date("n"),date("j")-$day)|date_format:"d M Y"}

    -

    x incidents

    +
    +

    {mktime(0,0,0,date("n"),date("j")-$day)|date_format:"d M Y"}

    +

    x incidents

    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    IncidentDescriptionTime OpenedStatusTime Closed
    123456Loss of power on remote site14:00Major Incident-
    123457Loss of power on remote site14:00Major Incident-
    -
    -
    - {/if} - {/foreach} - -
    +
    + {$start=mktime(0,0,0,date("n"),date("j")-$day)} + {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} + {$incidentsDuring=$site->openIncidentsDuring($start, $end)} + {if $incidentsDuring} + + + + + + + + + + {foreach from=$incidentsDuring item=incident} + + + + + + + {/foreach} + {else} +

    There were no recorded incidents on this day

    + {/if} + +
    IncidentDescriptionTime OpenedStatusTime Closed
    {$incident->reference|escape:html}{$incident->description|truncate|escape:html}{date('d-M H:i', $incident->start_time)}{StatusBoard_Status::name($incident->currentStatus())}{if $incident->actual_end_time} + {date('d-M H:i', $incident->actual_end_time)} + {else} + Still Open + {/if} +
    +
    +
    + {/if} + {/foreach} +
    +
    \ No newline at end of file From aa26ed4bf759dc90bd5bcf83b3d86d9ccb1f1221 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 23:32:52 +0000 Subject: [PATCH 092/142] Convert admin deletes to use POST requests --- public/scripts/main.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/public/scripts/main.js b/public/scripts/main.js index fd35a10..23c3a78 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -35,7 +35,7 @@ var sb = { deleteItem: function(url) { $('#confirm_delete_do').click(function() { - location.href = url; + sb.request.post(url); }); $('#confirm_delete').modal('show'); @@ -67,6 +67,20 @@ var sb = { } } + }, + + request: { + + post: function(url, data) { + console.log('Posting'); + var form = $('
    ').attr('method', 'post').attr('action', url); + for (var key in data) { + form.appendChild($('').attr('name', key).val(data[key])); + } + + form.submit(); + } + } }; From 9f35058e8c1f40736cce2c266e5be9ca646d4a74 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 23:51:39 +0000 Subject: [PATCH 093/142] Update admin pages to use PRG pattern --- source/webui/pages/admin.php | 4 ++++ source/webui/pages/admin/incident.php | 4 ++++ source/webui/pages/admin/service.php | 4 ++++ source/webui/pages/admin/site.php | 4 ++++ source/webui/templates/index.tpl | 5 +++++ 5 files changed, 21 insertions(+) diff --git a/source/webui/pages/admin.php b/source/webui/pages/admin.php index 6b51a08..c5a9a49 100644 --- a/source/webui/pages/admin.php +++ b/source/webui/pages/admin.php @@ -4,6 +4,7 @@ $main = StatusBoard_Main::instance(); $auth = $main->auth(); $config = $main->config(); $request = $main->request(); +$session = $main->session(); if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission::PERM_Administrator)) { throw new StatusBoard_Exception_NotAuthorised(); @@ -56,6 +57,9 @@ if ($request->exists('do')) { ); } } + + $session->set('messages', $messages); + StatusBoard_Page::redirect('admin/tab/services/'); } $this->smarty->assign('tab', $request->get('tab', 'admin')); diff --git a/source/webui/pages/admin/incident.php b/source/webui/pages/admin/incident.php index 8aed6c0..cce3d10 100644 --- a/source/webui/pages/admin/incident.php +++ b/source/webui/pages/admin/incident.php @@ -3,6 +3,7 @@ $main = StatusBoard_Main::instance(); $request = $main->request(); $auth = $main->auth(); +$session = $main->session(); if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission::PERM_UpdateIncidents)) { throw new StatusBoard_Exception_NotAuthorised(); @@ -71,6 +72,9 @@ if ($request->exists('do')) { } } + + $session->set('messages', $messages); + StatusBoard_Page::redirect("admin/incident/service/{$service->id}/site/{$site->id}/id/{$incident->id}/"); } $statuses = $incident->statusChanges(); diff --git a/source/webui/pages/admin/service.php b/source/webui/pages/admin/service.php index b531a1e..9429dde 100644 --- a/source/webui/pages/admin/service.php +++ b/source/webui/pages/admin/service.php @@ -3,6 +3,7 @@ $main = StatusBoard_Main::instance(); $request = $main->request(); $auth = $main->auth(); +$session = $main->session(); if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission::PERM_UpdateStatusBoards)) { throw new StatusBoard_Exception_NotAuthorised(); @@ -85,6 +86,9 @@ if ($request->exists('do')) { ); } } + + $session->set('messages', $messages); + StatusBoard_Page::redirect("admin/service/id/{$service->id}/"); } diff --git a/source/webui/pages/admin/site.php b/source/webui/pages/admin/site.php index acd73e5..8dea08c 100644 --- a/source/webui/pages/admin/site.php +++ b/source/webui/pages/admin/site.php @@ -3,6 +3,7 @@ $main = StatusBoard_Main::instance(); $request = $main->request(); $auth = $main->auth(); +$session = $main->session(); if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission::PERM_UpdateStatusBoards)) { throw new StatusBoard_Exception_NotAuthorised(); @@ -80,6 +81,9 @@ if ($request->exists('do')) { } } + + $session->set('messages', $messages); + StatusBoard_Page::redirect("admin/site/service/{$service->id}/id/{$site->id}/"); } diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 73a7193..0264031 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -39,6 +39,11 @@
    + {if ! $messages} + {$session = StatusBoard_Main::instance()->session()} + {$messages = $session->get('messages')} + {$session->delete('messages')} + {/if} {if $messages}
    {foreach from=$messages item=message} From 3efc70b5e919c0fb98e213e9b4d77d1a1ac969b8 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Wed, 21 Dec 2011 23:54:31 +0000 Subject: [PATCH 094/142] Update usercp to use PRG pattern --- source/webui/pages/usercp.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/webui/pages/usercp.php b/source/webui/pages/usercp.php index 6fa317d..a1fc75a 100644 --- a/source/webui/pages/usercp.php +++ b/source/webui/pages/usercp.php @@ -3,6 +3,7 @@ $main = StatusBoard_Main::instance(); $request = $main->request(); $auth = $main->auth(); +$session = $main->session(); $activity = null; @@ -44,6 +45,9 @@ if ($request->exists('do')) { ); } break; } + + $session->set('messages', $messages); + StatusBoard_Page::redirect("usercp/"); } $this->smarty->assign('activity', $activity); From 5523ee3b3ed6e28f3a4121f457996e3cae55c1b3 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 00:08:10 +0000 Subject: [PATCH 095/142] Fix admin tab javascript and remove incorrect name attributes --- source/webui/templates/admin.tpl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 5354bf9..e42a52a 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -1,31 +1,31 @@
    -
    +

    TODO

    -
    +

    Services

    -
    +

    Current Services

    Click on a Service to edit its properties, or access any of the sites defined under it.

    {if $services} - +
    @@ -66,7 +66,7 @@ -
    +

    Add New Service

    Use this form to define a new service

    @@ -101,7 +101,7 @@
    -
    +

    Users and Permissions

    Click on a User to edit its properties. @@ -120,7 +120,7 @@

    -
    +

    Settings

    Quick access to important settings. Please use the full settings From 64fe5dcd3ee454b97b301f02d3b4e355d3954e3c Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Thu, 22 Dec 2011 09:25:27 +0000 Subject: [PATCH 096/142] tweaks to admin gui and status page Signed-off-by: Nathan Booth --- source/webui/templates/admin.tpl | 2 +- source/webui/templates/admin/service.tpl | 4 ++-- source/webui/templates/status.tpl | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index e42a52a..0999824 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -41,7 +41,7 @@ {$service->description|escape:html}

    diff --git a/source/webui/templates/admin/service.tpl b/source/webui/templates/admin/service.tpl index c03727b..b629c93 100644 --- a/source/webui/templates/admin/service.tpl +++ b/source/webui/templates/admin/service.tpl @@ -64,8 +64,8 @@ {$site->description|escape:html} {/foreach} diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 4134ed4..9c406f0 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -8,7 +8,6 @@

    Today {mktime(0,0,0,date("n"),date("j"))|date_format:"d M Y"}

    -

    x incidents

    {$start=mktime(0,0,0,date("n"),date("j")-$day)} @@ -49,7 +48,6 @@

    {mktime(0,0,0,date("n"),date("j")-$day)|date_format:"d M Y"}

    -

    x incidents

    {$start=mktime(0,0,0,date("n"),date("j")-$day)} From 51617a7acfcd34b3ba2715ea87689c23297d88ba Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 10:10:23 +0000 Subject: [PATCH 097/142] Update actual_end_time when incident set to resolved --- source/webui/pages/admin/incident.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/webui/pages/admin/incident.php b/source/webui/pages/admin/incident.php index cce3d10..8af0963 100644 --- a/source/webui/pages/admin/incident.php +++ b/source/webui/pages/admin/incident.php @@ -62,6 +62,12 @@ if ($request->exists('do')) { $description = StatusBoard_Main::issetelse($_POST['description'], 'Sihnon_Exception_InvalidParameters'); $incident->changeStatus($status, $description); + + if ($status == StatusBoard_Status::STATUS_Resolved) { + $incident->actual_end_time = time(); + $incident->save(); + } + $messages[] = array( 'severity' => 'success', 'content' => 'The incident status was changed successfully.', From c0791a41662e15308ef18e6826913da45039911d Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 11:20:23 +0000 Subject: [PATCH 098/142] Update to the status page, displays details for a fixed time period --- source/lib/StatusBoard/Main.class.php | 3 +- source/webui/pages/status.php | 11 +- source/webui/templates/status.tpl | 167 +++++++++++++------------- 3 files changed, 95 insertions(+), 86 deletions(-) diff --git a/source/lib/StatusBoard/Main.class.php b/source/lib/StatusBoard/Main.class.php index c2753e4..4d8c7b8 100644 --- a/source/lib/StatusBoard/Main.class.php +++ b/source/lib/StatusBoard/Main.class.php @@ -36,7 +36,8 @@ class StatusBoard_Main extends SihnonFramework_Main { $this->smarty->registerPlugin('modifier', 'formatDuration', array('StatusBoard_Main', 'formatDuration')); $this->smarty->registerPlugin('modifier', 'formatFilesize', array('StatusBoard_Main', 'formatFilesize')); - + $this->smarty->registerPlugin('modifier', 'fuzzyTime', array('StatusBoard_DateTime', 'fuzzyTime')); + $this->smarty->assign('version', '0.1.0'); $this->smarty->assign('version_codename', 'Acai'); $this->smarty->assign('messages', array()); diff --git a/source/webui/pages/status.php b/source/webui/pages/status.php index 90a8ac2..e1a6426 100644 --- a/source/webui/pages/status.php +++ b/source/webui/pages/status.php @@ -1,8 +1,12 @@ request(); + $service_id = $request->get('service', 'Sihnon_Exception_InvalidParameters'); -$site_id = $request->get('id', 'Sihnon_Exception_InvalidParameters'); +$site_id = $request->get('id', 'Sihnon_Exception_InvalidParameters'); + +$start = $request->get('start'); +$end = $request->get('end'); $service = null; $site = null; @@ -13,7 +17,12 @@ try { } catch (Sihnon_Exception_ResultCountMismatch $e) { throw new StatusBoard_Exception_FileNotFound(); } + $services = StatusBoard_Service::all(); + $this->smarty->assign('service', $service); $this->smarty->assign('site', $site); +$this->smarty->assign('start', $start); +$this->smarty->assign('end', $end); + ?> \ No newline at end of file diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 4134ed4..d28f328 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -1,92 +1,91 @@
    -
    +

    Site Status History: {$service->name|escape:html} - {$site->name|escape:html}

    This page details the incident history for a site

    - {foreach from=array(0,1,2,3,4,5,6) item=day} - {if $day == 0} -
    -
    -

    Today {mktime(0,0,0,date("n"),date("j"))|date_format:"d M Y"}

    -

    x incidents

    -
    -
    - {$start=mktime(0,0,0,date("n"),date("j")-$day)} - {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} - {$incidentsDuring=$site->openIncidentsDuring($start, $end)} - {if $incidentsDuring} -
    Service Description - +
    - - + +
    - - - - - - - - - {foreach from=$incidentsDuring item=incident} - - - - - - - - {/foreach} - {else} -

    There were no recorded incidents on this day

    - {/if} - -
    IncidentDescriptionTime OpenedStatusTime Closed
    {$incident->reference|escape:html}{$incident->description|truncate|escape:html}{date('d-M H:i', $incident->start_time)}{StatusBoard_Status::name($incident->currentStatus())}{if $incident->actual_end_time} - {date('d-M H:i', $incident->actual_end_time)} - {else} - Still Open - {/if} -
    -
    -
    - {else} -
    -
    -

    {mktime(0,0,0,date("n"),date("j")-$day)|date_format:"d M Y"}

    -

    x incidents

    + {if $start && $end} + {$incidentsDuring=$site->openIncidentsDuring($start, $end)} + {$incidentCount=count($incidentsDuring)} +

    {$start|date_format:'d-M H:i'} to {$end|date_format:'d-M H:i'}

    + {foreach from=$incidentsDuring item=incident} + {$statuses=$incident->statusChanges()} +
    +
    +

    {$incident->reference|escape:html}

    +

    Opened: {$incident->start_time|date:"r"}

    + {if $incident->estimated_end_time} + {$time_difference=time()-$incident->estimated_end_time} +

    Estimated End Time: {$time_difference|fuzzyTime}

    + {/if}
    -
    - {$start=mktime(0,0,0,date("n"),date("j")-$day)} - {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} - {$incidentsDuring=$site->openIncidentsDuring($start, $end)} - {if $incidentsDuring} - - - - - - - - - - {foreach from=$incidentsDuring item=incident} - - - - - - - {/foreach} - {else} -

    There were no recorded incidents on this day

    - {/if} - -
    IncidentDescriptionTime OpenedStatusTime Closed
    {$incident->reference|escape:html}{$incident->description|truncate|escape:html}{date('d-M H:i', $incident->start_time)}{StatusBoard_Status::name($incident->currentStatus())}{if $incident->actual_end_time} - {date('d-M H:i', $incident->actual_end_time)} - {else} - Still Open - {/if} -
    -
    -
    - {/if} - {/foreach} +
    + + + + + + + + {foreach from=$statuses item=status} + + + + + + {/foreach} + +
    StatusTimeDescription
    {$status->status|escape:html}{$status->ctime|date_format:'d-M H:i'}{$status->description|escape:html}
    +
    +
    + {foreachelse} +

    There were no recorded incidents during this time period.

    + {/foreach} + {else} + {foreach from=array(0,1,2,3,4,5,6) item=day} + {$start=mktime(0,0,0,date("n"),date("j")-$day)} + {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} + {$incidentsDuring=$site->openIncidentsDuring($start, $end)} + {$incidentCount=count($incidentsDuring)} +
    +
    +

    {if $day == 0}Today {/if}{$start|date_format:"d M Y"}

    +

    {$incidentCount} {StatusBoard_Formatting::pluralise('incident','incidents',$incidentCount)}

    +
    +
    + {if $incidentsDuring} + + + + + + + + + + {foreach from=$incidentsDuring item=incident} + + + + + + + + {/foreach} + +
    IncidentDescriptionTime OpenedStatusTime Closed
    {$incident->reference|escape:html}{$incident->description|truncate|escape:html}{date('d-M H:i', $incident->start_time)}{StatusBoard_Status::name($incident->currentStatus())} + {if $incident->actual_end_time} + {date('d-M H:i', $incident->actual_end_time)} + {else} + Still Open + {/if} +
    + {else} +

    There were no recorded incidents on this day

    + {/if} +
    +
    + {/foreach} + {/if}
    \ No newline at end of file From 8e9aa304e3eeae129c994e0c89530e6761b996c7 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Thu, 22 Dec 2011 12:51:43 +0000 Subject: [PATCH 099/142] Updated style with white rounded content boxes and re organised site edit page Signed-off-by: Nathan Booth --- public/styles/normal.css | 32 +++- source/webui/templates/admin.tpl | 14 +- source/webui/templates/admin/service.tpl | 22 +-- source/webui/templates/admin/site.tpl | 191 ++++++++++++++--------- source/webui/templates/home.tpl | 8 + source/webui/templates/status.tpl | 10 +- 6 files changed, 174 insertions(+), 103 deletions(-) diff --git a/public/styles/normal.css b/public/styles/normal.css index 80fcc4d..80c401d 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -11,6 +11,7 @@ body { padding-top: 40px; padding: 0em; font-family: verdana, helvetica, sans-serif; + background: #F7F7F7; } a { @@ -109,8 +110,14 @@ div.incident { margin-left: 2em; } +table{ + background:#fff; +} + table th, table td { text-align: center; + line-height: 10px; + vertical-align: middle; } th.service { @@ -123,7 +130,6 @@ th.service { } div.page-header{ -background:#f5f5f5; margin:10px -5px 20px; padding:10px 10px 0 10px; -moz-border-radius:5px 5px 0 0; @@ -136,7 +142,25 @@ border-bottom: 0px; margin: 0 0 0px; } -table th, table td { -line-height: 10px; -vertical-align: middle; + +#my-tab-content{ + background:#fff; + margin:-20px -5px 20px; + Padding-top:20px; + padding-left:20px; + -moz-border-radius:5px 5px 0 0; +-webkit-border-radius:5px; + border-left: 1px solid #DDD; + border-right: 1px solid #DDD; + border-bottom: 1px solid #DDD; + } + .rounded_content{ + background:#fff; + margin:0 -5px 20px; + Padding-top:20px; + padding-left:20px; + -moz-border-radius:5px 5px 0 0; +-webkit-border-radius:5px; + border: 1px solid #DDD; + } diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 0999824..1f7e028 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -23,7 +23,7 @@

    Current Services

    Click on a Service to edit its properties, or access any of the sites defined under it.

    -
    +
    {if $services} @@ -41,8 +41,8 @@ {$service->description|escape:html} {/foreach} @@ -71,20 +71,20 @@

    Add New Service

    Use this form to define a new service

    -
    +
    - +
    - +
    - +
    diff --git a/source/webui/templates/admin/service.tpl b/source/webui/templates/admin/service.tpl index b629c93..ca47cad 100644 --- a/source/webui/templates/admin/service.tpl +++ b/source/webui/templates/admin/service.tpl @@ -9,12 +9,13 @@

    Service {$service->name|escape:html}

    +

    Edit Service

    Use this form to update the existing Service

    -
    +
    @@ -27,13 +28,13 @@
    - +
    -   +  
    @@ -46,7 +47,7 @@

    Existing Sites

    Currently the following sites that are defined for the service {$service->name|escape:html}, Edit the site or delete it from the service here, to add a new one use the form below

    -
    +
    {if $sites}
    - - + +
    @@ -64,8 +65,8 @@ {$site->description|escape:html} {/foreach} @@ -95,20 +96,20 @@

    Add Site

    Use this form to define a new site to the service {$service->name|escape:html}

    -
    +
    - +
    - +
    - +
    @@ -121,6 +122,7 @@
    + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + StatusBoard + + + +

    + Logged in as admin +

    + +
    +
    +
    + + +
    +
    + + + + + +
    +
    +
    +

    Site: Livingston Data Center - Service: LDAP

    +
    +
    +
    +
    +
    +

    Edit Service

    +

    Use this form to update the existing Service

    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +   +
    +
    +
    + +
    +
    + +
    +
    +

    Open Incidents

    +
    +
    +

    There are no open incidents for this site . If you need to open one, use the form below.

    +
    +
    + +
    +
    +

    Add Incident

    +

    Use this form to add a new incident

    +
    +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    +
    + +
    + +
    +

    Powered by StatusBoard 0.1.0 (Acai). Written by Ben Roberts and Nathan Booth.

    +
    + +
    + + \ No newline at end of file diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 0264031..f842ce7 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -5,6 +5,7 @@ + - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    - StatusBoard - - - -

    - Logged in as admin -

    - -
    -
    -
    - - -
    -
    - - - - - -
    -
    -
    -

    Site: Livingston Data Center - Service: LDAP

    -
    -
    -
    -
    -
    -

    Edit Service

    -

    Use this form to update the existing Service

    -
    -
    -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    -   -
    -
    -
    - -
    -
    - -
    -
    -

    Open Incidents

    -
    -
    -

    There are no open incidents for this site . If you need to open one, use the form below.

    -
    -
    - -
    -
    -

    Add Incident

    -

    Use this form to add a new incident

    -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    -
    - - -
    -
    -
    - -
    - -
    -

    Powered by StatusBoard 0.1.0 (Acai). Written by Ben Roberts and Nathan Booth.

    -
    - -
    - - \ No newline at end of file From 48e2b44517848dbcd8d936ce6149832a9d3b93ad Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 14:51:24 +0000 Subject: [PATCH 106/142] Remove user management from admin --- source/webui/templates/admin.tpl | 278 ++++++++++++-------------- source/webui/templates/navigation.tpl | 1 - 2 files changed, 129 insertions(+), 150 deletions(-) diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 1f7e028..273e4fa 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -3,164 +3,144 @@
    -
    -
    -

    TODO

    -
    -
    - -
    -
    -

    Services

    -
    -
    -

    Current Services

    -

    Click on a Service to edit its properties, or access any of the sites defined under it.

    -
    -
    - {if $services} -
    - - + +
    - - - - - - - {foreach from=$services item=service} - - - - - - {/foreach} - -
    ServiceDescriptionAction
    - {$service->name|escape:html} - - {$service->description|escape:html} - - - -
    - {else} - You haven't created any services yet. Create some with the button below. - {/if} -
    - +
    +
    + +
    +
    +

    Settings

    +

    + Quick access to important settings. Please use the full settings + page to configure more advanced settings. +

    + +
    +
    + Quick Settings + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +   +
    +
    +
    +
    +

    +
    + + From 8c9896f9b9c1bb9bf6509b6e07a83c5ed4a8dbff Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 19:16:18 +0000 Subject: [PATCH 118/142] Add new Add Incident page --- source/webui/pages/admin/add-incident.php | 89 +++++++++++++++ source/webui/templates/admin/add-incident.tpl | 106 ++++++++++++++++++ source/webui/templates/home.tpl | 2 +- 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 source/webui/pages/admin/add-incident.php create mode 100644 source/webui/templates/admin/add-incident.tpl diff --git a/source/webui/pages/admin/add-incident.php b/source/webui/pages/admin/add-incident.php new file mode 100644 index 0000000..c6e32aa --- /dev/null +++ b/source/webui/pages/admin/add-incident.php @@ -0,0 +1,89 @@ +request(); +$auth = $main->auth(); +$session = $main->session(); + +if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission::PERM_UpdateIncidents)) { + throw new StatusBoard_Exception_NotAuthorised(); +} + +if ($request->exists('do')) { + + $service_id = StatusBoard_Main::issetelse($_POST['service'], 'Sihnon_Exception_InvalidParameters'); + $site_id = StatusBoard_Main::issetelse($_POST['site'], 'Sihnon_Exception_InvalidParameters'); + $reference = StatusBoard_Main::issetelse($_POST['reference'], 'Sihnon_Exception_InvalidParameters'); + $description = StatusBoard_Main::issetelse($_POST['description'], 'Sihnon_Exception_InvalidParameters'); + $status = StatusBoard_Main::issetelse($_POST['status'], 'Sihnon_Exception_InvalidParameters'); + $start_time = StatusBoard_Main::issetelse($_POST['starttime'], 'Sihnon_Exception_InvalidParameters'); + $estimated_end_time = StatusBoard_Main::issetelse($_POST['estimatedendtime'], 'Sihnon_Exception_InvalidParameters'); + + $incident = null; + + try { + $service = StatusBoard_Service::fromId($service_id); + $site = StatusBoard_Site::fromId($site_id); + + $start_time = strtotime($start_time); + if ($start_time === null) { + throw new StatusBoard_Exception_InvalidParameters('starttime'); + } + $estimated_end_time = strtotime($estimated_end_time); + if ($estimated_end_time === null) { + throw new StatusBoard_Exception_InvalidParameters('estimatedendtime'); + } + + $incident = $site->newIncident($reference, $description, $status, $start_time, $estimated_end_time); + + $messages[] = array( + 'severity' => 'success', + 'content' => 'The incident was created succesfully.', + ); + } catch (StatusBoard_Exception_ResultCountMismatch $e) { + $messages[] = array( + 'severity' => 'error', + 'content' => 'The incident was not created because the Service or Site could not be found.', + ); + } + + $session->set('messages', $messages); + StatusBoard_Page::redirect("admin/incident/service/{$service->id}/site/{$site->id}/id/{$incident->id}/"); +} + +$service_id = $request->get('service'); +$site_id = $request->get('site'); + +$service = null; +$site = null; + +$services = StatusBoard_Service::all(); +try { + if ($service_id) { + $service = StatusBoard_Service::fromId($service_id); + } + if ($site_id) { + $site = StatusBoard_Site::fromId($site_id); + } +} catch (Sihnon_Exception_ResultCountMismatch $e) { + throw new StatusBoard_Exception_FileNotFound(); +} + +$all_sites = array(); +if ($service) { + $all_sites[$service->id] = $service->sites(); +} else { + foreach ($services as $all_service) { + $all_sites[$all_service->id] = $all_service->sites(); + } +} + + + +$this->smarty->assign('services', $services); +$this->smarty->assign('service', $service); +$this->smarty->assign('all_sites', $all_sites); +$this->smarty->assign('site', $site); +$this->smarty->assign('messages', $messages); + +?> \ No newline at end of file diff --git a/source/webui/templates/admin/add-incident.tpl b/source/webui/templates/admin/add-incident.tpl new file mode 100644 index 0000000..9e20ad6 --- /dev/null +++ b/source/webui/templates/admin/add-incident.tpl @@ -0,0 +1,106 @@ +
    +
    +
    +

    Add Incident

    +

    Use this form to add a new incident

    +
    +
    + +
    +
    +
    + +
    + {if $service} + + {$service->name|escape:html} + {else} + + {/if} +
    +
    + +
    + +
    + {if $service && $site} + + {$site->name|escape:html} + {else} + + {/if} +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index dce12ae..57958e8 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -4,7 +4,7 @@

    {$site_title}

    From fa07b536bf3fcdf701af18287258c6a4ce0dae15 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 22:07:41 +0000 Subject: [PATCH 119/142] Fix most severe incident status calculation for status board --- source/lib/StatusBoard/Incident.class.php | 54 ++++++++++++++++++++--- source/lib/StatusBoard/Status.class.php | 8 +++- source/webui/templates/home.tpl | 2 +- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index 6b5472f..a454b1e 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -59,7 +59,7 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { public function statusAt($time) { $database = StatusBoard_Main::instance()->database(); - $row = $database->selectOne('SELECT `status` FROM `incidentstatus` WHERE `incident`=:incident AND ctime < :time ORDER BY ctime DESC LIMIT 1', array( + $row = $database->selectOne('SELECT `status` FROM `incidentstatus` WHERE `incident`=:incident AND `ctime` < :time ORDER BY `ctime` DESC LIMIT 1', array( array('name' => 'incident', 'value' => $this->id, 'type' => PDO::PARAM_INT), array('name' => 'time', 'value' => $time, 'type' => PDO::PARAM_INT), ) @@ -68,18 +68,29 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { return $row['status']; } + protected function statusesBetween($start, $end) { + $database = StatusBoard_Main::instance()->database(); + + $row = $database->selectList('SELECT `status` FROM `incidentstatus` WHERE `incident`=:incident AND `ctime` >= :start AND `ctime` < :end', array( + array('name' => 'incident', 'value' => $this->id, 'type' => PDO::PARAM_INT), + array('name' => 'start', 'value' => $start, 'type' => PDO::PARAM_INT), + array('name' => 'end', 'value' => $end, 'type' => PDO::PARAM_INT), + ) + ); + + return array_map(function($a) { + return $a['status']; + }, $row); + } + /** * Returns the status of the most severe incident in the given set * * @param array(StatusBoard_Incident) $incidents */ public static function highestSeverityStatus(array $incidents, $time = null) { - if ( ! $incidents) { - return StatusBoard_Status::STATUS_Resolved; - } - // Check for the highest severity incident. - $status = StatusBoard_Status::STATUS_Maintenance; + $status = StatusBoard_Status::STATUS_Resolved; foreach ($incidents as $incident) { $incident_status = null; if ($time) { @@ -96,6 +107,37 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { return $status; } + /** + * Returns the status of the most severe incident in the given set + * + * @param array(StatusBoard_Incident) $incidents + */ + public static function highestSeverityStatusBetween(array $incidents, $start, $end) { + // Check for the highest severity incident. + $most_severe_status = StatusBoard_Status::STATUS_Resolved; + foreach ($incidents as $incident) { + $most_severe_incident_status = StatusBoard_Status::STATUS_Resolved; + + $statuses_between = $incident->statusesBetween($start, $end); + foreach ($statuses_between as $status) { + $most_severe_incident_status = StatusBoard_Status::mostSevere($most_severe_incident_status, $status); + } + + $incident_status_before = StatusBoard_Status::STATUS_Resolved; + try { + $incident_status_before = $incident->statusAt($start); + } catch (SihnonFramework_Exception_ResultCountMismatch $e) { + // Incident was opened after $start, ignore + } + + $most_severe_incident_status = StatusBoard_Status::mostSevere($incident_status_before, $most_severe_incident_status); + + $most_severe_status = StatusBoard_Status::mostSevere($most_severe_status, $most_severe_incident_status); + } + + return $most_severe_status; + } + public function statusChanges($ignore_cache = false) { if ($this->statuses === null || $ignore_cache) { $this->statuses = StatusBoard_IncidentStatus::allFor('incident', $this->id); diff --git a/source/lib/StatusBoard/Status.class.php b/source/lib/StatusBoard/Status.class.php index 461ecfd..7aa624b 100644 --- a/source/lib/StatusBoard/Status.class.php +++ b/source/lib/StatusBoard/Status.class.php @@ -1,6 +1,6 @@ 'The service is exeriencing a major outage affecting all customers.', ); - public function available() { + public static function available() { return array( self::STATUS_Resolved, self::STATUS_Maintenance, @@ -54,6 +54,10 @@ class StatusBoard_Status { return ($test > $base); } + public static function mostSevere($first, $second) { + return static::isMoreSevere($first, $second) ? $second : $first; + } + } ?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index 57958e8..c14390e 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -42,7 +42,7 @@ {$start=mktime(0,0,0,date("n"),date("j")-$day)} {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} {$incidentsDuring=$site->openIncidentsDuring($start, $end)} - {$statusDuring=StatusBoard_Incident::highestSeverityStatus($incidentsDuring, $end)} + {$statusDuring=StatusBoard_Incident::highestSeverityStatusBetween($incidentsDuring, $start, $end)} From 3b5f3b2f8913a9830a8adc77f02a1924ba5ed3d0 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 23:30:37 +0000 Subject: [PATCH 120/142] Fix broken edit form --- source/webui/templates/admin/service.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/templates/admin/service.tpl b/source/webui/templates/admin/service.tpl index b26e91b..b2ed8b2 100644 --- a/source/webui/templates/admin/service.tpl +++ b/source/webui/templates/admin/service.tpl @@ -28,7 +28,7 @@
    - +
    From 0b84a07c293c93ded2e513f54efc1af51ad561d0 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Thu, 22 Dec 2011 23:31:39 +0000 Subject: [PATCH 121/142] Convert site, service and incident names into admin edit links --- source/webui/pages/home.php | 8 +++++++- source/webui/pages/status.php | 4 ++++ source/webui/templates/home.tpl | 12 ++++++++++-- source/webui/templates/status.tpl | 16 ++++++++++++++-- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/source/webui/pages/home.php b/source/webui/pages/home.php index bfce82f..2a2616d 100644 --- a/source/webui/pages/home.php +++ b/source/webui/pages/home.php @@ -1,10 +1,16 @@ config(); +$main = StatusBoard_Main::instance(); +$config = $main->config(); +$auth = $main->auth(); + $services = StatusBoard_Service::all(); $this->smarty->assign('services', $services); $this->smarty->assign('site_title', $config->get('site.title', 'Status Board')); +$display_admin_links = ($auth->isAuthenticated() && $auth->isAdministrator()); +$this->smarty->assign('display_admin_links', $display_admin_links); + ?> \ No newline at end of file diff --git a/source/webui/pages/status.php b/source/webui/pages/status.php index e1a6426..ba44d78 100644 --- a/source/webui/pages/status.php +++ b/source/webui/pages/status.php @@ -1,6 +1,7 @@ request(); +$auth = $main->auth(); $service_id = $request->get('service', 'Sihnon_Exception_InvalidParameters'); $site_id = $request->get('id', 'Sihnon_Exception_InvalidParameters'); @@ -25,4 +26,7 @@ $this->smarty->assign('site', $site); $this->smarty->assign('start', $start); $this->smarty->assign('end', $end); +$display_admin_links = ($auth->isAuthenticated() && $auth->isAdministrator()); +$this->smarty->assign('display_admin_links', $display_admin_links); + ?> \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index c14390e..c4014a3 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -25,14 +25,22 @@ {foreach from=$services item=service}
    {foreach from=$service->sites() item=site} {$incidents=$site->openIncidents()} {foreach from=$incidentsDuring item=incident} - + From c4eb37d1c0a324401209ad738639b33495234425 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Fri, 23 Dec 2011 01:33:59 +0000 Subject: [PATCH 122/142] Add count() methods to Site and Service --- source/lib/StatusBoard/Service.class.php | 6 ++++++ source/lib/StatusBoard/Site.class.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/source/lib/StatusBoard/Service.class.php b/source/lib/StatusBoard/Service.class.php index 24aec8e..70c70bf 100644 --- a/source/lib/StatusBoard/Service.class.php +++ b/source/lib/StatusBoard/Service.class.php @@ -31,6 +31,12 @@ class StatusBoard_Service extends StatusBoard_DatabaseObject { return $this->sites; } + + public static function count() { + $database = StatusBoard_Main::instance()->database(); + $row = $database->selectOne('SELECT COUNT(*) AS `service_count` FROM `service`'); + return $row['service_count']; + } } diff --git a/source/lib/StatusBoard/Site.class.php b/source/lib/StatusBoard/Site.class.php index e567a88..f49f502 100644 --- a/source/lib/StatusBoard/Site.class.php +++ b/source/lib/StatusBoard/Site.class.php @@ -47,6 +47,12 @@ class StatusBoard_Site extends StatusBoard_DatabaseObject { return StatusBoard_Incident::highestSeverityStatus($this->openIncidents()); } + public static function count() { + $database = StatusBoard_Main::instance()->database(); + $row = $database->selectOne('SELECT COUNT(*) AS `site_count` FROM `site`'); + return $row['site_count']; + } + } ?> \ No newline at end of file From 7a0c2defe493a62585c8263a6ac8eb41e98db25f Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Fri, 23 Dec 2011 01:34:31 +0000 Subject: [PATCH 123/142] Add count and near/past deadline retrieval to Incident --- source/lib/StatusBoard/Incident.class.php | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index a454b1e..c32ab05 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -43,6 +43,19 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { return static::allFor('site', $site->id, 'incident_opentimes', '`start_time` < :end AND `ctime` > :start', $params); } + public static function allNearDeadline() { + return static::all('incident_open', "estimated_end_time>=:threshold AND estimated_end_time>=:now", array( + array('name' => 'threshold', 'value' => time() - StatusBoard_DateTime::HOUR, 'type' => PDO::PARAM_INT), + array('name' => 'now', 'value' => time(), 'type' => PDO::PARAM_INT), + )); + } + + public static function allPastDeadline() { + return static::all('incident_open', "estimated_end_time<=:threshold", array( + array('name' => 'threshold', 'value' => time(), 'type' => PDO::PARAM_INT), + )); + } + public function currentStatus($ignore_cache = false) { if ($this->current_status === null || $ignore_cache) { $database = StatusBoard_Main::instance()->database(); @@ -157,6 +170,26 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { return $new_status; } + public static function counts() { + $database = StatusBoard_Main::instance()->database(); + $rows = $database->selectList('SELECT `status`, COUNT(*) AS `incident_count` FROM `incidentstatus_current` GROUP BY `status`'); + + $counts = array(); + foreach (StatusBoard_Status::available() as $status) { + $counts[$status] = 0; + } + foreach ($rows as $row) { + $counts[$row['status']] = $row['incident_count']; + } + + return $counts; + } + + public static function compareEstimatedEndTimes(StatusBoard_Incident $first, StatusBoard_Incident $second) { + return $first->estimated_end_time < $second->estimated_end_time; + } + + } ?> \ No newline at end of file From 410f513e539342d47fa3ad540791dcc2f432bff5 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Fri, 23 Dec 2011 01:34:55 +0000 Subject: [PATCH 124/142] Fix undefined variable warning --- source/webui/pages/admin/incident.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/webui/pages/admin/incident.php b/source/webui/pages/admin/incident.php index 8af0963..a1f602a 100644 --- a/source/webui/pages/admin/incident.php +++ b/source/webui/pages/admin/incident.php @@ -9,6 +9,8 @@ if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission throw new StatusBoard_Exception_NotAuthorised(); } +$messages = array(); + $service_id = $request->get('service', 'Sihnon_Exception_InvalidParameters'); $site_id = $request->get('site', 'Sihnon_Exception_InvalidParameters'); $incident_id = $request->get('id', 'Sihnon_Exception_InvalidParameters'); From 79a2886e56eefa5ebfbec6293dd25c9d90d82208 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Fri, 23 Dec 2011 01:35:22 +0000 Subject: [PATCH 125/142] Update following changes to Formatting::pluralise --- source/webui/templates/status.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 5291e58..2c7e1f3 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -56,7 +56,7 @@

    {if $day == 0}Today {/if}{$start|date_format:"d M Y"}

    -

    {$incidentCount} {StatusBoard_Formatting::pluralise('incident','incidents',$incidentCount)}

    +

    {$incidentCount} {StatusBoard_Formatting::pluralise($incidentCount,'incident','incidents')}

    {if $incidentsDuring} From 803cbb6a3f589fe88b9953eeb2a3801c2b769314 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Fri, 23 Dec 2011 01:35:38 +0000 Subject: [PATCH 126/142] Add Admin Summary page with statistics and alerts --- source/webui/pages/admin.php | 20 +++++- source/webui/templates/admin.tpl | 89 +++++++++++++++++++++++++-- source/webui/templates/navigation.tpl | 2 +- 3 files changed, 102 insertions(+), 9 deletions(-) diff --git a/source/webui/pages/admin.php b/source/webui/pages/admin.php index 1019438..ab85b8a 100644 --- a/source/webui/pages/admin.php +++ b/source/webui/pages/admin.php @@ -13,6 +13,8 @@ if ( ! $auth->isAuthenticated() || ! $auth->hasPermission(StatusBoard_Permission $activity = null; $success = true; +$destination = $request->get('tab', 'summary'); + if ($request->exists('do')) { $activity = $request->get('do'); switch ($activity) { @@ -89,14 +91,28 @@ if ($request->exists('do')) { } } - $destination = $request->get('tab', 'admin'); $destination = "admin/tab/{$destination}/"; $session->set('messages', $messages); StatusBoard_Page::redirect($destination); } -$this->smarty->assign('tab', $request->get('tab', 'admin')); +$this->smarty->assign('tab', $destination); +if ($destination == 'summary') { + $this->smarty->assign('service_count', StatusBoard_Service::count()); + $this->smarty->assign('site_count', StatusBoard_Site::count()); + $this->smarty->assign('incident_counts', StatusBoard_Incident::counts()); + + $incidents_near_deadline = StatusBoard_Incident::allNearDeadline(); + usort($incidents_near_deadline, array('StatusBoard_Incident', 'compareEstimatedEndTimes')); + + $incidents_past_deadline = StatusBoard_Incident::allPastDeadline(); + usort($incidents_past_deadline, array('StatusBoard_Incident', 'compareEstimatedEndTimes')); + + $this->smarty->assign('incidents_near_deadline', $incidents_near_deadline); + $this->smarty->assign('incidents_past_deadline', $incidents_past_deadline); +} + $services = StatusBoard_Service::all(); $this->smarty->assign('services', $services); diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index e4a205c..349051f 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -1,17 +1,94 @@
    -
    -
    -

    TODO

    -
    +
    +
    +
    +
    +

    Alerts

    +
    +
    +

    + There {StatusBoard_Formatting::pluralise(count($incidents_near_deadline), 'is', 'are')} {$incidents_near_deadline|count} {StatusBoard_Formatting::pluralise(count($incidents_near_deadline), 'incident', 'incidents')} + within 1 hour of the current estimated end time. +

    + {if $incidents_near_deadline} +
      + {foreach from=$incidents_near_deadline item=incident} +
    1. {$incident->reference|escape:html}
    2. + {/foreach} +
    + {/if} +

    + There {StatusBoard_Formatting::pluralise(count($incidents_near_deadline), 'is', 'are')} {$incidents_past_deadline|count} {StatusBoard_Formatting::pluralise(count($incidents_past_deadline), 'incident', 'incidents')} + already past the set estimated end time. +

    + {if $incidents_past_deadline} +
      + {foreach from=$incidents_past_deadline item=incident} +
    1. {$incident->reference|escape:html}
    2. + {/foreach} +
    + {/if} +
    +
    +
    +
    +

    Statistics

    +
    +
    +
    {include file="fragments/site-status.tpl" nocache start=$start end=$end status=$statusDuring incidents=$incidentsDuring}
    - {$service->name} + {if $display_admin_links} + {$service->name} + {else} + {$service->name} + {/if}
    - {$site->name} + {if $display_admin_links} + {$site->name|escape:html} + {else} + {$site->name} + {/if} {$status=$site->status()} diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 1e868f8..5291e58 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -12,7 +12,13 @@ {$statuses=$incident->statusChanges()}
    -

    {$incident->reference|escape:html}

    +

    + {if $display_admin_links && $incident->currentStatus() != StatusBoard_Status::STATUS_Resolved} + {$incident->reference|escape:html} + {else} + {$incident->reference|escape:html} + {/if} +

    Opened: {$incident->start_time|date:"r"}

    {if $incident->estimated_end_time} {$time_difference=time()-$incident->estimated_end_time} @@ -65,7 +71,13 @@

    {$incident->reference|escape:html} + {if $display_admin_links && $incident->currentStatus() != StatusBoard_Status::STATUS_Resolved} + {$incident->reference|escape:html} + {else} + {$incident->reference|escape:html} + {/if} + {$incident->description|truncate|escape:html} {date('d-M H:i', $incident->start_time)} {StatusBoard_Status::name($incident->currentStatus())}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StatisticCount
    Services{$service_count}
    Sites{$site_count}
    Incidents{array_sum(array_values($incident_counts))}
    Major{$incident_counts[StatusBoard_Status::STATUS_Major]}
    Significant{$incident_counts[StatusBoard_Status::STATUS_Significant]}
    Minor{$incident_counts[StatusBoard_Status::STATUS_Minor]}
    Planned Maintenance{$incident_counts[StatusBoard_Status::STATUS_Maintenance]}
    Resolved{$incident_counts[StatusBoard_Status::STATUS_Resolved]}
    +
    +
    +
    @@ -129,7 +206,7 @@
    - +
    diff --git a/source/webui/templates/navigation.tpl b/source/webui/templates/navigation.tpl index 79e751c..2933de0 100644 --- a/source/webui/templates/navigation.tpl +++ b/source/webui/templates/navigation.tpl @@ -10,7 +10,7 @@
    +
    +
    \ No newline at end of file diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 6ad3f9f..2f75f92 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -73,11 +73,7 @@ {foreach from=$incidentsDuring item=incident} - {if $display_admin_links && $incident->currentStatus() != StatusBoard_Status::STATUS_Resolved} - {$incident->reference|escape:html} - {else} - {$incident->reference|escape:html} - {/if} + {$incident->reference|escape:html} {$incident->description|truncate|escape:html} {date('d-M H:i', $incident->start_time)} From d243bd65d276d3805902282a3b415f01784c92c9 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Sat, 31 Dec 2011 11:46:47 +0000 Subject: [PATCH 134/142] Updated linking from homepage to single status page, links to section for that date when clicked, tidied up to ui bits and bobs Signed-off-by: Nathan Booth --- public/styles/normal.css | 4 ++++ source/webui/templates/fragments/site-status.tpl | 2 +- source/webui/templates/home.tpl | 3 ++- source/webui/templates/incident.tpl | 10 +++++----- source/webui/templates/status.tpl | 11 ++++++----- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/public/styles/normal.css b/public/styles/normal.css index 930743f..b99761a 100644 --- a/public/styles/normal.css +++ b/public/styles/normal.css @@ -18,6 +18,10 @@ a { color: gray; } +.span12 a, .span11 a{ +color: blue; +} + label { margin-left: 1em; margin-right: 1em; diff --git a/source/webui/templates/fragments/site-status.tpl b/source/webui/templates/fragments/site-status.tpl index 3ddff08..c5b6a2e 100644 --- a/source/webui/templates/fragments/site-status.tpl +++ b/source/webui/templates/fragments/site-status.tpl @@ -1,3 +1,3 @@ - + {include file="fragments/image-status-icon.tpl"} \ No newline at end of file diff --git a/source/webui/templates/home.tpl b/source/webui/templates/home.tpl index af8efde..1e2d0c1 100644 --- a/source/webui/templates/home.tpl +++ b/source/webui/templates/home.tpl @@ -44,11 +44,12 @@ {$status=$site->status()} - {include file="fragments/site-status.tpl" nocache start=null end=null} + {include file="fragments/site-status.tpl" nocache date=null start=null end=null} {foreach from=array(0,1,2,3,4,5,6) item=day} {$start=mktime(0,0,0,date("n"),date("j")-$day)} {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} + {$date=mktime(0,0,0,date("n"),date("j")-$day)|date_format:"jM"} {$incidentsDuring=$site->openIncidentsDuring($start, $end)} {$statusDuring=StatusBoard_Incident::highestSeverityStatusBetween($incidentsDuring, $start, $end)} diff --git a/source/webui/templates/incident.tpl b/source/webui/templates/incident.tpl index ef05ce4..6aff016 100644 --- a/source/webui/templates/incident.tpl +++ b/source/webui/templates/incident.tpl @@ -20,8 +20,8 @@

    Service: {$service->name|escape:html}

    Site: {$site->name|escape:html}

    -

    Opened: {$incident->start_time|date_format:'h:i:s y-m-d'}

    -

    Estimated End: {$incident->estimated_end_time|date_format:'h:i:s y-m-d'}

    +

    Opened: {$incident->start_time|date_format:'h:i d-M-y'}

    +

    Estimated End: {ucwords(StatusBoard_DateTime::fuzzyTime($incident->estimated_end_time))}

    @@ -31,7 +31,7 @@

    The table display an audit log of changes to this incident

    - +
    @@ -41,8 +41,8 @@ {foreach from=$statuses item=status} diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index 2f75f92..ec06b32 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -2,7 +2,7 @@

    Site Status History: {$service->name|escape:html} - {$site->name|escape:html}

    -
    +

    This page details the incident history for a site:

    {if $start && $end} {$incidentsDuring=$site->openIncidentsDuring($start, $end)} @@ -53,12 +53,13 @@ {$end=mktime(0,0,0,date("n"),date("j")-$day+1)} {$incidentsDuring=$site->openIncidentsDuring($start, $end)} {$incidentCount=count($incidentsDuring)} -
    +

    {$start|date_format:"d M Y"}

    {$incidentCount} {StatusBoard_Formatting::pluralise($incidentCount,'incident','incidents')}

    +

    Note: Click on incident number to see incident audit trail

    -
    +
    {if $incidentsDuring}
    Date/Time Status
    - {StatusBoard_DateTime::fuzzyTime($status->ctime)}
    - {$status->ctime|date_format:'y-m-d h:i:s'} + {ucwords(StatusBoard_DateTime::fuzzyTime($status->ctime))}
    + {$status->ctime|date_format:'h:i d-M-y'}
    {StatusBoard_Status::name($status->status)} {$status->description|escape:html}
    @@ -85,7 +86,7 @@ Still Open {/if} - {if $display_admin_links}{/if} + {if $display_admin_links} {/foreach} @@ -94,7 +95,7 @@

    There were no recorded incidents on this day

    {/if} - + {/foreach} {/if} From b50d5e50dcc9fd87050f3e97ed988752db6c79c4 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Sat, 31 Dec 2011 12:40:40 +0000 Subject: [PATCH 135/142] UI updates to admin page and bug fixes, added readme Signed-off-by: Nathan Booth --- README.md | 21 +++++++++++++++++++++ source/webui/templates/admin.tpl | 18 +++++++++++------- source/webui/templates/index.tpl | 2 +- source/webui/templates/status.tpl | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) create mode 100755 README.md diff --git a/README.md b/README.md new file mode 100755 index 0000000..373d052 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +StatusBoard +============= + +StatusBoard is a simple PHP web-based tool for displaying the status of services. Administrators can manually record incidents and provide estimated end times and simple descriptions. This tool is suitable for exposing status information to customers or other third parties and does not need to be connected to internal systems. + +Features +------- + +#Customisable list of Services and Sites. +#Manual reporting and status changes for Incidents. +#Multiple severity levels. +#Full admin UI. + +Requirements +------------ + +PHP +MYSQL +Smarty +sihnon-php-lib: https://github.com/optiz0r/sihnon-php-lib + diff --git a/source/webui/templates/admin.tpl b/source/webui/templates/admin.tpl index 8555eb1..09d7030 100644 --- a/source/webui/templates/admin.tpl +++ b/source/webui/templates/admin.tpl @@ -15,7 +15,7 @@

    Alerts

    -

    +

    There {StatusBoard_Formatting::pluralise(count($incidents_near_deadline), 'is', 'are')} {$incidents_near_deadline|count} {StatusBoard_Formatting::pluralise(count($incidents_near_deadline), 'incident', 'incidents')} within 1 hour of the current estimated end time.

    @@ -43,8 +43,8 @@

    Statistics

    -
    -
    Edit Incident: {$incident->reference|escape:html}{/if}
    +
    +
    @@ -53,19 +53,23 @@ - + - + - + + - + + + + diff --git a/source/webui/templates/index.tpl b/source/webui/templates/index.tpl index 4d18af3..c6cb11f 100644 --- a/source/webui/templates/index.tpl +++ b/source/webui/templates/index.tpl @@ -1,4 +1,4 @@ - +Status Board diff --git a/source/webui/templates/status.tpl b/source/webui/templates/status.tpl index ec06b32..46667b1 100644 --- a/source/webui/templates/status.tpl +++ b/source/webui/templates/status.tpl @@ -57,7 +57,7 @@

    {$start|date_format:"d M Y"}

    {$incidentCount} {StatusBoard_Formatting::pluralise($incidentCount,'incident','incidents')}

    -

    Note: Click on incident number to see incident audit trail

    + {if $incidentsDuring}

    Note: Click on incident number to see incident audit trail

    {/if}
    {if $incidentsDuring} From a558dbda3118327e5b9484bcfd9544fc27eecb8a Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 31 Dec 2011 16:37:34 +0000 Subject: [PATCH 136/142] Backdate IncidentStatus when an Incident is created retrospectively --- source/lib/StatusBoard/Incident.class.php | 6 +++--- source/lib/StatusBoard/IncidentStatus.class.php | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/lib/StatusBoard/Incident.class.php b/source/lib/StatusBoard/Incident.class.php index c32ab05..e7fb4d8 100644 --- a/source/lib/StatusBoard/Incident.class.php +++ b/source/lib/StatusBoard/Incident.class.php @@ -25,7 +25,7 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { $new_incident->actual_end_time = null; $new_incident->create(); - $new_incident->changeStatus($status, 'Initial Classification'); + $new_incident->changeStatus($status, 'Initial Classification', $start_time); return $new_incident; } @@ -159,12 +159,12 @@ class StatusBoard_Incident extends StatusBoard_DatabaseObject { return $this->statuses; } - public function changeStatus($status, $description) { + public function changeStatus($status, $description, $start_time = null) { if ($this->statuses === null) { $this->statuses = StatusBoard_IncidentStatus::allFor('incident', $this->id); } - $new_status = StatusBoard_IncidentStatus::newForIncident($this, $status, $description); + $new_status = StatusBoard_IncidentStatus::newForIncident($this, $status, $description, $start_time); $this->statuses[] = $new_status; return $new_status; diff --git a/source/lib/StatusBoard/IncidentStatus.class.php b/source/lib/StatusBoard/IncidentStatus.class.php index a95072c..f7ecf0b 100644 --- a/source/lib/StatusBoard/IncidentStatus.class.php +++ b/source/lib/StatusBoard/IncidentStatus.class.php @@ -14,12 +14,16 @@ class StatusBoard_IncidentStatus extends StatusBoard_DatabaseObject { return static::all_for('incident', $incident->id); } - public function newForIncident(StatusBoard_Incident $incident, $status, $description) { + public function newForIncident(StatusBoard_Incident $incident, $status, $description, $ctime = null) { + if ($ctime === null) { + $ctime = time(); + } + $new_status = new self(); $new_status->incident = $incident->id; $new_status->status = $status; $new_status->description = $description; - $new_status->ctime = time(); + $new_status->ctime = $ctime; $new_status->create(); From ad9a7a92c201fae98b3ec0c22e4d398485d6c258 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sat, 31 Dec 2011 16:38:05 +0000 Subject: [PATCH 137/142] Add config settings for recent Session enhancements --- build/schema/mysql.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/schema/mysql.sql b/build/schema/mysql.sql index 3a1562b..bf99125 100644 --- a/build/schema/mysql.sql +++ b/build/schema/mysql.sql @@ -44,7 +44,9 @@ INSERT INTO `settings` (`name`, `value`, `type`) VALUES ('logging.FlatFile.tmp.severity', 'debug\ninfo\nwarning\nerror', 'array(string)'), ('logging.FlatFile.tmp.category', 'webui\ndefault', 'array(string)'), ('templates.tmp_path', '/var/tmp/status-board/', 'string'), -('site.title', 'Status Board', 'string'); +('site.title', 'Status Board', 'string'), +('sessions', 1, 'bool'), +('sessions.path', '/', 'string'); -- -- Table structure for table `log` From 9d24b25555915fc19220ca0f6545ab150d592815 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Sat, 31 Dec 2011 16:41:15 +0000 Subject: [PATCH 138/142] Updated times to be 24hour Signed-off-by: Nathan Booth --- source/webui/templates/admin/incident.tpl | 2 +- source/webui/templates/incident.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/webui/templates/admin/incident.tpl b/source/webui/templates/admin/incident.tpl index 211fe60..c1849d3 100644 --- a/source/webui/templates/admin/incident.tpl +++ b/source/webui/templates/admin/incident.tpl @@ -104,7 +104,7 @@
    diff --git a/source/webui/templates/incident.tpl b/source/webui/templates/incident.tpl index 6aff016..4b4911b 100644 --- a/source/webui/templates/incident.tpl +++ b/source/webui/templates/incident.tpl @@ -42,7 +42,7 @@ From ea5bf05088f4113980526001ac4cb22e6e3c9416 Mon Sep 17 00:00:00 2001 From: Nathan Booth Date: Sat, 31 Dec 2011 16:55:45 +0000 Subject: [PATCH 139/142] fixed hour on admin/incident, added rounded corners to add incident Signed-off-by: Nathan Booth --- source/webui/templates/admin/add-incident.tpl | 197 +++++++++--------- source/webui/templates/incident.tpl | 2 +- 2 files changed, 100 insertions(+), 99 deletions(-) diff --git a/source/webui/templates/admin/add-incident.tpl b/source/webui/templates/admin/add-incident.tpl index 9e20ad6..cf507c7 100644 --- a/source/webui/templates/admin/add-incident.tpl +++ b/source/webui/templates/admin/add-incident.tpl @@ -1,103 +1,104 @@
    +
    -
    -

    Add Incident

    -

    Use this form to add a new incident

    -
    -
    - -
    -
    -
    - -
    - {if $service} - - {$service->name|escape:html} - {else} - - {/if} -
    -
    - -
    - -
    - {if $service && $site} - - {$site->name|escape:html} - {else} - - {/if} -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    -
    -
    - - -
    +
    +

    Add Incident

    +

    Use this form to add a new incident

    +
    +
    + +
    +
    +
    + +
    + {if $service} + + {$service->name|escape:html} + {else} + + {/if} +
    +
    + +
    + +
    + {if $service && $site} + + {$site->name|escape:html} + {else} + + {/if} +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    diff --git a/source/webui/templates/incident.tpl b/source/webui/templates/incident.tpl index 4b4911b..8ff9172 100644 --- a/source/webui/templates/incident.tpl +++ b/source/webui/templates/incident.tpl @@ -20,7 +20,7 @@

    Service: {$service->name|escape:html}

    Site: {$site->name|escape:html}

    -

    Opened: {$incident->start_time|date_format:'h:i d-M-y'}

    +

    Opened: {$incident->start_time|date_format:'H:i d-M-y'}

    Estimated End: {ucwords(StatusBoard_DateTime::fuzzyTime($incident->estimated_end_time))}

    From ddfce3be711b877b44564ffac153f16e1192cae9 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sun, 1 Jan 2012 22:37:15 +0000 Subject: [PATCH 140/142] Fix syntax in readme --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 373d052..e258c28 100755 --- a/README.md +++ b/README.md @@ -6,16 +6,16 @@ StatusBoard is a simple PHP web-based tool for displaying the status of services Features ------- -#Customisable list of Services and Sites. -#Manual reporting and status changes for Incidents. -#Multiple severity levels. -#Full admin UI. +*Customisable list of Services and Sites. +*Manual reporting and status changes for Incidents. +*Multiple severity levels. +*Full admin UI. Requirements ------------ -PHP -MYSQL -Smarty -sihnon-php-lib: https://github.com/optiz0r/sihnon-php-lib +*PHP +*MYSQL +*Smarty +*sihnon-php-lib: https://github.com/optiz0r/sihnon-php-lib From 1f41d571134e629d2dacca3deded2e5ee78f8ccb Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sun, 1 Jan 2012 22:38:32 +0000 Subject: [PATCH 141/142] Fix syntax in readme --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e258c28..dee1710 100755 --- a/README.md +++ b/README.md @@ -6,16 +6,16 @@ StatusBoard is a simple PHP web-based tool for displaying the status of services Features ------- -*Customisable list of Services and Sites. -*Manual reporting and status changes for Incidents. -*Multiple severity levels. -*Full admin UI. +* Customisable list of Services and Sites. +* Manual reporting and status changes for Incidents. +* Multiple severity levels. +* Full admin UI. Requirements ------------ -*PHP -*MYSQL -*Smarty -*sihnon-php-lib: https://github.com/optiz0r/sihnon-php-lib +* PHP +* MYSQL +* Smarty +* sihnon-php-lib: https://github.com/optiz0r/sihnon-php-lib From 706c5dbbfd2f0c020a0ec2d2a18750e3a811d8fb Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Sun, 1 Jan 2012 22:43:57 +0000 Subject: [PATCH 142/142] Version bump to 1.0.0_rc1 --- source/lib/StatusBoard/Main.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/StatusBoard/Main.class.php b/source/lib/StatusBoard/Main.class.php index 4d8c7b8..fcb677a 100644 --- a/source/lib/StatusBoard/Main.class.php +++ b/source/lib/StatusBoard/Main.class.php @@ -38,7 +38,7 @@ class StatusBoard_Main extends SihnonFramework_Main { $this->smarty->registerPlugin('modifier', 'formatFilesize', array('StatusBoard_Main', 'formatFilesize')); $this->smarty->registerPlugin('modifier', 'fuzzyTime', array('StatusBoard_DateTime', 'fuzzyTime')); - $this->smarty->assign('version', '0.1.0'); + $this->smarty->assign('version', '1.0.0_rc1'); $this->smarty->assign('version_codename', 'Acai'); $this->smarty->assign('messages', array());
    Statistic
    ServicesServices {$service_count}
    SitesSites {$site_count}
    IncidentsIncidents {array_sum(array_values($incident_counts))}
    MajorIncident StatisticsCount
    Major {$incident_counts[StatusBoard_Status::STATUS_Major]}
    {StatusBoard_DateTime::fuzzyTime($status->ctime)}
    - {$status->ctime|date_format:'y-m-d h:i:s'} + {$status->ctime|date_format:'y-m-d H:i:s'}
    {StatusBoard_Status::name($status->status)} {$status->description|escape:html}
    {ucwords(StatusBoard_DateTime::fuzzyTime($status->ctime))}
    - {$status->ctime|date_format:'h:i d-M-y'} + {$status->ctime|date_format:'H:i d-M-y'}
    {StatusBoard_Status::name($status->status)} {$status->description|escape:html}