diff --git a/src/lang/bg_BG.lang.php b/src/lang/bg_BG.lang.php index f657e57a..7e4a3463 100644 --- a/src/lang/bg_BG.lang.php +++ b/src/lang/bg_BG.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Настройки', 'server' => 'Сървъри', - 'server_history' => 'History', 'server_log' => 'Логове', 'server_status' => 'Статус', 'server_update' => 'Обнови данните', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'SMS', 'updated' => 'Информацията за сървъра е обновена.', 'inserted' => 'Сървърът е добвен успешно.', - 'rtime' => 'Пинг', + 'latency' => 'Пинг', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%d.%m.%Y', 'chart_long_date_format' => '%d.%m.%Y %H:%M:%S', 'chart_short_date_format' => '%d.%m %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/de_DE.lang.php b/src/lang/de_DE.lang.php index fb589bbb..bd604b75 100644 --- a/src/lang/de_DE.lang.php +++ b/src/lang/de_DE.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Einstellungen', 'server' => 'Server', - 'server_history' => 'History', 'server_log' => 'Log', 'server_status' => 'Status', 'server_update' => 'Updates', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'SMS', 'updated' => 'Server aktualisiert.', 'inserted' => 'Server eingetragen.', - 'rtime' => 'Antwortzeit', + 'latency' => 'Antwortzeit', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%d.%m.%Y', 'chart_long_date_format' => '%d.%m.%Y %H:%M:%S', 'chart_short_date_format' => '%d.%m %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index 8399e9a4..fe0faf9e 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Config', 'server' => 'Servers', - 'server_history' => 'History', 'server_log' => 'Log', 'server_status' => 'Status', 'server_update' => 'Update', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'Send SMS', 'updated' => 'Server updated.', 'inserted' => 'Server added.', - 'rtime' => 'Response time', + 'latency' => 'Latency', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%Y-%m-%d', 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/fr_FR.lang.php b/src/lang/fr_FR.lang.php index 6d6a27cb..ccafeaab 100644 --- a/src/lang/fr_FR.lang.php +++ b/src/lang/fr_FR.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Configuration', 'server' => 'Serveurs', - 'server_history' => 'Historique', 'server_log' => 'Événements', 'server_status' => 'États', 'server_update' => 'Mise à jour', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'Envoyer un SMS', 'updated' => 'Serveur mis à jour.', 'inserted' => 'Serveur ajouté.', - 'rtime' => 'Temps de réponse', + 'latency' => 'Temps de réponse', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Mois', 'week' => 'Semaine', 'day' => 'Jour', 'hour' => 'Heure', 'warning_threshold' => 'Seuil d\'alerte', 'warning_threshold_description' => 'Nombre d\'échecs de connexion avant que le serveur soit marqué hors-service.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%d/%m/%Y', 'chart_long_date_format' => '%d/%m/%Y %H:%M:%S', 'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/ko_KR.lang.php b/src/lang/ko_KR.lang.php index 08879fa3..8ab9bc86 100644 --- a/src/lang/ko_KR.lang.php +++ b/src/lang/ko_KR.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => '설정', 'server' => '서버목록', - 'server_history' => 'History', 'server_log' => '로그', 'server_status' => 'Status', 'server_update' => '업데이트', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'SMS 전송', 'updated' => '서버가 수정되었습니다.', 'inserted' => '서버가 추가되었습니다.', - 'rtime' => '응답', + 'latency' => '응답', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%Y-%m-%d', 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/nl_NL.lang.php b/src/lang/nl_NL.lang.php index 93c5e628..6d437354 100644 --- a/src/lang/nl_NL.lang.php +++ b/src/lang/nl_NL.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Config', 'server' => 'Servers', - 'server_history' => 'Geschiedenis', 'server_log' => 'Log', 'server_status' => 'Status', 'server_update' => 'Update', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'Stuur SMS', 'updated' => 'Server gewijzigd.', 'inserted' => 'Server toegevoegd.', - 'rtime' => 'Response tijd', + 'latency' => 'Response tijd', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Aantal mislukte pogingen voordat de server als offline gemarkeerd wordt.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%d-%m-%Y', 'chart_long_date_format' => '%d-%m-%Y %H:%M:%S', 'chart_short_date_format' => '%d-%m %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/lang/pt_BR.lang.php b/src/lang/pt_BR.lang.php index a14d4559..69cbb4d8 100644 --- a/src/lang/pt_BR.lang.php +++ b/src/lang/pt_BR.lang.php @@ -61,7 +61,6 @@ $sm_lang = array( 'menu' => array( 'config' => 'Configuração', 'server' => 'Servidores', - 'server_history' => 'History', 'server_log' => 'Log', 'server_status' => 'Status', 'server_update' => 'Atualização', @@ -119,15 +118,21 @@ $sm_lang = array( 'send_sms' => 'Enviar SMS', 'updated' => 'Servidor atualizado.', 'inserted' => 'Servidor adicionar.', - 'rtime' => 'Tempo de resposta', + 'latency' => 'Tempo de resposta', + 'latency_max' => 'Latency (maximum)', + 'latency_min' => 'Latency (minimum)', + 'latency_avg' => 'Latency (average)', + 'year' => 'Year', 'month' => 'Month', 'week' => 'Week', 'day' => 'Day', 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', - + 'chart_last_week' => 'Last week', + 'chart_history' => 'History', // Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html + 'chart_day_format' => '%d/%m/%Y', 'chart_long_date_format' => '%d/%m/%Y %H:%M:%S', 'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_time_format' => '%H:%M', diff --git a/src/psm/Module/AbstractController.class.php b/src/psm/Module/AbstractController.class.php index e8488c60..175dbe62 100644 --- a/src/psm/Module/AbstractController.class.php +++ b/src/psm/Module/AbstractController.class.php @@ -31,13 +31,6 @@ use psm\Service\Template; abstract class AbstractController implements ControllerInterface { - /** - * Current mode. Can be used by modules to determine - * what to do - * @var string $mode - */ - public $mode; - /** * Current action * @var string $action @@ -234,10 +227,10 @@ abstract class AbstractController implements ControllerInterface { switch($ulvl) { case PSM_USER_ADMIN: - $items = array('server', 'server_status', 'server_history', 'server_log', 'user', 'config', 'server_update'); + $items = array('server', 'server_status', 'server_log', 'user', 'config', 'server_update'); break; case PSM_USER_USER: - $items = array('server', 'server_status', 'server_history', 'server_log', 'server_update'); + $items = array('server', 'server_status', 'server_log', 'server_update'); break; default: $items = array(); diff --git a/src/psm/Module/Server/Controller/AbstractServerController.class.php b/src/psm/Module/Server/Controller/AbstractServerController.class.php index d29fcb67..23a63ca9 100644 --- a/src/psm/Module/Server/Controller/AbstractServerController.class.php +++ b/src/psm/Module/Server/Controller/AbstractServerController.class.php @@ -77,8 +77,4 @@ abstract class AbstractServerController extends AbstractController { return $servers; } - - public function getServerUptime($server_id) { - return $this->db->select(PSM_DB_PREFIX.'servers_uptime' , "server_id=$server_id", null, '', 'date'); - } } \ No newline at end of file diff --git a/src/psm/Module/Server/Controller/HistoryController.class.php b/src/psm/Module/Server/Controller/HistoryController.class.php deleted file mode 100644 index 24bac648..00000000 --- a/src/psm/Module/Server/Controller/HistoryController.class.php +++ /dev/null @@ -1,134 +0,0 @@ -. - * - * @package phpservermon - * @author Pepijn Over - * History module : Jérôme Cabanis - * @copyright Copyright (c) 2008-2014 Pepijn Over - * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 - * @version Release: @package_version@ - * @link http://www.phpservermonitor.org/ - **/ - -namespace psm\Module\Server\Controller; -use psm\Service\Database; -use psm\Service\Template; - -/** - * History module. Create the page to view server history - */ -class HistoryController extends AbstractServerController { - - function __construct(Database $db, Template $tpl) { - parent::__construct($db, $tpl); - - $this->setActions('index', 'index'); - } - - /** - * Prepare the template with a list of all log entries - */ - protected function executeIndex() { - $this->setTemplateId('history_list', 'history.tpl.html'); - - // get the active servers from database - $servers = $this->getServers(); - - $data = array(); - foreach ($servers as $server) { - if($server['active'] == 'no') { - continue; - } - - $server_id = $server['server_id']; - $uptimes = $this->getServerUptime($server_id); - $last_date = 0; - $last_status = 0; - // Create the list of points and server down zones - $line = array(); - $lines = array(); - $down = array(); - foreach ($uptimes as $uptime) { - $time = strtotime($uptime['date']) * 1000; - if($uptime['status']) { - // The server is up - $line[] = '[' . $time . ',' . round((float)$uptime['latency'], 3) . ']'; - if($last_date) { - // Was down before. - // Record the first and last date as a string in the down array - $down[] = '[' . $last_date . ',' . $time . ']'; - $last_date = 0; - } - $last_status = 1; - } - else { - // The server is down - if($last_status) { - // If was up before, record la line as string in the lines array - $lines[] = '[' . implode(',', $line) . ']'; - $line = array(); - $last_status = 0; - } - if(!$last_date) { - $last_date = $time; - } - } - } - if($last_status) { - $lines[] = '[' . implode(',', $line) . ']'; - } - if($last_date) { - $down[] = '[' . $last_date . ',0]'; - } - $data[] = array( - 'server_id' => $server_id, - 'server_name' => $server['label'], - 'server_lines' => sizeof($lines) ? '[' . implode(',', $lines) . ']' : '', - 'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '', - 'server_online' => psm_date($server['last_online']), - 'server_rtime' => round((float)$server['rtime'], 3), - ); - } - - $this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $data); - } - - - // override parent::createHTMLLabels() - protected function createHTMLLabels() { - $this->tpl->addTemplateData( - $this->getTemplateId(), - array( - 'subtitle' => psm_get_lang('menu', 'server_history'), - 'label_server' => psm_get_lang('servers', 'server'), - 'label_last_online' => psm_get_lang('servers', 'last_online'), - 'label_rtime' => psm_get_lang('servers', 'rtime'), - 'label_month' => psm_get_lang('servers', 'month'), - 'label_week' => psm_get_lang('servers', 'week'), - 'label_day' => psm_get_lang('servers', 'day'), - 'label_hour' => psm_get_lang('servers', 'hour'), - 'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'), - 'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'), - 'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'), - ) - ); - - return parent::createHTMLLabels(); - } -} \ No newline at end of file diff --git a/src/psm/Module/Server/Controller/ServerController.class.php b/src/psm/Module/Server/Controller/ServerController.class.php index 7abc91c7..6d8fbcf1 100644 --- a/src/psm/Module/Server/Controller/ServerController.class.php +++ b/src/psm/Module/Server/Controller/ServerController.class.php @@ -38,7 +38,7 @@ class ServerController extends AbstractServerController { parent::__construct($db, $tpl); $this->setActions(array( - 'index', 'edit', 'save', 'delete', + 'index', 'edit', 'save', 'delete', 'view', ), 'index'); // make sure only admins are allowed to edit/delete servers: @@ -89,23 +89,12 @@ class ServerController extends AbstractServerController { // will also be replaced in the html_actions template itself $servers[$x] = $html_actions + $servers[$x]; $servers[$x]['class'] = ($x & 1) ? 'odd' : 'even'; - $servers[$x]['rtime'] = round((float) $servers[$x]['rtime'], 4); - $servers[$x]['last_online'] = psm_date($servers[$x]['last_online']); - $servers[$x]['last_check'] = psm_date($servers[$x]['last_check']); - $servers[$x]['active'] = psm_get_lang('system', $servers[$x]['active']); - $servers[$x]['email'] = psm_get_lang('system', $servers[$x]['email']); - $servers[$x]['sms'] = psm_get_lang('system', $servers[$x]['sms']); + $servers[$x] = $this->formatServer($servers[$x]); if($servers[$x]['type'] == 'website') { // add link to label $servers[$x]['ip'] = ''.$servers[$x]['ip'].''; } - - if($servers[$x]['status'] == 'on' && $servers[$x]['warning_threshold_counter'] > 0) { - $servers[$x]['status'] = 'warning'; - } - - $servers[$x]['type'] = psm_get_lang('servers', 'type_' . $servers[$x]['type']); } // add servers to template $this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $servers); @@ -156,7 +145,7 @@ class ServerController extends AbstractServerController { array('server_id' => $server_id) ); if (empty($edit_server)) { - $this->addMessage('Invalid server id', 'error'); + $this->addMessage('Invalid server', 'error'); return $this->initializeAction('index'); } @@ -242,6 +231,85 @@ class ServerController extends AbstractServerController { $this->initializeAction('index'); } + /** + * Prepare the view template + */ + protected function executeView() { + $this->setTemplateId('server_view', 'server/view.tpl.html'); + $server_id = isset($_GET['id']) ? intval($_GET['id']) : 0; + + // get server entry + $server = $this->db->selectRow( + PSM_DB_PREFIX.'servers', + array('server_id' => $server_id) + ); + if (empty($server)) { + $this->addMessage('Invalid server', 'error'); + return $this->initializeAction('index'); + } + + $sidebar = new \psm\Util\Module\Sidebar($this->tpl); + $this->setSidebar($sidebar); + $sidebar->setSubtitle($server['label']); + + if($this->user->getUserLevel() == PSM_USER_ADMIN) { + $sidebar->addLink( + 'edit', + psm_get_lang('system', 'edit'), + psm_build_url(array('mod' => 'server', 'action' => 'edit', 'id' => $server_id)), + 'edit' + ); + $sidebar->addLink( + 'delete', + psm_get_lang('system', 'delete'), + "javascript:sm_delete('{$server_id}', 'server');", + 'remove' + ); + } + $sidebar->addLink( + 'go_back', + psm_get_lang('system', 'go_back'), + psm_build_url(array('mod' => 'server')), + 'th-list' + ); + + $tpl_data = $this->formatServer($server); + $history = new \psm\Util\Server\HistoryGraph($this->db, $this->tpl); + $tpl_data['html_history'] = $history->createHTML($server_id); + + $this->tpl->addTemplateData( + $this->getTemplateId(), + $tpl_data + ); + } + + /** + * Format server data for display + * @param array $server + * @return array + */ + protected function formatServer($server) { + $server['rtime'] = round((float) $server['rtime'], 4); + $server['last_online'] = psm_timespan($server['last_online']); + $server['last_check'] = psm_timespan($server['last_check']); + $server['active'] = psm_get_lang('system', $server['active']); + $server['email'] = psm_get_lang('system', $server['email']); + $server['sms'] = psm_get_lang('system', $server['sms']); + $server['url_view'] = psm_build_url(array( + 'mod' => 'server', + 'action' => 'view', + 'id' => $server['server_id'], + )); + + if($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) { + $server['status'] = 'warning'; + } + + $server['type'] = psm_get_lang('servers', 'type_' . $server['type']); + + return $server; + } + // override parent::createHTMLLabels() protected function createHTMLLabels() { $this->tpl->addTemplateData( @@ -258,7 +326,7 @@ class ServerController extends AbstractServerController { 'label_pattern' => psm_get_lang('servers', 'pattern'), 'label_pattern_description' => psm_get_lang('servers', 'pattern_description'), 'label_last_check' => psm_get_lang('servers', 'last_check'), - 'label_rtime' => psm_get_lang('servers', 'rtime'), + 'label_rtime' => psm_get_lang('servers', 'latency'), 'label_last_online' => psm_get_lang('servers', 'last_online'), 'label_monitoring' => psm_get_lang('servers', 'monitoring'), 'label_send_email' => psm_get_lang('servers', 'send_email'), diff --git a/src/psm/Module/Server/Controller/StatusController.class.php b/src/psm/Module/Server/Controller/StatusController.class.php index fe1fdb52..5fa5b6ca 100644 --- a/src/psm/Module/Server/Controller/StatusController.class.php +++ b/src/psm/Module/Server/Controller/StatusController.class.php @@ -65,7 +65,7 @@ class StatusController extends AbstractServerController { 'warning_fg' => '#F3F3B1', 'label_last_check' => psm_get_lang('servers', 'last_check'), 'label_last_online' => psm_get_lang('servers', 'last_online'), - 'label_rtime' => psm_get_lang('servers', 'rtime'), + 'label_rtime' => psm_get_lang('servers', 'latency'), ); $this->tpl->addTemplateData($this->getTemplateId(), $tpl_data); @@ -75,6 +75,7 @@ class StatusController extends AbstractServerController { } $server['last_checked_nice'] = psm_timespan($server['last_check']); $server['last_online_nice'] = psm_timespan($server['last_online']); + $server['url_view'] = psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server['server_id'])); if ($server['status'] == "off") { $offline[$server['server_id']] = $server; diff --git a/src/psm/Module/Server/ServerModule.class.php b/src/psm/Module/Server/ServerModule.class.php index 4eae4c9d..2055192f 100644 --- a/src/psm/Module/Server/ServerModule.class.php +++ b/src/psm/Module/Server/ServerModule.class.php @@ -33,7 +33,6 @@ class ServerModule implements ModuleInterface { public function getControllers() { return array( 'server' => __NAMESPACE__ . '\Controller\ServerController', - 'history' => __NAMESPACE__ . '\Controller\HistoryController', 'log' => __NAMESPACE__ . '\Controller\LogController', 'status' => __NAMESPACE__ . '\Controller\StatusController', 'update' => __NAMESPACE__ . '\Controller\UpdateController', diff --git a/src/psm/Service/Template.class.php b/src/psm/Service/Template.class.php index 39c661b3..3bcd72d0 100644 --- a/src/psm/Service/Template.class.php +++ b/src/psm/Service/Template.class.php @@ -114,54 +114,100 @@ class Template { } /** - * Add repeat rows to template + * Add repeat rows to template. + * It's possible to create a nested repeat tpl. All you need to do is to create a subarray + * For example: + * $data = array( + * 0 => array( + * 'name' => 'Test', + * 'subdata' => array( + * 0 => array( + * 'name' => 'Subtest 1', + * ), + * 1 => array(...) + * ), + * ), + * ); + * In your template you would literally put the nested repeat inside the first repeat. + * If you have more than 1 nested array, the first subtemplate will be used for all others. * - * @param string $id template id used by add_template() + * @param string $id template id used by add_template() or html code in case of repeat-repeat tpl * @param string $repeat_id ID used in template file for the repeat template: html * @param array $data + * @param boolean $use_html can only be used from within this function for recursive repeat templating. in this case the $id is the html code + * @param int $level starts off with 0. if level=2, current repeat template will be used again for subs, so you can go all the way + * @param int $level_reuse_prev from what level should we start repeating the current template for more subrecords, so we can go all the way? * @return mixed false if repeat template cannot be found, html code on success */ - public function addTemplateDataRepeat($id, $repeat_id, $data) { - // does the template exist? - if (!isset($this->templates[$id])) { - // file does not exist - trigger_error('Template not found with id: '.$id); - return false; + public function addTemplateDataRepeat($tpl_id, $repeat_id, $data, $use_html = false, $level = 0, $level_reuse_prev = 2) { + if($use_html) { + $source = $tpl_id; + } else { + // does the template exist? + if (!isset($this->templates[$tpl_id])) { + // file does not exist + trigger_error("Template '{$tpl_id}' could not be found", E_USER_WARNING); + return false; + } + $source =& $this->templates[$tpl_id]; } - $use_tpl = null; + if($level < $level_reuse_prev) { + // find "tpl_repeat_{$repeat_id}_" in the current template + preg_match_all("{(.*?)}is", $source, $matches); - // find "tpl_repeat_{$repeat_id}_" in the current template - //preg_match_all('{(.*?)}is', $this->templates[$id], $matches); - preg_match_all("{(.*?)}is", $this->templates[$id], $matches); + // check if the repeat_id is in one of the matches + if (isset($matches[1][0])) { + $use_tpl = $matches[1][0]; + } else { + // if we didn't find a repeat template for the repeat_id supplied, skip the rest.. + return false; + } - // no repeat tpl found? skip to next one - if (empty($matches)) return false; - - // check if the row_id is in one of the matches (aka whether the supplied row id actually has a repeat template in this file) - if (isset($matches[1][0])) { - $use_tpl = $matches[1][0]; + // remove repeat tpl code from original template so it won't be in the source + $source = preg_replace("{(.*?)}is", "", $source); + } else { + $use_tpl = $source; } - - // if we didn't find a repeat template for the row_id supplied, skip the rest.. - if ($use_tpl === null) return false; - - // remove repeat tpl code from original template so it won't be in the source - $this->templates[$id] = preg_replace("{(.*?)}is", "", $this->templates[$id]); - // now lets go through all the records supplied and put them in the HTML repeat code we just found $result = ''; foreach($data as $record) { $tmp_string = $use_tpl; - foreach($record as $k => $v) { - $tmp_string = str_replace('{'.$k.'}', $v, $tmp_string); + + if(!is_array($record)) { + $record = array( + 'value' => $record, + ); } - $result .= $tmp_string."\n"; + + // multi dim array + foreach($record as $k => $v) { + if(is_array($v)) { + // nested repeat + if(isset($v[0]) && is_array($v[0])) { + // repeat template in a repeat template + $repeat_html = $this->addTemplateDataRepeat($use_tpl, $k, $v, true, ($level + 1), $level_reuse_prev); + $tmp_string = str_replace('{'.$k.'}', $repeat_html, $tmp_string); + } else { + foreach($v as $vk => $vv) { + $tmp_string = str_replace('{'.$k.'_'.$vk.'}', $vv, $tmp_string); + } + } + } else { + $tmp_string = str_replace('{'.$k.'}', $v, $tmp_string); + } + } + + $result .= $tmp_string.PHP_EOL; } - // add to main template.. - return $this->addTemplateData($id, array($repeat_id => $result)); + if($use_html === false) { + // add to main template.. + return $this->addTemplateData($tpl_id, array($repeat_id => $result)); + } else { + return $result; + } } public function display($id) { diff --git a/src/psm/Util/Module/Sidebar.class.php b/src/psm/Util/Module/Sidebar.class.php index 04b34d53..7174966b 100644 --- a/src/psm/Util/Module/Sidebar.class.php +++ b/src/psm/Util/Module/Sidebar.class.php @@ -43,6 +43,13 @@ class Sidebar implements SidebarInterface { */ protected $items = array(); + /** + * Custom subtitle + * @var string $subtitle + * @see setSubtitle() + */ + protected $subtitle; + /** * Template service * @var \psm\Service\Template $tpl @@ -63,6 +70,16 @@ class Sidebar implements SidebarInterface { return $this; } + /** + * Set a custom subtitle (default is module subitle) + * @param string $title + * @return \psm\Util\Moduke\Sidebar + */ + public function setSubtitle($title) { + $this->subtitle = $title; + return $this; + } + /** * Add new link to sidebar * @param string $id @@ -114,6 +131,11 @@ class Sidebar implements SidebarInterface { if(!empty($items)) { $this->tpl->addTemplateDataRepeat($tpl_id, 'items', $items); } + if($this->subtitle !== null) { + $this->tpl->addTemplateData($tpl_id, array( + 'subtitle' => $this->subtitle, + )); + } $html = $this->tpl->getTemplate($tpl_id); diff --git a/src/psm/Util/Server/HistoryGraph.class.php b/src/psm/Util/Server/HistoryGraph.class.php new file mode 100644 index 00000000..48d0fea1 --- /dev/null +++ b/src/psm/Util/Server/HistoryGraph.class.php @@ -0,0 +1,221 @@ +. + * + * @package phpservermon + * @author Jérôme Cabanis + * Pepijn Over + * @copyright Copyright (c) 2008-2014 Pepijn Over + * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 + * @version Release: @package_version@ + * @link http://www.phpservermonitor.org/ + **/ + +namespace psm\Util\Server; +use psm\Service\Database; +use psm\Service\Template; + +/** + * History util, create HTML for server graphs + */ +class HistoryGraph { + + /** + * Database service + * @var \psm\Service\Database $db; + */ + protected $db; + + /** + * Template service + * @var \psm\Service\Template $tpl + */ + protected $tpl; + + function __construct(Database $db, Template $tpl) { + $this->db = $db; + $this->tpl = $tpl; + } + + /** + * Prepare the HTML for the graph + * @return string + */ + public function createHTML($server_id) { + $tpl_id = 'server_history'; + $this->tpl->newTemplate($tpl_id, 'server/history.tpl.html'); + + $graphs = array( + 0 => $this->generateGraphUptime($server_id), + 1 => $this->generateGraphHistory($server_id), + ); + $this->tpl->addTemplateDataRepeat($tpl_id, 'graphs', $graphs); + + $this->tpl->addTemplateData( + $tpl_id, + array( + 'label_server' => psm_get_lang('servers', 'server'), + 'label_latency_avg' => psm_get_lang('servers', 'latency_avg'), + 'day_format' => psm_get_lang('servers', 'chart_day_format'), + 'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'), + 'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'), + 'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'), + ) + ); + + return $this->tpl->getTemplate($tpl_id); + } + + /** + * Generate data for uptime graph + * @param int $server_id + * @return array + */ + protected function generateGraphUptime($server_id) { + $uptimes = $this->db->select(PSM_DB_PREFIX.'servers_uptime' , array('server_id' => $server_id), null, '', 'date'); + $last_date = 0; + $latency_avg = 0; + // Create the list of points and server down zones + $line = array(); + $lines = array(); + $down = array(); + foreach ($uptimes as $uptime) { + $latency_avg += (float) $uptime['latency']; + + $time = strtotime($uptime['date']) * 1000; + if($uptime['status']) { + // The server is up + $line[] = '[' . $time . ',' . round((float)$uptime['latency'], 4) . ']'; + if($last_date) { + // Was down before. + // Record the first and last date as a string in the down array + $down[] = '[' . $last_date . ',' . $time . ']'; + $last_date = 0; + } + } + else { + if(!$last_date) { + $last_date = $time; + } + } + } + if(!empty($line)) { + $lines[] = '[' . implode(',', $line) . ']'; + } + if($last_date) { + $down[] = '[' . $last_date . ',0]'; + } + $buttons = array(); + $buttons[] = array('mode' => 'hour', 'label' => psm_get_lang('servers', 'hour'), 'class_active' => 'btn-info'); + $buttons[] = array('mode' => 'day', 'label' => psm_get_lang('servers', 'day')); + $buttons[] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week')); + + $data = array( + 'title' => psm_get_lang('servers', 'chart_last_week'), + 'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0, + 'server_lines' => sizeof($lines) ? '[' . implode(',', $lines) . ']' : '', + 'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '', + 'series' => "[{label: '".psm_get_lang('servers', 'latency')."', lineWidth: 1}]", + 'plotmode' => 'hour', + 'buttons' => $buttons, + 'chart_id' => $server_id . '_uptime', + ); + return $data; + } + + /** + * Generate data for history graph + * @param int $server_id + * @return array + */ + protected function generateGraphHistory($server_id) { + $uptimes = $this->db->select(PSM_DB_PREFIX.'servers_history' , array('server_id' => $server_id), null, '', 'date'); + + $last_date = 0; + // Create the list of points and server down zones + $lines = array( + 'latency_avg' => array(), + 'latency_max' => array(), + 'latency_min' => array(), + ); + $latency_avg = 0; + $series = array(); + $time_end = 0; + + $down = array(); + foreach ($uptimes as $uptime) { + $time = strtotime($uptime['date']) * 1000; + // keep track of highest timestamp to use as end-date for graphs + if($time > $time_end) { + $time_end = $time; + } + $latency_avg += (float) $uptime['latency_avg']; + + if($uptime['checks_failed'] == 0) { + // The server is up + foreach($lines as $key => &$value) { + // add the value for each of the different lines + if(isset($uptime[$key])) { + $value[] = '[' . $time . ',' . round((float)$uptime[$key], 4) . ']'; + } + } + if($last_date) { + // Was down before. + // Record the first and last date as a string in the down array + $down[] = '[' . $last_date . ',' . $time . ']'; + $last_date = 0; + } + } else { + // The server is down + if(!$last_date) { + $last_date = $time; + } + } + } + $lines_merged = array(); + + foreach($lines as $line_key => $line_value) { + if(empty($value)) { + continue; + } + $lines_merged[] = '[' . implode(',', $line_value) . ']'; + $series[] = "{label: '".psm_get_lang('servers', $line_key)."', lineWidth: 1}"; + } + if($last_date) { + $down[] = '[' . $last_date . ',0]'; + } + $buttons = array(); + $buttons[] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week')); + $buttons[] = array('mode' => 'month', 'label' => psm_get_lang('servers', 'month'), 'class_active' => 'btn-info'); + $buttons[] = array('mode' => 'year', 'label' => psm_get_lang('servers', 'year')); + + $data = array( + 'title' => psm_get_lang('servers', 'chart_history'), + 'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0, + 'server_lines' => sizeof($lines_merged) ? '[' . implode(',', $lines_merged) . ']' : '', + 'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '', + 'series' => sizeof($series) ? '[' . implode(',', $series) . ']' : '', + 'plotmode' => 'month', + 'end_timestamp' => $time_end, + 'buttons' => $buttons, + // make sure to add chart id after buttons so its added to those tmeplates as well + 'chart_id' => $server_id . '_history', + ); + return $data; + } +} \ No newline at end of file diff --git a/src/psm/Util/Updater/Autorun.class.php b/src/psm/Util/Updater/Autorun.class.php index 0f602dce..8e789012 100644 --- a/src/psm/Util/Updater/Autorun.class.php +++ b/src/psm/Util/Updater/Autorun.class.php @@ -81,7 +81,7 @@ class Autorun { $archiver = new StatusArchiver($this->db); $cleanup_date = new \DateTime(); - $cleanup_date->modify('-1 month'); + $cleanup_date->modify('-1 week'); foreach($servers as $server) { $status_old = ($server['status'] == 'on') ? true : false; diff --git a/src/templates/history.tpl.html b/src/templates/server/history.tpl.html similarity index 63% rename from src/templates/history.tpl.html rename to src/templates/server/history.tpl.html index e274ceeb..427f775e 100644 --- a/src/templates/history.tpl.html +++ b/src/templates/server/history.tpl.html @@ -1,4 +1,4 @@ - + @@ -9,6 +9,7 @@
- +
-
+
@@ -28,28 +29,25 @@
- {label_last_online}: {server_online}
- {label_rtime}: {server_rtime}
+ {label_latency_avg}: {latency_avg}
- - - - -
+ + + + {buttons} +
 
- -{servers} + +{graphs} - - + \ No newline at end of file diff --git a/src/templates/server/view.tpl.html b/src/templates/server/view.tpl.html new file mode 100644 index 00000000..e5bfacdf --- /dev/null +++ b/src/templates/server/view.tpl.html @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {status} +   + {label} +
{label_type}:{type}
{label_domain}:{ip}
{label_port}:{port}
{label_last_check}:{last_check}
{label_last_online}:{last_online}
{label_rtime}:{rtime} s
{label_monitoring}:{active}
{label_send_email}:{email}
{label_send_sms}:{sms}
+{html_history} + \ No newline at end of file diff --git a/src/templates/servers.tpl.html b/src/templates/servers.tpl.html index 8eeb8891..5857a875 100755 --- a/src/templates/servers.tpl.html +++ b/src/templates/servers.tpl.html @@ -24,7 +24,7 @@ {status} - {label} + {label} {ip} {port} {type} diff --git a/src/templates/status.tpl.html b/src/templates/status.tpl.html index 23a15fbd..82ed5831 100755 --- a/src/templates/status.tpl.html +++ b/src/templates/status.tpl.html @@ -24,6 +24,7 @@ border-radius: 3px; margin-bottom: 20px; width: 300px; + cursor: pointer; } .offline { @@ -54,7 +55,7 @@
-
+

{label}

{label_last_online}: {last_online_nice}

{label_last_check}: {last_checked_nice}

@@ -64,7 +65,7 @@
-
+

{label}

{label_last_online}: {last_checked_nice}

{label_rtime}: {rtime}s

diff --git a/static/css/style.css b/static/css/style.css index a4070f89..d5b0db4f 100755 --- a/static/css/style.css +++ b/static/css/style.css @@ -87,4 +87,8 @@ legend{ max-width: 350px; margin: auto; margin-bottom: 18px; +} + +.oce-first{ + background-color:#eee; } \ No newline at end of file diff --git a/static/js/history.js b/static/js/history.js index 976b6ca2..9beb5bbd 100644 --- a/static/js/history.js +++ b/static/js/history.js @@ -3,8 +3,8 @@ $().ready(function() $('.chart').each(function() { var $this = $(this); create_plot($this); - }); - + }); + $(window).resize(function(){ $('.chart').each(function() { var plot = $(this).data('psm_plot'); @@ -12,7 +12,7 @@ $().ready(function() plot.replot( ); }); }); - + $('.chart-selector .btn').click(function(){ var $btn = $(this); var chartID = $btn.attr('data-chartId'); @@ -26,14 +26,18 @@ $().ready(function() function create_plot($this, mode) { if(!$this) return; - + var plot = $this.data('psm_plot'); if(plot) { plot.destroy(); $this.removeData('psm_plot'); } - var d = new Date(); + if($this.attr('data-endTime')) { + var d = new Date(parseInt($this.attr('data-endTime'))); + } else { + var d = new Date(); + } var time = d.getTime(); var lines = $this.attr('data-lines'); @@ -44,14 +48,18 @@ function create_plot($this, mode) lines = eval(lines); } - mode = mode || $this.data('psm_plotMode') || 'hour'; - $this.data('psm_plotMode', mode); + mode = mode || $this.attr('data-plotMode') || 'hour'; + $this.attr('data-plotMode', mode); var timeStamp, tickFormat; switch(mode) { + case 'year': + timeStamp = 1000 * 60 * 60 * 24 * 365.25; + tickFormat = day_format; + break; case 'month': timeStamp = 1000 * 60 * 60 * 24 * 30; - tickFormat = short_date_format; + tickFormat = day_format; break; case 'week': timeStamp = 1000 * 60 * 60 * 24 * 7; @@ -87,14 +95,19 @@ function create_plot($this, mode) showTooltipPrecision: 1.0, tooltipFormatString: "↓ " + d.strftime(long_date_format) }}); - } + } } plot = $.jqplot($this.attr('id'), lines, { title: $this.attr('data-title'), + series: eval($this.attr('data-series')), + legend: { + show: true, + placement: 'outsideGrid' + }, axes : { xaxis:{ - renderer:$.jqplot.DateAxisRenderer, + renderer:$.jqplot.DateAxisRenderer, tickOptions : { formatString: tickFormat }, min: time - timeStamp, max: time @@ -111,20 +124,17 @@ function create_plot($this, mode) return "↑ " + d.strftime(long_date_format) + ' - ' + $.jqplot.sprintf('%.3fs', point[1]); } }, - seriesDefaults: { - color: "#4bb2c5" - }, canvasOverlay: { show: true, objects: downArray }, - cursor:{ + cursor:{ show: true, - zoom: true, + zoom: true, showTooltip:false, dblClickReset: true, constrainZoomTo: 'x' - } + } }); $this.data('psm_plot', plot); }