/** * Generates form elements. The main use for print_search() and print_form(), see examples of this functions. * * Options tree: * textarea -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, (string)width, (string)class, * (int)rows, (int)cols, * (string)value, (bool,string)placeholder, (bool)ajax, (array)ajax_vars * text, input, password -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, (string)width, (string)class, * (string)value, (bool,string)placeholder, (bool)ajax, (array)ajax_vars, * (bool)show_password * hidden -\ * (string)id, (string)value * select, multiselect -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, (string)onchange, (string)width, * (string)title, (int)size, (bool)right, (bool)live-search, (bool)encode, (bool)subtext * (string)value, (array)values, (string)icon, * values items can be arrays, ie: * value => array('name' => string, 'group' => string, 'icon' => string, 'class' => string, 'style' => string) * datetime -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, * (string|FALSE)from, (string|FALSE)to, (bool)presets, (string)min, (string)max * (string)value (use it for single input) * checkbox, switch -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, (string)onchange, * (bool)revert, (int)width, (string)size, (string)off-color, (string)on-color, (string)off-text, (string)on-text * (string)value, (string)placeholder, (string)title * submit -\ * (string)id, (string)name, (bool)readonly, (bool)disabled, * (string)class, (bool)right, (string)tooltip, * (string)value, (string)form_id, (string)icon * html, raw -\ * (string)id, * (string)html * newline -\ * (string)id, * (bool)hr * * @param array $item Options for current form element * @param string $type Type of form element, also can passed as $item['type'] * @return string Generated form element */ function generate_form_element($item, $type = '') { $value_isset = isset($item['value']); if (!$value_isset) { $item['value'] = ''; } if (!isset($item['type'])) { $item['type'] = $type; } $string = ''; $element_tooltip = ''; switch ($item['type']) { case 'hidden': if (!$item['readonly'] && !$item['disabled']) { $string .= ' <input type="' . $item['type'] . '" name="' . $item['id'] . '" id="' . $item['id'] . '" value="' . $item['value'] . '" />' . PHP_EOL; } break; case 'password': case 'textarea': case 'text': case 'input': if ($item['type'] != 'textarea') { $item_begin = ' <input type="' . $item['type'] . '" '; // password specific options if ($item['type'] == 'password') { // disable autocomplete for passwords $item_begin .= ' autocomplete="off" '; // mask password field for disabled/readonly by bullet if (strlen($item['value']) && ($item['disabled'] || $item['readonly'])) { if (!($item['show_password'] && $_SESSION['userlevel'] > 7)) { $item['value'] = '••••••••'; } } // add icon for show/hide password if ($item['show_password']) { $item_begin .= ' data-toggle="password" '; register_html_resource('js', 'bootstrap-show-password.min.js'); $GLOBALS['cache_html']['javascript'][] = "\$('[data-toggle=\"password\"]').password();"; } } $item_end = ' value="' . $item['value'] . '" />'; $item_class = 'input'; } else { $item_begin = ' <textarea '; // textarea specific options if (is_numeric($item['rows'])) { $item_begin .= 'rows="' . $item['rows'] . '" '; } if (is_numeric($item['cols'])) { $item_begin .= 'cols="' . $item['cols'] . '" '; } $item_end = '>' . $item['value'] . '</textarea>'; $item_class = 'form-control'; } if ($item['disabled']) { $item_end = ' disabled="1"' . $item_end; } else { if ($item['readonly']) { $item_end = ' readonly="1"' . $item_end; } } if (isset($item['placeholder']) && $item['placeholder'] !== FALSE) { if ($item['placeholder'] === TRUE) { $item['placeholder'] = $item['name']; } $string .= PHP_EOL; $string .= $item_begin . 'placeholder="' . $item['placeholder'] . '" '; $item['placeholder'] = TRUE; // Set to true for check at end } else { $string .= ' <div class="input-prepend">' . PHP_EOL; if (!$item['name']) { $item['name'] = '<i class="icon-list"></i>'; } $string .= ' <span class="add-on">' . $item['name'] . '</span>' . PHP_EOL; $string .= $item_begin; } if ($item['class']) { $item_class .= ' ' . $item['class']; } $string .= isset($item['width']) ? 'style="width:' . $item['width'] . '" ' : ''; $string .= 'name="' . $item['id'] . '" id="' . $item['id'] . '" class="' . $item_class; if ($item['ajax'] === TRUE && is_array($item['ajax_vars'])) { $ajax_vars = array(); if (!isset($item['ajax_vars']['field'])) { // If query field not specified use item id as field $item['ajax_vars']['field'] = $item['id']; } foreach ($item['ajax_vars'] as $k => $v) { $ajax_vars[] = urlencode($k) . '=' . var_encode($v); } $string .= ' ajax-typeahead" autocomplete="off" data-link="/ajax/input.php?' . implode('&', $ajax_vars); // Register scripts/css register_html_resource('js', 'typeahead.bundle.min.js'); register_html_resource('css', 'typeaheadjs.css'); // Ajax autocomplete for input // <input type='text' class='ajax-typeahead' data-link='your-json-link' /> $item_id = $item['id']; $script = <<<SCRIPT var element_{$item_id} = \$('#{$item_id}.ajax-typeahead'); var entries_{$item_id} = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: element_{$item_id}.data('link') + '&query=%QUERY', wildcard: '%QUERY', filter: function(json) { return json.options; } } }); element_{$item_id}.typeahead({ hint: false, highlight: true, minLength: 1 }, { name: 'options', limit: 16, source: entries_{$item_id} } ); SCRIPT; register_html_resource('script', $script); } $string .= '" ' . $item_end . PHP_EOL; $string .= $item['placeholder'] ? PHP_EOL : ' </div>' . PHP_EOL; // End 'text' & 'input' break; case 'switch': // switch specific options if ($item['revert']) { $item_switch = ' data-toggle="switch-revert"'; } else { $item_switch = ' data-toggle="switch"'; } if ($item['size']) { $item_switch .= ' data-size="' . $item['size'] . '"'; } if ($item['on-color']) { $item_switch .= ' data-on-color="' . $item['on-color'] . '"'; } if ($item['off-color']) { $item_switch .= ' data-off-color="' . $item['off-color'] . '"'; } if ($item['on-text']) { $item_switch .= ' data-on-text="' . $item['on-text'] . '"'; } if ($item['off-text']) { $item_switch .= ' data-off-text="' . $item['off-text'] . '"'; } if (is_numeric($item['width']) && $item['width'] > 10) { $item_switch .= ' data-handle-width="' . intval($item['width'] / 2) . '"'; } case 'checkbox': $string = ' <input type="checkbox" '; $string .= ' name="' . $item['id'] . '" id="' . $item['id'] . '" ' . $item_switch; if ($item['title']) { $string .= ' data-rel="tooltip" data-tooltip="' . escape_html($item['title']) . '"'; } if ($item['value'] == '1' || $item['value'] === 'on' || $item['value'] === 'yes' || $item['value'] === TRUE) { $string .= ' checked'; } if ($item['disabled']) { $string .= ' disabled="1"'; } else { if ($item['readonly']) { $string .= ' readonly="1" onclick="return false"'; } else { if ($item['onchange']) { $string .= ' onchange="' . $item['onchange'] . '"'; } } } $string .= ' value="1" />'; if (is_string($item['placeholder'])) { // add placeholder text at right of the element $string .= ' <span class="help-inline" style="margin-top: 4px;">' . $item['placeholder'] . '</span>' . PHP_EOL; } // End 'switch' & 'checkbox' break; case 'datetime': register_html_resource('js', 'bootstrap-datetimepicker.min.js'); // Enable DateTime JS $id_from = $item['id'] . '_from'; $id_to = $item['id'] . '_to'; if ($value_isset && !$item['from'] && !$item['to']) { // Single datetime input $item['from'] = $item['value']; $item['to'] = FALSE; $item['presets'] = FALSE; $id_from = $item['id']; $name_from = $item['name']; } else { $name_from = 'From'; } // Presets if ($item['from'] === FALSE || $item['to'] === FALSE) { $item['presets'] = FALSE; } if (is_numeric($item['from'])) { $item['from'] = strftime("%F %T", $item['from']); } if (is_numeric($item['to'])) { $item['to'] = strftime("%F %T", $item['to']); } if ($item['presets']) { $presets = array('sixhours' => 'Last 6 hours', 'today' => 'Today', 'yesterday' => 'Yesterday', 'tweek' => 'This week', 'lweek' => 'Last week', 'tmonth' => 'This month', 'lmonth' => 'Last month', 'tquarter' => 'This quarter', 'lquarter' => 'Last quarter', 'tyear' => 'This year', 'lyear' => 'Last year'); // Recursive call $preset_item = array('id' => $item['id'] . '_preset', 'type' => 'select', 'name' => 'Date presets', 'width' => '110px', 'values' => $presets); $string .= generate_form_element($preset_item) . PHP_EOL; } // Date/Time input fields if ($item['from'] !== FALSE) { $string .= ' <div id="' . $id_from . '_div" class="input-prepend" style="margin-bottom: 0;">' . PHP_EOL; $string .= ' <span class="add-on btn"><i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> ' . $name_from . '</span>' . PHP_EOL; //$string .= ' <input type="text" class="input-medium" data-format="yyyy-MM-dd hh:mm:ss" '; $string .= ' <input type="text" data-format="yyyy-MM-dd hh:mm:ss" '; $string .= isset($item['width']) ? 'style="width:' . escape_html($item['width']) . '" ' : 'style="width: 130px;" '; if ($item['disabled']) { $string .= 'disabled="1" '; } else { if ($item['readonly']) { $item['disabled'] = TRUE; // for js $string .= 'readonly="1" '; } } $string .= 'name="' . $id_from . '" id="' . $id_from . '" value="' . escape_html($item['from']) . '"/>' . PHP_EOL; $string .= ' </div>' . PHP_EOL; } if ($item['to'] !== FALSE) { $string .= ' <div id="' . $id_to . '_div" class="input-prepend" style="margin-bottom: 0;">' . PHP_EOL; $string .= ' <span class="add-on btn"><i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> To</span>' . PHP_EOL; //$string .= ' <input type="text" class="input-medium" data-format="yyyy-MM-dd hh:mm:ss" '; $string .= ' <input type="text" data-format="yyyy-MM-dd hh:mm:ss" '; $string .= isset($item['width']) ? 'style="width:' . escape_html($item['width']) . '" ' : 'style="width: 140px;" '; $string .= 'name="' . $id_to . '" id="' . $id_to . '" value="' . escape_html($item['to']) . '"/>' . PHP_EOL; $string .= ' </div>' . PHP_EOL; } // JS SCRIPT $min = '-Infinity'; $max = 'Infinity'; $pattern = '/^(\\d{4})-(\\d{2})-(\\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/'; if (!empty($item['min'])) { if (preg_match($pattern, $item['min'], $matches)) { $matches[2] = $matches[2] - 1; array_shift($matches); $min = 'new Date(' . implode(',', $matches) . ')'; } else { if ($item['min'] == 'now' || $item['min'] == 'current') { $min = 'new Date()'; } } } if (!empty($item['max'])) { if (preg_match($pattern, $item['max'], $matches)) { $matches[2] = $matches[2] - 1; array_shift($matches); $max = 'new Date(' . implode(',', $matches) . ')'; } else { if ($item['max'] == 'now' || $item['max'] == 'current') { $max = 'new Date()'; } } } $script = ' var startDate = ' . $min . '; var endDate = ' . $max . '; $(document).ready(function() { $(\'[id=' . $id_from . '_div]\').datetimepicker({ //pickSeconds: false, weekStart: 1, startDate: startDate, endDate: endDate });'; if ($item['disabled']) { $script .= ' $(\'[id=' . $id_from . '_div]\').datetimepicker(\'disable\');'; } if ($item['to'] !== FALSE) { $script .= ' $(\'[id=' . $id_to . '_div]\').datetimepicker({ //pickSeconds: false, weekStart: 1, startDate: startDate, endDate: endDate });'; } $script .= ' });' . PHP_EOL; if ($item['presets']) { $script .= ' $(\'select[id=' . $item['id'] . '_preset]\').change(function() { var input_from = $(\'input#' . $id_from . '\'); var input_to = $(\'input#' . $id_to . '\'); switch ($(this).val()) {' . PHP_EOL; foreach ($presets as $k => $v) { $preset = datetime_preset($k); $script .= " case '{$k}':\n"; $script .= " input_from.val('" . $preset['from'] . "');\n"; $script .= " input_to.val('" . $preset['to'] . "');\n"; $script .= " break;\n"; } $script .= ' default: input_from.val(""); input_to.val(""); break; } });'; } register_html_resource('script', $script); // End 'datetime' break; case 'tags': // Tags mostly same as multiselect, but used separate options and Bootstrap Tags Input JS register_html_resource('js', 'bootstrap-tagsinput.min.js'); // Enable Tags Input JS //register_html_resource('js', 'bootstrap-tagsinput.js'); // Enable Tags Input JS register_html_resource('css', 'bootstrap-tagsinput.css'); // Enable Tags Input CSS // defaults $delimiter = empty($item['delimiter']) ? ',' : $item['delimiter']; $script_begin = ''; $script_options = array('trimValue' => 'true', 'tagClass' => 'function(item) {return "label label-default";}'); //register_html_resource('script', '$("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput({trimValue: true, tagClass: function(item) {return "label label-default";} });'); $string .= ' <select multiple data-toggle="tagsinput" name="' . $item['id'] . '[]" ' . $title; $string .= 'id="' . $item['id'] . '" '; if ($item['title']) { $string .= 'title="' . $item['title'] . '" '; } else { if (isset($item['name'])) { $string .= 'title="' . $item['name'] . '" '; } } if (isset($item['placeholder']) && $item['placeholder'] !== FALSE) { if ($item['placeholder'] === TRUE) { $item['placeholder'] = $item['name']; } //$string .= PHP_EOL; $string .= ' placeholder="' . $item['placeholder'] . '"'; //$item['placeholder'] = TRUE; // Set to true for check at end } if ($item['disabled']) { $string .= ' disabled="1"'; } else { if ($item['readonly']) { $string .= ' disabled="1" readonly="1"'; // Bootstrap Tags Input not support readonly attribute, currently use disable } } if ($item['onchange']) { $string .= ' onchange="' . $item['onchange'] . '"'; } $string .= '>' . PHP_EOL . ' '; // end <select> // Process values if (!is_array($item['value'])) { //$item['value'] = explode($delimiter, $item['value']); $item['value'] = array($item['value']); } //$item['value'] = array('test', 'hello'); $suggest = array(); foreach ($item['value'] as $entry) { $value = (string) $entry; if ($value == '[there is no data]' || $value === '') { continue; } $suggest[] = $value; $string .= '<option value="' . $value . '"'; $string .= '>' . escape_html($value) . '</option> '; } $string .= PHP_EOL . ' </select>' . PHP_EOL; // Generate typeahead from values $suggest = array_merge($suggest, (array) $item['values']); if (count($suggest)) { $option = '[{ hint: false, highlight: true, minLength: 1 }, { name: "suggest", limit: 16, source: suggest_' . $item['id'] . ' }]'; $script_begin .= 'var suggest_' . $item['id'] . ' = new Bloodhound({ matchAnyQueryToken: true, queryTokenizer: Bloodhound.tokenizers.nonword, datumTokenizer: Bloodhound.tokenizers.nonword, local: ['; $values = array(); foreach (array_unique($suggest) as $k => $entry) { if (is_array($entry)) { $value = (string) $k; } else { $value = (string) $entry; } $values[] = "'" . str_replace("'", "\\'", $value) . "'"; } $script_begin .= implode(',', $values); $script_begin .= ']});' . PHP_EOL; $script_options['typeaheadjs'] = $option; // Register scripts/css //register_html_resource('js', 'typeahead.bundle.js'); register_html_resource('js', 'typeahead.bundle.min.js'); register_html_resource('css', 'typeaheadjs.css'); } if (count($script_options)) { $script = $script_begin; $script .= "\$('#" . $item['id'] . "').tagsinput({" . PHP_EOL; foreach ($script_options as $key => &$option) { $option = ' ' . $key . ': ' . $option; } $script .= implode(',' . PHP_EOL, $script_options) . PHP_EOL; $script .= "});"; register_html_resource('script', $script); } // End 'tags' break; case 'multiselect': unset($item['icon']); // For now not used icons in multiselect // For now not used icons in multiselect case 'select': $count_values = count($item['values']); if (empty($item['values'])) { $item['values'] = array(0 => '[there is no data]'); $item['subtext'] = FALSE; } if ($item['type'] == 'multiselect') { $string .= ' <select multiple name="' . $item['id'] . '[]" ' . $title; // Enable Select/Deselect all (if select values count more than 4) if ($count_values > 4) { $string .= ' data-actions-box="true" '; } } else { $string .= ' <select name="' . $item['id'] . '" '; } $string .= 'id="' . $item['id'] . '" '; if ($item['title']) { $string .= 'title="' . $item['title'] . '" '; } else { if (isset($item['name'])) { $string .= 'title="' . $item['name'] . '" '; } } $data_width = $item['width'] ? ' data-width="' . $item['width'] . '"' : ' data-width="auto"'; $data_size = is_numeric($item['size']) ? ' data-size="' . $item['size'] . '"' : ' data-size="15"'; $string .= 'class="selectpicker show-tick'; if ($item['right']) { $string .= ' pull-right'; } $string .= '" data-selected-text-format="count>2"'; if ($item['data-style']) { $string .= ' data-style="' . $item['data-style'] . '"'; } // Enable Live search in values list (if select values count more than 12) if ($count_values > 12 && $item['live-search'] !== FALSE) { $string .= ' data-live-search="true"'; } if ($item['disabled']) { $string .= ' disabled="1"'; } else { if ($item['readonly']) { $string .= ' disabled="1" readonly="1"'; // Bootstrap select not support readonly attribute, currently use disable } } if ($item['onchange']) { $string .= ' onchange="' . $item['onchange'] . '"'; } $string .= $data_width . $data_size . '>' . PHP_EOL . ' '; // end <select> if (!is_array($item['value'])) { $item['value'] = array($item['value']); } // Prepare values for optgroups $values = array(); $optgroup = array(); foreach ($item['values'] as $k => $entry) { $k = (string) $k; $value = $item['encode'] ? var_encode($k) : $k; // Use base64+serialize encoding // Default group is '' (empty string), for allow to use 0 as group name! $group = ''; if (!is_array($entry)) { $entry = array('name' => $entry); } else { if (isset($entry['group'])) { $group = $entry['group']; } } if ($item['subtext'] && !isset($entry['subtext'])) { $entry['subtext'] = $k; } // Icons and empty name fix if ($item['icon'] && $item['value'] === array('')) { // Only one main icon $entry['icon'] = $item['icon']; // Set value icon as global icon unset($item['icon']); } if (in_array($k, $item['value'])) { if (!($k === '' && $entry['name'] === '')) { if ($item['icon']) { $entry['icon'] = $item['icon']; // Set value icon as global icon } // Element selected $entry['selected'] = TRUE; } } else { if ($entry['name'] == '[there is no data]') { $entry['disabled'] = TRUE; } } if (strlen($entry['name']) == 0 && $k !== '') { $entry['name'] = $k; } // if name still empty set it as value $values[$group][$value] = $entry; } // Generate optgroups for values foreach ($values as $group => $entries) { $optgroup[$group] = ''; foreach ($entries as $value => $entry) { $optgroup[$group] .= '<option value="' . $value . '"'; if (isset($entry['subtext']) && strlen($entry['subtext'])) { $optgroup[$group] .= ' data-subtext="' . $entry['subtext'] . '"'; } if ($entry['name'] == '[there is no data]') { $optgroup[$group] .= ' disabled="1"'; } if (isset($entry['class']) && $entry['class']) { $optgroup[$group] .= ' class="' . $entry['class'] . '"'; } else { if (isset($entry['style']) && $entry['style']) { $optgroup[$group] .= ' style="' . $entry['style'] . '"'; } else { if (isset($entry['color']) && $entry['color']) { $optgroup[$group] .= ' style="color:' . $entry['color'] . ' !important;"'; //$optgroup[$group] .= ' data-content="<span style=\'color: ' . $entry['color'] . '\'>' . $entry['name'] . '</span>"'; } } } // Icons if (isset($entry['icon']) && $entry['icon']) { $optgroup[$group] .= ' data-icon="' . $entry['icon'] . '"'; } // Disabled, Selected if (isset($entry['disabled']) && $entry['disabled']) { $optgroup[$group] .= ' disabled="1"'; } else { if (isset($entry['selected']) && $entry['selected']) { $optgroup[$group] .= ' selected'; } } $optgroup[$group] .= '>' . escape_html($entry['name']) . '</option> '; } } // If item groups passed, use order passed from it $optgroups = array_keys($optgroup); if (isset($item['groups'])) { $groups = array_intersect((array) $item['groups'], $optgroups); $optgroups = array_diff($optgroups, $groups); $optgroups = array_merge($groups, $optgroups); } if (count($optgroups) === 1) { // Single optgroup, do not use optgroup tags $string .= array_shift($optgroup); } else { // Multiple optgroups implode foreach ($optgroups as $group) { $entry = $optgroup[$group]; $label = $group !== '' ? ' label="' . $group . '"' : ''; $string .= '<optgroup' . $label . '>' . PHP_EOL; $string .= $entry; $string .= '</optgroup>' . PHP_EOL; } } $string .= PHP_EOL . ' </select>' . PHP_EOL; // End 'select' & 'multiselect' break; case 'submit': $button_type = 'submit'; $button_onclick = ''; $button_class = 'btn'; if (!empty($item['class'])) { if (!preg_match('/btn-(default|primary|success|info|warning|danger)/', $item['class'])) { // Add default class if custom class hot have it $button_class .= ' btn-default'; } $button_class .= ' ' . $item['class']; } else { $button_class .= ' btn-default'; } if ($item['right']) { $button_class .= ' pull-right'; } if ($item['form_id'] && $item['id'] == 'search') { // Note, used script form_to_path() stored in js/observium.js $button_type = 'button'; $button_onclick = " onclick=\"form_to_path('" . $item['form_id'] . "');\""; } $button_disabled = $item['disabled'] || $item['readonly']; if ($button_disabled) { $button_class .= ' disabled'; } $string .= ' <button id="' . $item['id'] . '" name="' . $item['id'] . '" type="' . $button_type . '"'; // Add tooltip data if ($item['tooltip']) { $button_class .= ' tooltip-from-element'; $string .= ' data-tooltip-id="tooltip-' . $item['id'] . '"'; $element_tooltip .= '<div id="tooltip-' . $item['id'] . '" style="display: none;">' . $item['tooltip'] . '</div>' . PHP_EOL; } //$string .= ' class="'.$button_class.' text-nowrap" style="line-height: 20px;"'.$button_onclick; $string .= ' class="' . $button_class . ' text-nowrap"' . $button_onclick; if ($button_disabled) { $string .= ' disabled="1"'; } if ($item['value']) { $string .= ' value="' . $item['value'] . '"'; } $string .= '>'; switch ($item['id']) { // Note. 'update' - use POST request, all other - use GET with generate url from js. case 'update': $button_icon = 'icon-refresh'; $button_name = 'Update'; break; default: $button_icon = 'icon-search'; $button_name = 'Search'; } $nbsp = 0; if (array_key_exists('icon', $item)) { $button_icon = trim($item['icon']); } if (strlen($button_icon)) { $string .= '<i class="' . $button_icon . '"></i>'; $nbsp++; } if (array_key_exists('name', $item)) { $button_name = trim($item['name']); } if (strlen($button_name)) { $nbsp++; } if ($nbsp == 2) { $string .= ' '; } $string .= $button_name . '</button>' . PHP_EOL; // End 'submit' break; case 'raw': case 'html': // Just add custom (raw) html element if (isset($item['html'])) { $string .= $item['html']; } else { $string .= '<span'; if (isset($item['class'])) { $string .= ' class="' . $item['class'] . '"'; } $string .= '>' . $item['value'] . '</span>'; } break; case 'newline': // Deprecated $string .= '<div class="clearfix" id="' . $item['id'] . '">'; $string .= $item['hr'] ? '<hr />' : '<hr style="border-width: 0px;" />'; $string .= '</div>' . PHP_EOL; // End 'newline' break; } return $string . $element_tooltip; }
function detect_browser($user_agent = NULL) { $ua_custom = !is_null($user_agent); // Used custom user agent? if (!$ua_custom && isset($GLOBALS['cache']['detect_browser'])) { //if (isset($_COOKIE['observium_screen_ratio']) && !isset($GLOBALS['cache']['detect_browser']['screen_resolution'])) //{ // r($_COOKIE); //} // Return cached info return $GLOBALS['cache']['detect_browser']; } $detect = new Mobile_Detect(); if ($ua_custom) { // Set custom User-Agent $detect->setUserAgent($user_agent); } else { $user_agent = $_SERVER['HTTP_USER_AGENT']; } // Default type and icon $type = 'generic'; $icon = 'icon-laptop'; if ($detect->isMobile()) { // Any phone device (exclude tablets). $type = 'mobile'; $icon = 'glyphicon glyphicon-phone'; if ($detect->isTablet()) { // Any tablet device. $type = 'tablet'; $icon = 'icon-tablet'; } } // Load additional function if (!function_exists('parse_user_agent')) { include_once $GLOBALS['config']['install_dir'] . '/libs/UserAgentParser.php'; } // Detect Browser name, version and platform $ua_info = parse_user_agent($user_agent); $detect_browser = array('user_agent' => $user_agent, 'type' => $type, 'icon' => $icon, 'browser_full' => $ua_info['browser'] . ' ' . preg_replace('/^([^\\.]+(?:\\.[^\\.]+)?).*$/', '\\1', $ua_info['version']), 'browser' => $ua_info['browser'], 'version' => $ua_info['version'], 'platform' => $ua_info['platform']); // For custom UA, do not cache and return only base User-Agent info if ($ua_custom) { return $detect_browser; } // Load screen and DPI detector. This set cookies with: // $_COOKIE['observium_screen_ratio'] - if ratio >= 2, than HiDPI screen is used // $_COOKIE['observium_screen_resolution'] - screen resolution 'width x height', ie: 1920x1080 // $_COOKIE['observium_screen_size'] - current window size (less than resolution) 'width x height', ie: 1097x456 register_html_resource('js', 'observium-screen.js'); // Additional browser info (screen_ratio, screen_size, svg) if ($ua_info['browser'] == 'Firefox' && version_compare($ua_info['version'], '47.0') < 0) { // Do not use srcset in FF, while issue open: // https://bugzilla.mozilla.org/show_bug.cgi?id=1149357 // Update, seems as in 47.0 partially fixed $zoom = 1; } else { if (isset($_COOKIE['observium_screen_ratio'])) { // Note, Opera uses ratio 1.5 $zoom = round($_COOKIE['observium_screen_ratio']); // Use int zoom } else { // If JS not supported or cookie not set, use default zoom 2 (for allow srcset) $zoom = 2; } } $detect_browser['screen_ratio'] = $zoom; //$detect_browser['svg'] = ($ua_info['browser'] == 'Firefox'); // SVG supported or allowed if (isset($_COOKIE['observium_screen_resolution'])) { $detect_browser['screen_resolution'] = $_COOKIE['observium_screen_resolution']; //$detect_browser['screen_size'] = $_COOKIE['observium_screen_size']; } $GLOBALS['cache']['detect_browser'] = $detect_browser; // Store to cache //r($GLOBALS['cache']['detect_browser']); return $GLOBALS['cache']['detect_browser']; }
<?php register_html_resource('js', 'd3.v3.min.js'); register_html_resource('js', 'donut-chart.js'); ?> <div class="col-md-12" style="padding: 5px 20px 20px 20px;"> <table style="width: 100%; background: none;"> <tr style="align: center;"> <td><div class="donut-chart" id="devices_chart"></div></td> <td><div class="donut-chart" id="ports_chart"></div></td> <td><div class="donut-chart" id="sensors_chart"></div></td> <td><div class="donut-chart" id="status_chart"></div></td> <td><div class="donut-chart" id="alerts_chart"></div></td> </tr> </table> </div> <script> // Object.create() polyfill if (typeof Object.create !== 'function') { Object.create = function(obj) { function F() {} F.prototype = obj; return new F(); }; } // Select containers var chartContainer_devices = document.querySelector('#devices_chart'); var chartContainer_ports = document.querySelector('#ports_chart'); var chartContainer_sensors = document.querySelector('#sensors_chart');
/** * Observium Network Management and Monitoring System * Copyright (C) 2006-2015, Adam Armstrong - http://www.observium.org * * @package observium * @subpackage webui * @author Adam Armstrong <*****@*****.**> * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ //r(auth_user_level_permissions($_SESSION['userlevel'])); if ($_SESSION['userlevel'] >= 7) { // Enable google code prettify register_html_resource('js', 'google-code-prettify.js'); register_html_resource('css', 'google-code-prettify.css'); // Print device config navbar $navbar = array(); $navbar['brand'] = "Config"; $navbar['class'] = "navbar-narrow"; $cmd_file = escapeshellarg($device_config_file); $rev = array('count' => 0); if (is_executable($config['svn'])) { //$svnlogs = external_exec($config['svn'] . ' log -q -l 8 ' . $device_config_file); // Last 8 entries $svnlogs = external_exec($config['svn'] . ' log -q ' . $cmd_file); foreach (explode("\n", $svnlogs) as $line) { // r1884 | rancid | 2014-09-19 19:50:12 +0400 (Fri, 19 Sep 2014) // ------------------------------------------------------------------------ if (preg_match('/r(?<rev>\\d+) \\| .+? \\| (?<date>[\\d\\-]+ [\\d:]+ [\\+\\-]?\\d+)/', $line, $matches)) { $rev['list'][] = array('rev' => $matches['rev'], 'date' => format_timestamp(trim($matches['date']))); $rev['count']++;
/** * Observium * * This file is part of Observium. * * @package observium * @subpackage web * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ if ($_SESSION['userlevel'] < 10) { print_error_permission(); return; } register_html_resource('js', 'clipboard.min.js'); register_html_resource('script', 'new Clipboard("#clipboard");'); // Load SQL config into $database_config load_sqlconfig($database_config); // cache default and config.php-defined values $defined_config = get_defined_settings(); $default_config = get_default_settings(); echo '<form id="settings" name="settings" method="post" action="" class="form form-inline">' . PHP_EOL; // Pretty inefficient looping everything if section != all, but meh // This is only done on this page, so there is no performance issue for the rest of Observium foreach ($config_subsections as $section => $subdata) { if (isset($config_sections[$section]['edition']) && $config_sections[$section]['edition'] != OBSERVIUM_EDITION) { // Skip sections not allowed for current Observium edition continue; } echo ' <div class="row"> <div class="col-md-12"> <!-- BEGIN SECTION ' . $section . ' -->' . PHP_EOL; if ($vars['section'] == 'all' || $vars['section'] == $section) {
// Determine type of web browser. $browser_type = detect_browser_type(); if ($browser_type == 'mobile' || $browser_type == 'tablet') { $_SESSION['touch'] = 'yes'; } if ($vars['touch'] == "yes") { $_SESSION['touch'] = 'yes'; } if ($vars['touch'] == "no") { unset($_SESSION['touch'], $vars['touch']); } if ($_SESSION['authenticated']) { $allow_mobile = in_array(detect_browser_type(), array('mobile', 'tablet')) ? $config['web_mouseover_mobile'] : TRUE; if ($config['web_mouseover'] && $allow_mobile) { // Enable qTip tooltips register_html_resource('js', 'jquery.qtip.min.js'); } // Do various queries which we use in multiple places include $config['html_dir'] . "/includes/cache-data.inc.php"; // Include navbar if ($vars['bare'] != "yes") { include $config['html_dir'] . "/includes/navbar.inc.php"; } } ?> <div class="container"> <?php if ($_SESSION['authenticated']) { if ($_SESSION['userlevel'] > 7) {
* * @package observium * @subpackage webui * @author Adam Armstrong <*****@*****.**> * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ register_html_title("Edit user"); if ($_SESSION['userlevel'] < 10) { print_error_permission(); return; } include $config['html_dir'] . "/pages/usermenu.inc.php"; // Load JS entity picker register_html_resource('js', 'tw-sack.js'); register_html_resource('js', 'observium-entities.js'); ?> <form method="post" action="" class="form form-inline"> <div class="navbar navbar-narrow"> <div class="navbar-inner"> <div class="container"> <a class="brand">Edit User</a> <ul class="nav"> <?php $user_list_sort = array_sort_by(auth_user_list(), 'level', SORT_DESC, SORT_NUMERIC, 'username', SORT_ASC, SORT_STRING); $user_list = array(); foreach ($user_list_sort as $entry) { humanize_user($entry); $user_list[$entry['user_id']] = $entry;
<?php /** * Observium * * This file is part of Observium. * * @package observium * @subpackage map * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ register_html_resource('css', 'leaflet.css'); register_html_resource('js', 'leaflet.js'); //register_html_resource('js', '/geo.php'); // [lat, lng], zoom if (is_numeric($config['frontpage']['map']['zoom']) && is_numeric($config['frontpage']['map']['center']['lat']) && is_numeric($config['frontpage']['map']['center']['lng'])) { // Manual zoom & map center $leaflet_init = '[' . $config['frontpage']['map']['center']['lat'] . ', ' . $config['frontpage']['map']['center']['lng'] . '], ' . $config['frontpage']['map']['zoom']; $leaflet_bounds = ''; } else { // Auto zoom $leaflet_init = '[0, -0], 2'; $leaflet_bounds = 'map.fitBounds(markers.getBounds(), { padding: [30, 30] });'; } switch ($config['frontpage']['map']['api']) { case 'mapbox': /* Requires API key. Configurable tile sources in future. L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>', maxZoom: 18,
/** * Display Devices Inventory. * * @param array $vars * @return none * */ function print_inventory($vars) { // On "Inventory" device tab display hierarchical list if ($vars['page'] == 'device' && is_numeric($vars['device']) && device_permitted($vars['device'])) { // DHTML expandable tree register_html_resource('js', 'mktree.js'); register_html_resource('css', 'mktree.css'); echo generate_box_open($vars['header']); echo '<table class="table table-striped table-condensed "><tr><td>'; echo '<div class="btn-group pull-right" style="margin-top:5px; margin-right: 5px;"> <button class="btn btn-small" onClick="expandTree(\'enttree\');return false;"><i class="icon-plus muted small"></i> Expand</button> <button class="btn btn-small" onClick="collapseTree(\'enttree\');return false;"><i class="icon-minus muted small"></i> Collapse</button> </div>'; echo '<div style="clear: left; margin: 5px;"><ul class="mktree" id="enttree" style="margin-left: -10px;">'; print_ent_physical(0, 0, "liOpen"); echo '</ul></div>'; echo '</td></tr></table>'; echo generate_box_close(); return TRUE; } // With pagination? (display page numbers in header) $pagination = isset($vars['pagination']) && $vars['pagination']; pagination($vars, 0, TRUE); // Get default pagesize/pageno $pageno = $vars['pageno']; $pagesize = $vars['pagesize']; $start = $pagesize * $pageno - $pagesize; $param = array(); $where = ' WHERE 1 '; foreach ($vars as $var => $value) { if ($value != '') { switch ($var) { case 'device': case 'device_id': $where .= generate_query_values($value, 'device_id'); break; case 'os': $where .= generate_query_values($value, 'os'); break; case 'parts': $where .= generate_query_values($value, 'entPhysicalModelName', 'LIKE'); break; case 'serial': $where .= generate_query_values($value, 'entPhysicalSerialNum', '%LIKE%'); break; case 'description': $where .= generate_query_values($value, 'entPhysicalDescr', '%LIKE%'); break; } } } // Show inventory only for permitted devices //$query_permitted = generate_query_permitted(array('device'), array('device_table' => 'D')); $query = 'FROM `entPhysical`'; $query .= ' LEFT JOIN `devices` USING(`device_id`) '; $query .= $where . $GLOBALS['cache']['where']['devices_permitted']; $query_count = 'SELECT COUNT(*) ' . $query; $query = 'SELECT * ' . $query; $query .= ' ORDER BY `hostname`'; $query .= " LIMIT {$start},{$pagesize}"; // Query inventories $entries = dbFetchRows($query, $param); // Query inventory count if ($pagination) { $count = dbFetchCell($query_count, $param); } $list = array('device' => FALSE); if (!isset($vars['device']) || empty($vars['device']) || $vars['page'] == 'inventory') { $list['device'] = TRUE; } $string = generate_box_open($vars['header']); $string .= '<table class="' . OBS_CLASS_TABLE_STRIPED . '">' . PHP_EOL; if (!$short) { $string .= ' <thead>' . PHP_EOL; $string .= ' <tr>' . PHP_EOL; if ($list['device']) { $string .= ' <th>Device</th>' . PHP_EOL; } $string .= ' <th>Name</th>' . PHP_EOL; $string .= ' <th>Description</th>' . PHP_EOL; $string .= ' <th>Part #</th>' . PHP_EOL; $string .= ' <th>Serial #</th>' . PHP_EOL; $string .= ' </tr>' . PHP_EOL; $string .= ' </thead>' . PHP_EOL; } $string .= ' <tbody>' . PHP_EOL; foreach ($entries as $entry) { $string .= ' <tr>' . PHP_EOL; if ($list['device']) { $string .= ' <td class="entity" style="white-space: nowrap">' . generate_device_link($entry, NULL, array('page' => 'device', 'tab' => 'entphysical')) . '</td>' . PHP_EOL; } if ($entry['ifIndex']) { $interface = get_port_by_ifIndex($entry['device_id'], $entry['ifIndex']); $entry['entPhysicalName'] = generate_port_link($interface); } elseif ($entry['entPhysicalClass'] == "sensor") { $sensor = dbFetchRow("SELECT * FROM `sensors` LEFT JOIN `sensors-state` USING(`sensor_id`)\n WHERE `device_id` = ? AND (`entPhysicalIndex` = ? OR `sensor_index` = ?)", array($entry['device_id'], $entry['entPhysicalIndex'], $entry['entPhysicalIndex'])); //$ent_text .= ' ('.$sensor['sensor_value'] .' '. $sensor['sensor_class'].')'; $entry['entPhysicalName'] = generate_entity_link('sensor', $sensor); } $string .= ' <td style="width: 160px;">' . $entry['entPhysicalName'] . '</td>' . PHP_EOL; $string .= ' <td>' . $entry['entPhysicalDescr'] . '</td>' . PHP_EOL; $string .= ' <td>' . $entry['entPhysicalModelName'] . '</td>' . PHP_EOL; $string .= ' <td>' . $entry['entPhysicalSerialNum'] . '</td>' . PHP_EOL; $string .= ' </tr>' . PHP_EOL; } $string .= ' </tbody>' . PHP_EOL; $string .= '</table>'; $string .= generate_box_close(); // Print pagination header if ($pagination) { $string = pagination($vars, $count) . $string . pagination($vars, $count); } $entries_allowed = array('entPhysical_id', 'device_id', 'entPhysicalIndex', 'entPhysicalDescr', 'entPhysicalClass', 'entPhysicalName', 'entPhysicalHardwareRev', 'entPhysicalFirmwareRev', 'entPhysicalSoftwareRev', 'entPhysicalAlias', 'entPhysicalAssetID', 'entPhysicalIsFRU', 'entPhysicalModelName', 'entPhysicalVendorType', 'entPhysicalSerialNum', 'entPhysicalContainedIn', 'entPhysicalParentRelPos', 'entPhysicalMfgName'); foreach ($entries as $entry) { $entries_cleaned[$entry['entPhysical_id']] = array_intersect_key($entry, array_flip($entries_allowed)); } // Print Inventories switch ($vars['format']) { case "csv": echo implode($entry, ", "); echo "\n"; break; default: echo $string; break; } }
<li class="dropdown hidden-xs"> <form id="searchform" class="navbar-search" action="#" style="margin-left: 5px; margin-right: 10px; margin-top: 5px; margin-bottom: -5px;"> <input style="width: 100px;" onkeyup="lookup(this.value);" onblur="$('#suggestions').fadeOut()" type="text" value="" class="dropdown-toggle" placeholder="Search" /> </form> <div id="suggestions" class="typeahead dropdown-menu"></div> </li> <?php // Script for go to first founded link in search register_html_resource('script', ' $(function() { $(\'form#searchform\').each(function() { $(this).find(\'input\').keypress(function(e) { if (e.which==10 || e.which==13) { //console.log($(\'div#suggestions > li > a\').first().prop(\'href\')); $(\'form#searchform\').prop(\'action\', $(\'div#suggestions > li > a\').first().prop(\'href\')); // Only submit if we actually have a suggestion to link to if ($(\'div#suggestions > li > a\').length > 0) { this.form.submit(); } } }); }); }); '); $ua = array('browser' => detect_browser_type()); if ($_SESSION['touch'] == "yes") { $ua['url'] = generate_url($vars, array('touch' => 'no')); } else { $ua['url'] = generate_url($vars, array('touch' => 'yes')); } if ($vars['touch'] == 'yes') { $ua['icon'] = 'glyphicon glyphicon-hand-up';