You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
15 KiB
459 lines
15 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** 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; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** 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.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
class CMultiSelect extends CTag {
|
|
/**
|
|
* Default CSS class name for HTML root element.
|
|
*/
|
|
const ZBX_STYLE_CLASS = 'multiselect-control';
|
|
|
|
/**
|
|
* Search method used for autocomplete requests.
|
|
*/
|
|
const SEARCH_METHOD = 'multiselect.get';
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $params = [];
|
|
|
|
/**
|
|
* @param array $options['objectOptions'] An array of parameters to be added to the request URL.
|
|
* @param bool $options['multiple'] Allows multiple selections.
|
|
* @param bool $options['add_post_js']
|
|
*
|
|
* @see jQuery.multiSelect()
|
|
*/
|
|
public function __construct(array $options = []) {
|
|
parent::__construct('div', true);
|
|
|
|
$options = $this->mapOptions($options);
|
|
|
|
$this
|
|
->setId(zbx_formatDomId($options['name']))
|
|
->addClass('multiselect')
|
|
->setAttribute('role', 'application')
|
|
->addItem((new CDiv())
|
|
->setAttribute('aria-live', 'assertive')
|
|
->setAttribute('aria-atomic', 'true')
|
|
);
|
|
|
|
if (array_key_exists('disabled', $options) && $options['disabled']) {
|
|
$this->setAttribute('aria-disabled', 'true');
|
|
}
|
|
|
|
// Autocomplete url.
|
|
$url = (new CUrl('jsrpc.php'))
|
|
->setArgument('type', PAGE_TYPE_TEXT_RETURN_JSON)
|
|
->setArgument('method', static::SEARCH_METHOD)
|
|
->setArgument('object_name', $options['object_name']);
|
|
|
|
if (array_key_exists('objectOptions', $options)) {
|
|
foreach ($options['objectOptions'] as $option_name => $option_value) {
|
|
$url->setArgument($option_name, $option_value);
|
|
}
|
|
}
|
|
|
|
$params = [
|
|
'url' => $url->getUrl(),
|
|
'name' => $options['name'],
|
|
'labels' => [
|
|
'No matches found' => _('No matches found'),
|
|
'More matches found...' => _('More matches found...'),
|
|
'type here to search' => _('type here to search'),
|
|
'new' => _('new'),
|
|
'Select' => _('Select')
|
|
]
|
|
];
|
|
|
|
if (array_key_exists('data', $options)) {
|
|
$params['data'] = zbx_cleanHashes($options['data']);
|
|
}
|
|
|
|
foreach (['defaultValue', 'disabled', 'selectedLimit', 'addNew', 'styles', 'placeholder', 'hidden'] as $option) {
|
|
if (array_key_exists($option, $options)) {
|
|
$params[$option] = $options[$option];
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('autosuggest', $options)
|
|
&& array_key_exists('filter_preselect', $options['autosuggest'])) {
|
|
$params['autosuggest']['filter_preselect'] = $options['autosuggest']['filter_preselect'];
|
|
}
|
|
|
|
if (array_key_exists('custom_select', $options)) {
|
|
$params['custom_select'] = $options['custom_select'];
|
|
}
|
|
elseif (array_key_exists('popup', $options)) {
|
|
if (array_key_exists('filter_preselect', $options['popup'])) {
|
|
$params['popup']['filter_preselect'] = $options['popup']['filter_preselect'];
|
|
}
|
|
|
|
if (array_key_exists('parameters', $options['popup'])) {
|
|
$params['popup']['parameters'] = $options['popup']['parameters'];
|
|
|
|
$excludeids = array_key_exists('excludeids', $options['popup']['parameters'])
|
|
? $options['popup']['parameters']['excludeids']
|
|
: [];
|
|
|
|
$excludeids = array_merge($excludeids, array_key_exists('disableids', $options['popup']['parameters'])
|
|
? $options['popup']['parameters']['disableids']
|
|
: []);
|
|
|
|
if ($excludeids) {
|
|
$params['excludeids'] = $excludeids;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->params = $params;
|
|
|
|
if (!array_key_exists('add_post_js', $options) || $options['add_post_js']) {
|
|
zbx_add_post_js($this->getPostJS());
|
|
}
|
|
}
|
|
|
|
public function setWidth($value) {
|
|
$this->addStyle('width: '.$value.'px;');
|
|
return $this;
|
|
}
|
|
|
|
public function getPostJS() {
|
|
return 'jQuery("#'.$this->getAttribute('id').'").multiSelect('.json_encode($this->params).');';
|
|
}
|
|
|
|
/**
|
|
* Multiselect options mapper for backward compatibility.
|
|
*
|
|
* @param array $options
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function mapOptions(array $options) {
|
|
$valid_fields = ['name', 'object_name', 'multiple', 'disabled', 'default_value', 'data', 'add_new',
|
|
'add_post_js', 'styles', 'popup', 'custom_select', 'placeholder', 'autosuggest', 'hidden'
|
|
];
|
|
|
|
foreach ($options as $field => $value) {
|
|
if (!in_array($field, $valid_fields)) {
|
|
error('unsupported multiselect option: $options[\''.$field.'\']');
|
|
}
|
|
}
|
|
|
|
$mapped_options = [];
|
|
$mappings = [
|
|
'name' => 'name',
|
|
'object_name' => 'object_name',
|
|
'disabled' => 'disabled',
|
|
'hidden' => 'hidden',
|
|
'default_value' => 'defaultValue',
|
|
'data' => 'data',
|
|
'add_new' => 'addNew',
|
|
'add_post_js' => 'add_post_js',
|
|
'styles' => 'styles',
|
|
'placeholder' => 'placeholder'
|
|
];
|
|
|
|
foreach ($mappings as $new_field => $old_field) {
|
|
if (array_key_exists($new_field, $options)) {
|
|
$mapped_options[$old_field] = $options[$new_field];
|
|
}
|
|
}
|
|
|
|
$multiple = array_key_exists('multiple', $options) ? $options['multiple'] : true;
|
|
if (!$multiple) {
|
|
$mapped_options['selectedLimit'] = '1';
|
|
}
|
|
|
|
if (array_key_exists('autosuggest', $options)) {
|
|
$valid_fields = ['filter_preselect'];
|
|
|
|
foreach (array_keys($options['autosuggest']) as $field) {
|
|
if (!in_array($field, $valid_fields)) {
|
|
error('unsupported option: $options[\'autosuggest\'][\''.$field.'\']');
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('filter_preselect', $options['autosuggest'])) {
|
|
if (is_array($options['autosuggest']['filter_preselect'])) {
|
|
if (self::validateFilterPreselect($options['autosuggest']['filter_preselect'],
|
|
'$options[\'autosuggest\'][\'filter_preselect\']')) {
|
|
$mapped_options['autosuggest']['filter_preselect']
|
|
= $options['autosuggest']['filter_preselect'];
|
|
}
|
|
}
|
|
else {
|
|
error('invalid property: $options[\'autosuggest\'][\'filter_preselect\']');
|
|
}
|
|
}
|
|
}
|
|
|
|
$autocomplete_parameters = [];
|
|
|
|
if (array_key_exists('custom_select', $options)) {
|
|
$mapped_options['custom_select'] = true;
|
|
}
|
|
elseif (array_key_exists('popup', $options)) {
|
|
$valid_fields = ['parameters', 'filter_preselect'];
|
|
|
|
foreach (array_keys($options['popup']) as $field) {
|
|
if (!in_array($field, $valid_fields)) {
|
|
error('unsupported option: $options[\'popup\'][\''.$field.'\']');
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('filter_preselect', $options['popup'])) {
|
|
if (is_array($options['popup']['filter_preselect'])) {
|
|
if (self::validateFilterPreselect($options['popup']['filter_preselect'],
|
|
'$options[\'popup\'][\'filter_preselect\']')) {
|
|
$mapped_options['popup']['filter_preselect'] = $options['popup']['filter_preselect'];
|
|
}
|
|
}
|
|
else {
|
|
error('invalid property: $options[\'popup\'][\'filter_preselect\']');
|
|
}
|
|
}
|
|
|
|
$popup_parameters = [];
|
|
|
|
if (array_key_exists('parameters', $options['popup'])) {
|
|
$parameters = $options['popup']['parameters'];
|
|
|
|
$valid_fields = ['srctbl', 'srcfld1', 'srcfld2', 'dstfrm', 'dstfld1', 'real_hosts', 'with_hosts',
|
|
'monitored_hosts', 'with_monitored_triggers', 'editable', 'templated_hosts', 'with_templates',
|
|
'hostid', 'parent_discoveryid', 'normal_only', 'numeric', 'with_graphs', 'with_graph_prototypes',
|
|
'with_items', 'with_simple_graph_items', 'with_simple_graph_item_prototypes', 'with_triggers',
|
|
'value_types', 'excludeids', 'disableids', 'enrich_parent_groups', 'with_monitored_items',
|
|
'with_httptests', 'user_type', 'disable_selected', 'hostids', 'with_inherited', 'context',
|
|
'enabled_only', 'group_status', 'hide_host_filter'
|
|
];
|
|
|
|
foreach ($parameters as $field => $value) {
|
|
if (!in_array($field, $valid_fields)) {
|
|
error('unsupported option: $options[\'popup\'][\'parameters\'][\''.$field.'\']');
|
|
}
|
|
}
|
|
|
|
$mappings = [
|
|
'srctbl' => 'srctbl',
|
|
'srcfld1' => 'srcfld1',
|
|
'srcfld2' => 'srcfld2',
|
|
'dstfrm' => 'dstfrm',
|
|
'dstfld1' => 'dstfld1'
|
|
];
|
|
|
|
foreach ($mappings as $new_field => $old_field) {
|
|
if (array_key_exists($new_field, $parameters)) {
|
|
$popup_parameters[$old_field] = $parameters[$new_field];
|
|
}
|
|
}
|
|
|
|
if ($multiple) {
|
|
$popup_parameters['multiselect'] = '1';
|
|
}
|
|
|
|
if (array_key_exists('hostid', $parameters) && $parameters['hostid'] > 0) {
|
|
$popup_parameters['only_hostid'] = (string) $parameters['hostid'];
|
|
$autocomplete_parameters['hostid'] = (string) $parameters['hostid'];
|
|
}
|
|
|
|
if (array_key_exists('hide_host_filter', $parameters)) {
|
|
$popup_parameters['hide_host_filter'] = '1';
|
|
}
|
|
|
|
if (array_key_exists('groupid', $parameters) && $parameters['groupid'] > 0) {
|
|
$popup_parameters['groupid'] = (string) $parameters['groupid'];
|
|
}
|
|
|
|
if (array_key_exists('parent_discoveryid', $parameters) && $parameters['parent_discoveryid'] > 0) {
|
|
$popup_parameters['parent_discoveryid'] = $parameters['parent_discoveryid'];
|
|
$autocomplete_parameters['parent_discoveryid'] = $parameters['parent_discoveryid'];
|
|
}
|
|
|
|
if (array_key_exists('numeric', $parameters) && $parameters['numeric']) {
|
|
$popup_parameters['numeric'] = '1';
|
|
$autocomplete_parameters['filter']['value_type'] = [ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64];
|
|
}
|
|
|
|
if (array_key_exists('normal_only', $parameters) && $parameters['normal_only']) {
|
|
$popup_parameters['normal_only'] = '1';
|
|
$autocomplete_parameters['filter']['flags'] = ZBX_FLAG_DISCOVERY_NORMAL;
|
|
}
|
|
|
|
if (array_key_exists('value_types', $parameters)) {
|
|
$popup_parameters['value_types'] = $parameters['value_types'];
|
|
$autocomplete_parameters['filter']['value_type'] = $parameters['value_types'];
|
|
}
|
|
|
|
if (array_key_exists('real_hosts', $parameters) && $parameters['real_hosts']) {
|
|
$popup_parameters['real_hosts'] = '1';
|
|
$autocomplete_parameters['real_hosts'] = true;
|
|
}
|
|
|
|
if (array_key_exists('with_hosts', $parameters) && $parameters['with_hosts']) {
|
|
$popup_parameters['real_hosts'] = '1';
|
|
$autocomplete_parameters['with_hosts'] = true;
|
|
}
|
|
|
|
if (array_key_exists('templated_hosts', $parameters) && $parameters['templated_hosts']) {
|
|
$popup_parameters['templated_hosts'] = '1';
|
|
$autocomplete_parameters['templated_hosts'] = true;
|
|
}
|
|
|
|
if ($popup_parameters['srctbl'] == 'template_triggers') {
|
|
$autocomplete_parameters['templated'] = true;
|
|
}
|
|
|
|
if (array_key_exists('with_templates', $parameters) && $parameters['with_templates']) {
|
|
$popup_parameters['templated_hosts'] = '1';
|
|
$autocomplete_parameters['with_templates'] = true;
|
|
}
|
|
|
|
foreach (['with_graphs', 'with_graph_prototypes', 'with_simple_graph_items',
|
|
'with_simple_graph_item_prototypes', 'with_triggers', 'with_inherited'] as $name) {
|
|
if (array_key_exists($name, $parameters) && $parameters[$name]) {
|
|
$popup_parameters[$name] = '1';
|
|
$autocomplete_parameters[$name] = true;
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('editable', $parameters) && $parameters['editable']) {
|
|
$popup_parameters['writeonly'] = '1';
|
|
$autocomplete_parameters['editable'] = true;
|
|
}
|
|
|
|
if (array_key_exists('monitored_hosts', $parameters) && $parameters['monitored_hosts']) {
|
|
$popup_parameters['monitored_hosts'] = '1';
|
|
$autocomplete_parameters['monitored'] = true;
|
|
}
|
|
|
|
if (array_key_exists('with_monitored_triggers', $parameters) && $parameters['with_monitored_triggers']) {
|
|
$popup_parameters['with_monitored_triggers'] = '1';
|
|
|
|
if ($popup_parameters['srctbl'] === 'triggers') {
|
|
$autocomplete_parameters['monitored'] = true;
|
|
}
|
|
else {
|
|
$autocomplete_parameters['with_monitored_triggers'] = true;
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('with_monitored_items', $parameters) && $parameters['with_monitored_items']) {
|
|
$popup_parameters['with_monitored_items'] = '1';
|
|
$autocomplete_parameters['with_monitored_items'] = true;
|
|
}
|
|
|
|
if (array_key_exists('with_httptests', $parameters) && $parameters['with_httptests']) {
|
|
$popup_parameters['with_httptests'] = '1';
|
|
$autocomplete_parameters['with_httptests'] = true;
|
|
}
|
|
|
|
if (array_key_exists('with_items', $parameters) && $parameters['with_items']) {
|
|
$popup_parameters['with_items'] = '1';
|
|
$autocomplete_parameters['with_items'] = true;
|
|
}
|
|
|
|
if (array_key_exists('excludeids', $parameters) && $parameters['excludeids']) {
|
|
$popup_parameters['excludeids'] = $parameters['excludeids'];
|
|
}
|
|
|
|
if (array_key_exists('disableids', $parameters) && $parameters['disableids']) {
|
|
$popup_parameters['disableids'] = $parameters['disableids'];
|
|
}
|
|
|
|
if (array_key_exists('enrich_parent_groups', $parameters) && $parameters['enrich_parent_groups']) {
|
|
$popup_parameters['enrich_parent_groups'] = '1';
|
|
$autocomplete_parameters['enrich_parent_groups'] = true;
|
|
}
|
|
|
|
if (array_key_exists('user_type', $parameters) && $parameters['user_type']) {
|
|
$popup_parameters['user_type'] = (int) $parameters['user_type'];
|
|
$autocomplete_parameters['user_type'] = (int) $parameters['user_type'];
|
|
}
|
|
|
|
if (array_key_exists('disable_selected', $parameters) && $parameters['disable_selected']) {
|
|
$popup_parameters['disable_selected'] = '1';
|
|
}
|
|
|
|
if (array_key_exists('hostids', $parameters) && $parameters['hostids']) {
|
|
$popup_parameters['hostids'] = $parameters['hostids'];
|
|
$autocomplete_parameters['hostids'] = $parameters['hostids'];
|
|
}
|
|
|
|
if (array_key_exists('context', $parameters)) {
|
|
$popup_parameters['context'] = $parameters['context'];
|
|
$autocomplete_parameters['context'] = $parameters['context'];
|
|
}
|
|
|
|
if (array_key_exists('enabled_only', $parameters) && $parameters['enabled_only']) {
|
|
$popup_parameters['enabled_only'] = '1';
|
|
$autocomplete_parameters['enabled_only'] = true;
|
|
}
|
|
|
|
if (array_key_exists('group_status', $parameters)) {
|
|
$popup_parameters['group_status'] = $parameters['group_status'];
|
|
$autocomplete_parameters['group_status'] = $parameters['group_status'];
|
|
}
|
|
}
|
|
|
|
$mapped_options['popup']['parameters'] = $popup_parameters;
|
|
}
|
|
|
|
$mapped_options['objectOptions'] = $autocomplete_parameters;
|
|
|
|
return $mapped_options;
|
|
}
|
|
|
|
protected static function validateFilterPreselect(array $field, string $path): bool {
|
|
$is_valid = true;
|
|
|
|
foreach (array_keys($field) as $option) {
|
|
if (!in_array($option, ['id', 'submit_as', 'submit_parameters', 'multiple'])) {
|
|
error('unsupported option: '.$path.'[\''.$option.'\']');
|
|
$is_valid = false;
|
|
}
|
|
}
|
|
|
|
if (!array_key_exists('id', $field) || !is_string($field['id']) || $field['id'] === '') {
|
|
error('invalid property: '.$path.'[\'id\']');
|
|
$is_valid = false;
|
|
}
|
|
|
|
if (array_key_exists('submit_as', $field)
|
|
&& (!is_string($field['submit_as']) || $field['submit_as'] === '')) {
|
|
error('invalid property: '.$path.'[\'submit_as\']');
|
|
$is_valid = false;
|
|
}
|
|
|
|
if (array_key_exists('submit_parameters', $field) && !is_array($field['submit_parameters'])) {
|
|
error('invalid property: '.$path.'[\'submit_parameters\']');
|
|
$is_valid = false;
|
|
}
|
|
|
|
if (array_key_exists('multiple', $field) && !is_bool($field['multiple'])) {
|
|
error('invalid property: '.$path.'[\'multiple\']');
|
|
$is_valid = false;
|
|
}
|
|
|
|
return $is_valid;
|
|
}
|
|
}
|