<?php // Pandora FMS - http://pandorafms.com // ================================================== // Copyright (c) 2005-2010 Artica Soluciones Tecnologicas // Please see http://pandorafms.org for full contribution list // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation for version 2. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Singleton class Ui { private static $instance; private $title; private $page_name; private $endHeader = false; private $header = []; private $endContent = false; private $content = []; private $endFooter = false; private $footer = []; private $form = []; private $grid = []; private $collapsible = true; private $endForm = true; private $endGrid = true; private $endCollapsible = true; private $dialogs = []; private $dialog = ''; public function __construct() { } public static function getInstance() { if (!(self::$instance instanceof self)) { self::$instance = new self; } return self::$instance; } public function debug($var, $file=false) { $more_info = ''; if (is_string($var)) { $more_info = 'size: '.strlen($var); } else if (is_bool($var)) { $more_info = 'val: '.($var ? 'true' : 'false'); } else if (is_null($var)) { $more_info = 'is null'; } else if (is_array($var)) { $more_info = count($var); } if ($file === true) { $file = '/tmp/logDebug'; } if (strlen($file) > 0) { $f = fopen($file, 'a'); ob_start(); echo date('Y/m/d H:i:s').' ('.gettype($var).') '.$more_info."\n"; print_r($var); echo "\n\n"; $output = ob_get_clean(); fprintf($f, '%s', $output); fclose($f); } else { echo '<pre>'.date('Y/m/d H:i:s').' ('.gettype($var).') '.$more_info.'</pre>'; echo '<pre>'; print_r($var); echo '</pre>'; } } public function createPage($title=null, $page_name=null) { if (!isset($title)) { $this->title = __('%s mobile', get_product_name()); } else { $this->title = $title; } if (!isset($page_name)) { $this->page_name = 'main_page'; } else { $this->page_name = $page_name; } $this->html = ''; $this->endHeader = false; $this->header = []; $this->endContent = false; $this->content = []; $this->noFooter = false; $this->endFooter = false; $this->footer = []; $this->form = []; $this->grid = []; $this->collapsible = []; $this->endForm = true; $this->endGrid = true; $this->endCollapsible = true; $this->dialog = ''; $this->dialogs = []; } public function showFooter($show=true) { $this->noFooter = !$show; } public function beginHeader() { $this->header = []; $this->header['button_left'] = ''; $this->header['button_right'] = ''; $this->header['title'] = ''; $this->endHeader = false; } public function endHeader() { $this->endHeader = true; } public function createHeader($title=null, $buttonLeft=null, $buttonRight=null) { $this->beginHeader(); $this->headerTitle($title); $this->headerAddButtonLeft($buttonLeft); $this->headerAddButtonRight($buttonRight); $this->endHeader(); } public function headerTitle($title=null) { if (isset($title)) { $this->header['title'] = $title; } } public function headerAddButtonLeft($button=null) { if (isset($button)) { $this->header['button_left'] = $button; } } public function headerAddButtonRight($button=null) { if (isset($button)) { $this->header['button_right'] = $button; } } public function createHeaderButton($options) { return $this->createButton($options); } public function createDefaultHeader($title=false, $left_button=false) { if ($title === false) { $title = __('%s : Mobile', get_product_name()); } if ($left_button === false) { $left_button = $this->createHeaderButton( [ 'icon' => 'back', 'pos' => 'left', 'text' => __('Logout'), 'href' => 'index.php?action=logout', ] ); } $this->createHeader( $title, $left_button, $this->createHeaderButton( [ 'icon' => 'home', 'pos' => 'right', 'text' => __('Home'), 'href' => 'index.php?page=home', ] ) ); } public function createButton($options) { $return = '<a data-role="button" '; if (isset($options['id'])) { $return .= 'id="'.$options['id'].'" '; } if (isset($options['icon'])) { $return .= 'data-icon="'.$options['icon'].'" '; } if (isset($options['icon_pos'])) { $return .= 'data-iconpos="'.$options['pos'].'" '; } if (isset($options['href'])) { $return .= 'href="'.$options['href'].'" '; } else { $return .= 'href="#" '; } $return .= ' data-ajax="false">'; if (isset($options['text'])) { $return .= $options['text']; } $return .= '</a>'; return $return; } public function beginFooter() { $this->footer = []; $this->endFooter = false; } public function endFooter() { $this->endFooter = true; } public function createFooter($text='') { $this->footerText($text); } public function footerText($text=null) { if (!isset($text)) { $this->footer['text'] = ''; } else { $this->footer['text'] = $text; } $this->endFooter(); } public function defaultFooter() { global $pandora_version, $build_version; if (isset($_SERVER['REQUEST_TIME'])) { $time = $_SERVER['REQUEST_TIME']; } else { $time = get_system_time(); } return "<div id='footer' style='text-align: center;'>\n".sprintf(__('%s %s - Build %s', get_product_name(), $pandora_version, $build_version))."<br />\n".__('Generated at').' '.ui_print_timestamp($time, true, ['prominent' => 'timestamp'])."\n".'</div>'; } public function beginContent() { $this->content = []; $this->endContent = false; } public function endContent() { $this->endContent = true; } public function contentAddHtml($html) { $this->content[] = $html; } public function contentBeginGrid($mode='responsive') { $this->endGrid = false; $this->grid = []; $this->grid['mode'] = $mode; $this->grid['cells'] = []; } public function contentGridAddCell($html, $key=false) { $k = uniqid('cell_'); if ($key !== false) { $k = $key; } $this->grid['cells'][$k] = $html; } public function contentEndGrid() { $this->endGrid = true; // TODO Make others modes, only responsible mode $convert_columns_jquery_grid = [ 2 => 'a', 3 => 'b', 4 => 'c', 5 => 'd', ]; $convert_cells_jquery_grid = [ 'a', 'b', 'c', 'd', 'e', ]; $html = "<div class='ui-grid-".$convert_columns_jquery_grid[count($this->grid['cells'])]." ui-responsive'>\n"; reset($convert_cells_jquery_grid); foreach ($this->grid['cells'] as $key => $cell) { switch ($this->grid['mode']) { default: case 'responsive': $html .= "<div class='ui-block-".current($convert_cells_jquery_grid)."'>\n"; break; } next($convert_cells_jquery_grid); $html .= "<div id='".$key."' class='ui-body ui-body-d'>\n"; $html .= $cell; $html .= "</div>\n"; $html .= "</div>\n"; } $html .= "</div>\n"; $this->contentAddHtml($html); $this->grid = []; } public function contentBeginCollapsible($title=' ') { $this->endCollapsible = false; $this->collapsible = []; $this->collapsible['items'] = []; $this->collapsible['title'] = $title; } public function contentCollapsibleAddItem($html) { $this->collapsible['items'][] = $html; } public function contentEndCollapsible() { $this->endCollapsible = true; $html = "<div data-role='collapsible' "." data-collapsed-icon='arrow-d' "." data-expanded-icon='arrow-u' data-mini='true' "." data-theme='a' data-content-theme='c'>\n"; $html .= '<h4>'.$this->collapsible['title']."</h4>\n"; $html .= "<ul data-role='listview' data-theme='c'>\n"; foreach ($this->collapsible['items'] as $item) { $html .= '<li>'.$item.'</li>'; } $html .= "</ul>\n"; $html .= "</div>\n"; $this->contentAddHtml($html); $this->collapsible = []; } public function beginForm($action='index.php', $method='post') { $this->form = []; $this->endForm = false; $this->form['action'] = $action; $this->form['method'] = $method; } public function endForm() { $this->contentAddHtml($this->getEndForm()); } public function getEndForm() { $this->endForm = true; $html = "<form data-ajax='false' action='".$this->form['action']."' "."method='".$this->form['method']."'>\n"; foreach ($this->form['fields'] as $field) { $html .= $field."\n"; } $html .= "</form>\n"; $this->form = []; return $html; } public function formAddHtml($html) { $this->form['fields'][] = $html; } public function formAddInput($options) { $this->formAddHtml($this->getInput($options)); } public function getInput($options) { if (empty($options['name'])) { $options['name'] = uniqid('input'); } if (empty($options['id'])) { $options['id'] = 'text-'.$options['name']; } $html = "<div id='".$options['name']."-container' >\n"; $html .= "<fieldset data-role='controlgroup'>\n"; if (!empty($options['label'])) { $html .= "<label for='".$options['id']."'>".$options['label']."</label>\n"; } // Erase other options and only for the input unset($options['label']); $html .= '<input '; foreach ($options as $option => $value) { $html .= ' '.$option."='".$value."' "; } $html .= ">\n"; $html .= "</fieldset>\n"; $html .= "</div>\n"; return $html; } public function formAddInputPassword($options) { $options['type'] = 'password'; $this->formAddInput($options); } public function formAddInputText($options) { $options['type'] = 'text'; $this->formAddInput($options); } public function formAddInputSearch($options) { $options['type'] = 'search'; $this->formAddInput($options); } public function formAddInpuDate($options) { $options['type'] = 'date'; $options['data-clear-btn'] = 'false'; $this->formAddInput($options); } public function formAddCheckbox($options) { $options['type'] = 'checkbox'; if (isset($options['checked'])) { if ($options['checked']) { $options['checked'] = 'checked'; } else { unset($options['checked']); } } $this->formAddInput($options); } public function formAddSubmitButton($options) { $options['type'] = 'submit'; if (isset($options['icon'])) { $options['data-icon'] = $options['icon']; unset($options['icon']); } if (isset($options['icon_pos'])) { $options['data-iconpos'] = $options['icon_pos']; unset($options['icon_pos']); } if (isset($options['text'])) { $options['value'] = $options['text']; unset($options['text']); } $this->formAddInput($options); } public function formAddSelectBox($options) { $html = ''; if (empty($options['name'])) { $options['name'] = uniqid('input'); } if (empty($options['id'])) { $options['id'] = 'select-'.$options['name']; } $html = "<div data-role='fieldcontain'>\n"; $html .= "<fieldset>\n"; if (!empty($options['label'])) { $html .= "<label for='".$options['id']."'>".$options['label']."</label>\n"; } $html .= "<select name='".$options['name']."' "."id='".$options['id']."' data-native-menu='false'>\n"; // Hack of jquery mobile $html .= '<option>'.$options['title']."</option>\n"; if (empty($options['items'])) { $options['items'] = []; } foreach ($options['items'] as $id => $item) { if (!empty($options['item_id'])) { $item_id = $item[$options['item_id']]; } else { $item_id = $id; } if (!empty($options['item_value'])) { $item_value = $item[$options['item_value']]; } else { $item_value = $item; } $selected = ''; if (isset($options['selected'])) { if (is_numeric($options['selected'])) { if (floatval($options['selected']) === floatval($item_id)) { $selected = "selected = 'selected'"; } } else { if ($options['selected'] === $item_id) { $selected = "selected = 'selected'"; } } } $html .= '<option '.$selected." value='".$item_id."'>".$item_value."</option>\n"; } $html .= "</select>\n"; $html .= "</fieldset>\n"; $html .= "</div>\n"; $this->formAddHtml($html); } public function formAddSlider($options) { $options['type'] = 'range'; $this->formAddInput($options); // <input type="range" name="slider-fill" id="slider-fill" value="60" min="0" max="1000" step="50" data-highlight="true"> } public function addDialog($options) { $type = 'hidden'; $dialog_id = uniqid('dialog_'); $dialog_class = ''; $title_close_button = false; $title_text = ''; $content_id = uniqid('content_'); $content_class = ''; $content_text = ''; $button_close = true; $button_text = __('Close'); if (is_array($options)) { if (isset($options['type'])) { $type = $options['type']; } if (isset($options['dialog_id'])) { $dialog_id = $options['dialog_id']; } if (isset($options['dialog_class'])) { $dialog_class = $options['dialog_class']; } if (isset($options['title_close_button'])) { $title_close_button = $options['title_close_button']; } if (isset($options['title_text'])) { $title_text = $options['title_text']; } if (isset($options['content_id'])) { $content_id = $options['content_id']; } if (isset($options['content_class'])) { $content_class = $options['content_class']; } if (isset($options['content_text'])) { $content_text = $options['content_text']; } if (isset($options['button_close'])) { $button_close = $options['button_close']; } if (isset($options['button_text'])) { $button_text = $options['button_text']; } } $html_title_close_button = ''; if ($title_close_button) { $html_title_close_button = "data-close-btn='yes'"; } $dialogHtml = "<div id='".$dialog_id."' class='".$dialog_class."' data-role='dialog' ".$html_title_close_button.">\n"; $dialogHtml .= "<div data-role='header'>\n"; $dialogHtml .= "<h1 class='dialog_title'>".$title_text."</h1>\n"; $dialogHtml .= "</div>\n"; $dialogHtml .= "<div id='".$content_id."' class='".$content_class."' data-role='content'>\n"; $dialogHtml .= $content_text; if ($button_close) { $dialogHtml .= "<a data-role='button' href='#main_page' id='".$dialog_id."-button_close'>"; if (empty($button_text)) { $dialogHtml .= __('Close'); } else { $dialogHtml .= $button_text; } $dialogHtml .= "</a></p>\n"; } $dialogHtml .= "</div>\n"; $dialogHtml .= "</div>\n"; $this->dialogs[$type][] = $dialogHtml; } public function showError($msg) { echo $msg; } public function showPage() { if (!$this->endHeader) { $this->showError(__('Not found header.')); } else if (!$this->endContent) { $this->showError(__('Not found content.')); } else if ((!$this->endFooter) && (!$this->noFooter)) { $this->showError(__('Not found footer.')); } else if (!$this->endForm) { $this->showError(__('Incorrect form.')); } else if (!$this->endGrid) { $this->showError(__('Incorrect grid.')); } else if (!$this->endCollapsible) { $this->showError(__('Incorrect collapsible.')); } ob_start(); echo "<!DOCTYPE html>\n"; echo "<html>\n"; echo " <head>\n"; echo ' <title>'.$this->title."</title>\n"; echo " <meta charset='UTF-8' />\n"; echo " <meta name='viewport' content='width=device-width, initial-scale=1'>\n"; echo " <link rel='stylesheet' href='include/style/main.css' />\n"; echo " <link rel='stylesheet' href='include/style/jquery.mobile-1.3.1.css' />\n"; echo " <script src='include/javascript/jquery.js'></script>\n"; echo " <script src='include/javascript/jquery.mobile-1.3.1.js'></script>\n"; echo " <script src='../include/javascript/pandora.js'></script>\n"; echo " <script src='../include/javascript/pandora_ui.js'></script>\n"; echo " </head>\n"; echo " <body>\n"; echo include_javascript_dependencies_flot_graph(false, false); echo " <div class='ui-loader-background'> </div>"; if (!empty($this->dialogs)) { if (!empty($this->dialogs['onStart'])) { foreach ($this->dialogs['onStart'] as $dialog) { echo ' '.$dialog."\n"; } } } echo " <div data-dom-cache='false' data-role='page' id='".$this->page_name."'>\n"; echo " <div data-role='header' data-position='fixed' >\n"; echo ' <h1>'.$this->header['title']."</h1>\n"; echo ' '.$this->header['button_left']."\n"; echo ' '.$this->header['button_right']."\n"; echo " </div>\n"; echo " <div data-role='content'>\n"; foreach ($this->content as $content) { echo ' '.$content."\n"; } echo " </div>\n"; if (!$this->noFooter) { echo " <div data-role='footer' role='contentinfo'>\n"; if (!empty($this->footer['text'])) { echo ' '.$this->footer['text']."\n"; } else { echo ' '.$this->defaultFooter()."\n"; } } echo " </div>\n"; echo " </div>\n"; if (!empty($this->dialogs)) { if (!empty($this->dialogs['hidden'])) { foreach ($this->dialogs['hidden'] as $dialog) { echo ' '.$dialog."\n"; } } } echo "<script type='text/javascript'> $(document).bind('mobileinit', function() { //Disable ajax link $('.disable-ajax').click(function(event) { $.mobile.ajaxFormsEnabled = false; }); }); </script>"; echo " </body>\n"; echo '</html>'; ob_end_flush(); } // Add a listener to set a link when a row of a table is clicked. // The target link will be the first <a> tag found into the row public function contentAddLinkListener($table_name) { $this->contentAddHtml( '<script type="text/javascript"> //Set link on entire row function refresh_link_listener_'.$table_name."() { $('#".$table_name." tr').click( function() { var link = $(this).find('a').attr('href'); if (link != undefined) { window.location = $(this).find('a').attr('href'); } }); } $(document).ready(function() { refresh_link_listener_".$table_name.'(); }); </script>' ); } } class Table { private $head = []; private $rows = []; public $id = ''; private $rowClass = []; private $class_table = ''; private $row_heads = []; public $row_keys_as_head_row = false; public function __construct() { $this->init(); } public function init() { $this->id = uniqid(); $this->head = []; $this->rows = []; $this->rowClass = []; $this->class_table = ''; $this->row_heads = []; $this->row_keys_as_head_row = false; } public function addHeader($head) { $this->head = $head; } public function addRowHead($key, $head_text) { $this->row_heads[$key] = $head_text; } public function addRow($row=[], $key=false) { if ($key !== false) { $this->rows[$key] = $row; } else { $this->rows[] = $row; } } public function importFromHash($data) { foreach ($data as $id => $row) { $table_row = []; foreach ($row as $key => $value) { if (!in_array($key, $this->head)) { $this->head[] = $key; } $cell_key = array_search($key, $this->head); $table_row[$cell_key] = $value; } $this->rows[$id] = $table_row; } } public function importFromHashEvents($data) { foreach ($data as $id => $row) { $table_row = []; foreach ($row as $key => $value) { if (!in_array($key, $this->head)) { // $this->head[] = $key; } // $cell_key = array_search($key, $this->head); // $table_row[$cell_key] = $value; $table_row[$key] = $value; } $this->rows[$id] = $table_row; } } public function setClass($class='') { $this->class_table = $class; } public function setId($id=false) { if (empty($id)) { $this->id = uniqid(); } else { $this->id = $id; } } public function setRowClass($class='', $pos=false) { if (is_array($class)) { $this->rowClass = $class; } else { if ($pos !== false) { $this->rowClass[$pos] = $class; } else { $this->rowClass = array_fill(0, count($this->rows), $class); } } } public function getHTML() { $html = ''; $html = "<table data-role='table' id='".$this->id."' "."data-mode='reflow' class='".$this->class_table." ui-responsive table-stroke'>"; if ($this->head) { $html .= '<thead>'; $html .= '<tr>'; // Empty head for white space between rows in the responsive vertical layout // ~ $html .= "<th class='head_horizontal'></th>"; foreach ($this->head as $head) { $html .= "<th class='head_horizontal'>".$head.'</th>'; } $html .= '</tr>'; $html .= '</thead>'; } $html .= '<tbody>'; foreach ($this->rows as $key => $row) { $class = ''; if (isset($this->rowClass[$key])) { $class = $this->rowClass[$key]; } $html .= "<tr class='".$class."'>"; // Empty head for white space between rows in the responsive vertical layout foreach ($row as $key_cell => $cell) { $html .= "<td class='cell_".$key_cell."'>".$cell.'</td>'; } $html .= '</tr>'; } $html .= '</tbody>'; $html .= '</table>'; return $html; } }