From 93d1491aac54cbad1b278e4dc4cfcc040ed44cf4 Mon Sep 17 00:00:00 2001 From: thnilsen Date: Sun, 27 Sep 2020 14:01:54 +0200 Subject: [PATCH] Add functionality to services in backend. - Add functionallity to categorize a one or more services under one service group. Partial fix for #7 and #90. (Frontend code to be done) - Add description field to service to be displayed as a help text on front page. Partial fix for #51 (Frontend code to be done) --- admin/index.php | 12 ++- admin/service-group.php | 99 ++++++++++++++++++++++ admin/service.php | 97 ++++++++++++++++++++++ admin/settings.php | 93 ++++++++++++++++----- classes/constellation.php | 29 +++---- classes/service-group.php | 167 ++++++++++++++++++++++++++++++++++++++ classes/service.php | 45 +++++++++- install.sql | 12 +++ template.php | 3 +- 9 files changed, 515 insertions(+), 42 deletions(-) create mode 100644 admin/service-group.php create mode 100644 admin/service.php create mode 100644 classes/service-group.php diff --git a/admin/index.php b/admin/index.php index 274e286..345f89c 100644 --- a/admin/index.php +++ b/admin/index.php @@ -36,7 +36,7 @@ else{ define("PHP_MAILER_USER", $db->getSetting($mysqli, "php_mailer_user")); define("PHP_MAILER_PASS", $db->getSetting($mysqli, "php_mailer_pass")); define("CRON_SERVER_IP", $db->getSetting($mysqli, "cron_server_ip")); - + // Process the subscriber notification queue // If CRON_SERVER_IP is not set, call notification once incident has been saved if ( empty(CRON_SERVER_IP) ) @@ -110,6 +110,16 @@ else{ require_once("new-user.php"); break; + case 'new-service': + case 'edit-service': + require_once('service.php'); + break; + + case 'new-service-group': + case 'edit-service-group': + require_once('service-group.php'); + break; + case 'options': require_once("options.php"); break; diff --git a/admin/service-group.php b/admin/service-group.php new file mode 100644 index 0000000..23f3293 --- /dev/null +++ b/admin/service-group.php @@ -0,0 +1,99 @@ +prepare("SELECT * FROM services_groups WHERE id LIKE ?"); + $stmt->bind_param("i", $group_id); + $stmt->execute(); + $query = $stmt->get_result(); + $data = $query->fetch_assoc(); + $group_value = $data['name']; + $description_value = $data['description']; + $visibility_id_value = $data['visibility']; +} + + +if (!$boolEdit) { + +Template::render_header(_("New service group"), true); ?> +
+

+
+ +
+

+
+ + +
+ +

+ +
+
" class="form-control" required>
+
" class="form-control">
+
+
+
+ + +
+
+ '; + } + ?> + +
diff --git a/admin/service.php b/admin/service.php new file mode 100644 index 0000000..1f51d70 --- /dev/null +++ b/admin/service.php @@ -0,0 +1,97 @@ +prepare("SELECT * FROM services WHERE id LIKE ?"); + $stmt->bind_param("i", $service_id); + $stmt->execute(); + $query = $stmt->get_result(); + $data = $query->fetch_assoc(); + //print_r($data); + $service_value = $data['name']; + $description_value = $data['description']; + $group_id_value = $data['group_id']; +} + + +if (!$boolEdit) { + +Template::render_header(_("New service"), true); ?> +
+

+
+ +
+

+
+ +
+ +

+ +
+
" class="form-control" required>
+
" class="form-control">
+
+
+
+ + +
+
+ '; + } + ?> + +
diff --git a/admin/settings.php b/admin/settings.php index a3f58d8..bd93f10 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -1,12 +1,12 @@

Settings

-

@@ -24,19 +24,18 @@ if (isset($message)){ get_rank() <= 1){?>
- - - - +
- + - + + + get_rank()<=1) {?> @@ -44,16 +43,66 @@ if (isset($message)){ - query("SELECT * FROM services"); + query("SELECT services.*, services_groups.name AS group_name FROM `services` LEFT JOIN services_groups ON services.group_id = services_groups.id ORDER BY services.name ASC"); while($result = $query->fetch_assoc()) { echo ""; - echo ""; - echo ""; + //echo ""; + echo '"; + echo ""; + if ($user->get_rank()<=1) { - echo ''; + echo ''; + } + echo ""; + }?> + +
".$result['id']."".$result['name']."".$result['id']."'.$result['name'].''; + echo "".$result['description']."".$result['group_name']."
+
+ + +
+

+ get_rank() <= 1){?> +
+
+ +
+
+ +
+ + + + + + + + + get_rank()<=1) + {?> + + + + + + query("SELECT sg.* , (SELECT COUNT(*) FROM services WHERE services.group_id = sg.id) AS counter FROM services_groups AS sg ORDER BY sg.id ASC"); + while($result = $query->fetch_assoc()) + { + echo ""; + //echo ""; + echo '"; + echo ""; + + if ($user->get_rank()<=1) + { + echo ''; } echo ""; }?> @@ -68,10 +117,10 @@ if (isset($message)){ get_rank() == 0){?>
".$result['id']."'.$result['name'].''; + echo ' '.$result['counter'].''; + echo "".$result['description']."".$visibility[$result['visibility']]."
- + - query("SELECT * FROM users"); while($result = $query->fetch_assoc()) { @@ -89,4 +138,4 @@ if (isset($message)){
Active
-
\ No newline at end of file + diff --git a/classes/constellation.php b/classes/constellation.php index c4fc58e..b8b7b16 100644 --- a/classes/constellation.php +++ b/classes/constellation.php @@ -2,6 +2,7 @@ //DIR Because of include problems require_once(__DIR__ . "/incident.php"); require_once(__DIR__ . "/service.php"); +require_once(__DIR__ . "/service-group.php"); require_once(__DIR__ . "/user.php"); require_once(__DIR__ . "/token.php"); /** @@ -20,7 +21,7 @@ class Constellation public function render_incidents($future=false, $offset=0, $limit = 5, $admin = 0){ if ($offset<0) { - $offset = 0; + $offset = 0; } $limit = (isset($_GET['limit'])?$_GET['limit']:5); @@ -37,7 +38,7 @@ class Constellation } else if (count($incidents["incidents"]) &&!$ajax) { - if ($offset) + if ($offset) { echo ''; } @@ -66,11 +67,11 @@ class Constellation /** * Renders service status - in admin page it returns array so it can be processed further. * @param boolean $admin - * @return array of services + * @return array of services */ public function render_status($admin = false, $heading = true){ global $mysqli; - + $query = $mysqli->query("SELECT id, name FROM services"); $array = array(); if ($query->num_rows){ @@ -91,7 +92,7 @@ class Constellation else{ $array[] = new Service($result['id'], $result['name']); } - } + } if ($heading) { echo Service::current_status($array); @@ -131,14 +132,14 @@ class Constellation $limit--; $more = false; if ($query->num_rows>$limit){ - $more = true; + $more = true; } if ($query->num_rows){ while(($result = $query->fetch_assoc()) && $limit-- > 0) { // Add service id and service names to an array in the Incident class - $stmt_service = $mysqli->prepare("SELECT services.id,services.name FROM services - INNER JOIN services_status ON services.id = services_status.service_id + $stmt_service = $mysqli->prepare("SELECT services.id,services.name FROM services + INNER JOIN services_status ON services.id = services_status.service_id WHERE services_status.status_id = ?"); $stmt_service->bind_param("i", $result['status_id']); $stmt_service->execute(); @@ -156,17 +157,17 @@ class Constellation "incidents" => $array ]; } - - + + function render_warning($header, $message, $show_link = false, $url = null, $link_text = null) { - $this->render_alert('alert-warning', $header, $message, $show_link, $url, $link_text); + $this->render_alert('alert-warning', $header, $message, $show_link, $url, $link_text); } function render_success($header, $message, $show_link = false, $url = null, $link_text = null) { $this->render_alert('alert-success', $header, $message, $show_link, $url, $link_text); } - + /** * Renders an alert on screen with an optional button to return to a given URL * @param string alert_type - Type of warning to render alert-danger, alert-warning, alert-success etc @@ -188,8 +189,8 @@ class Constellation if ( $show_link ) { echo '
'.$link_text.'
'; } - + } } -$constellation = new Constellation(); \ No newline at end of file +$constellation = new Constellation(); diff --git a/classes/service-group.php b/classes/service-group.php new file mode 100644 index 0000000..933571a --- /dev/null +++ b/classes/service-group.php @@ -0,0 +1,167 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->visibility_id = $visibility_id; + $this->status = $status; + } + + /** + * Returns id of this servicegroup + * @return int id + */ + public function get_id() + { + return $this->id; + } + + /** + * Returns name of this servicegroup + * @return String name + */ + public function get_name() + { + return $this->name; + } + + /** + * Returns description of this servicegroup + * @return String description + */ + public function get_description() + { + return $this->description; + } + + /** + * Processes submitted form and adds service unless problem is encountered, + * calling this is possible only for admin or higher rank. Also checks requirements + * for char limits. + * @return void + */ + public static function add() + { + global $user, $message; + if (strlen($_POST['group'])>50) + { + $message = _("Service group name is too long! Character limit is 50"); + return; + }else if (strlen(trim($_POST['group']))==0){ + $message = _("Please enter name!"); + return; + } + + if ($user->get_rank()<=1) + { + global $mysqli; + $name = $_POST["group"]; + $description = $_POST["description"]; + $visibility_id = $_POST["visibility_id"]; + $stmt = $mysqli->prepare("INSERT INTO services_groups VALUES(NULL,?,?,?)"); + $stmt->bind_param("ssi", $name, $description, $visibility_id); + $stmt->execute(); + $stmt->get_result(); + header("Location: ".WEB_URL."/admin/?do=settings"); + }else + { + $message = _("You don't have the permission to do that!"); + } + } + + public static function edit() + { + global $user, $message; + if (strlen($_POST['group'])>50) + { + $message = _("Service group name is too long! Character limit is 50"); + return; + }else if (strlen(trim($_POST['group']))==0){ + $message = _("Please enter name!"); + return; + } + + if ($user->get_rank()<=1) + { + global $mysqli; + $name = $_POST["group"]; + $description = $_POST["description"]; + $visibility_id = $_POST["visibility_id"]; + $group_id = $_POST["id"]; + $stmt = $mysqli->prepare("UPDATE services_groups SET name=?, description=?,visibility=? WHERE id LIKE ?"); + $stmt->bind_param("ssii", $name, $description, $visibility_id, $group_id); + $stmt->execute(); + $stmt->get_result(); + header("Location: ".WEB_URL."/admin/?do=settings"); + }else + { + $message = _("You don't have the permission to do that!"); + } + } + /** + * Deletes this service - first checks if user has permission to do that. + * @return void + */ + public static function delete() + { + global $user, $message; + if ($user->get_rank()<=1) + { + global $mysqli; + $id = $_GET['delete']; + + $stmt = $mysqli->prepare("DELETE FROM services_groups WHERE id = ?"); + $stmt->bind_param("i", $id); + $stmt->execute(); + $query = $stmt->get_result(); + + $stmt = $mysqli->prepare("UPDATE services SET group_id = NULL WHERE group_id = ?"); + $stmt->bind_param("i", $id); + $stmt->execute(); + $query = $stmt->get_result(); + + header("Location: ".WEB_URL."/admin/?do=settings"); + } + else + { + $message = _("You don't have the permission to do that!"); + } + } + + + /** + * Get list of services groups. + * @return array $groups + */ + public function get_groups() { + global $mysqli; + $stmt = $mysqli->query("SELECT id, name FROM services_groups ORDER by name ASC"); + + $groups = array(); + $groups[0] = ''; + while ($res = $stmt->fetch_assoc()) { + $groups[$res['id']] = $res['name']; + } + return $groups; + } +} diff --git a/classes/service.php b/classes/service.php index ae1ca94..d86383b 100644 --- a/classes/service.php +++ b/classes/service.php @@ -70,9 +70,11 @@ class Service implements JsonSerializable if ($user->get_rank()<=1) { global $mysqli; - $name = $_POST['service']; - $stmt = $mysqli->prepare("INSERT INTO services ( name ) VALUES ( ? )"); - $stmt->bind_param("s", $name); + $name = htmlspecialchars($_POST['service']); + $description = htmlspecialchars($_POST['description']); + $group_id = $_POST['group_id']; + $stmt = $mysqli->prepare("INSERT INTO services ( name, description, group_id ) VALUES ( ?, ?, ? )"); + $stmt->bind_param("ssi", $name, $description, $group_id); $stmt->execute(); $stmt->get_result(); header("Location: ".WEB_URL."/admin/?do=settings"); @@ -81,6 +83,41 @@ class Service implements JsonSerializable $message = _("You don't have the permission to do that!"); } } + /** + * Processes submitted form and adds service unless problem is encountered, + * calling this is possible only for admin or higher rank. Also checks requirements + * for char limits. + * @return void + */ + public static function edit() + { + global $user, $message; + if (strlen($_POST['service'])>50) + { + $message = _("Service name is too long! Character limit is 50"); + return; + }else if (strlen(trim($_POST['service']))==0){ + $message = _("Please enter name!"); + return; + } + + if ($user->get_rank()<=1) + { + global $mysqli; + $service_id = $_POST["id"]; + $name = htmlspecialchars($_POST['service']); + $description = htmlspecialchars($_POST["description"]); + $group_id = $_POST["group_id"]; + $stmt = $mysqli->prepare("UPDATE services SET name=?, description=?, group_id=? WHERE id = ?"); + $stmt->bind_param("ssii", $name, $description, $group_id, $service_id); + $stmt->execute(); + $stmt->get_result(); + header("Location: ".WEB_URL."/admin/?do=settings"); + }else + { + $message = _("You don't have the permission to do that!"); + } + } /** * Deletes this service - first checks if user has permission to do that. @@ -139,7 +176,7 @@ class Service implements JsonSerializable { $worst = $service->get_status(); } - $statuses[$service->get_status()]++; + $statuses[$service->get_status()]++; } echo '
'; diff --git a/install.sql b/install.sql index 8432510..cd3b013 100644 --- a/install.sql +++ b/install.sql @@ -57,6 +57,14 @@ CREATE TABLE queue_notify ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +CREATE TABLE services_groups ( + id int(11) NOT NULL AUTO_INCREMENT, + name varchar(50) NOT NULL, + description varchar(50) DEFAULT NULL, + visibility tinyint(4) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + CREATE TABLE queue_task ( id int(11) NOT NULL AUTO_INCREMENT, type_id int(11) NOT NULL, @@ -128,3 +136,7 @@ ALTER TABLE `subscribers` ADD COLUMN update_time int(11) DEFAULT NULL; ALTER TABLE `subscribers` DROP INDEX telegramID; # was UNIQUE (telegramID) ALTER TABLE `subscribers` ADD UNIQUE userID (userID); COMMIT; + +ALTER TABLE services ADD COLUMN description varchar(200) COLLATE utf8_czech_ci NOT NULL; +ALTER TABLE services ADD COLUMN group_id int(11) DEFAULT NULL; +COMMIT; diff --git a/template.php b/template.php index 5d0d1e7..b66b8dc 100644 --- a/template.php +++ b/template.php @@ -7,6 +7,7 @@ $icons = array("fa fa-times", "fa fa-exclamation", "fa fa-info", "fa fa-check" ) $some = array(_("Some systems are experiencing major outages"), _("Some systems are experiencing minor outages"), _("Some systems are under maintenance")); $all = array(_("Our systems are experiencing major outages."), _("Our systems are experiencing minor outages"), _("Our systems are under maintenance"), _("All systems operational")); $permissions = array(_("Super admin"), _("Admin"), _("Editor")); +$visibility = array(_("Collapsed"), _("Expanded"), _("Expand on events")); /** * Class that encapsulates methods to render header and footer @@ -56,7 +57,7 @@ class Template{ -