/** * Validates the input parameters for the get() method. * * @throws APIException if the input is invalid * * @param array $options * * @return void */ protected function validateGet(array $options) { $sourceValidator = new CLimitedSetValidator(array('values' => array_keys(eventSource()))); if (!$sourceValidator->validate($options['source'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect source value.')); } $objectValidator = new CLimitedSetValidator(array('values' => array_keys(eventObject()))); if (!$objectValidator->validate($options['object'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect object value.')); } $sourceObjectValidator = new CEventSourceObjectValidator(); if (!$sourceObjectValidator->validate(array('source' => $options['source'], 'object' => $options['object']))) { self::exception(ZBX_API_ERROR_PARAMETERS, $sourceObjectValidator->getError()); } }
/** * Returns true if the given $value is valid, or set's an error and returns false otherwise. * * * @param $condition * * @return bool */ public function validate($condition) { // build validators $timePeriodValidator = new CTimePeriodValidator(); $discoveryCheckTypeValidator = new CLimitedSetValidator(array('values' => array_keys(discovery_check_type2str()))); $discoveryObjectStatusValidator = new CLimitedSetValidator(array('values' => array_keys(discovery_object_status2str()))); $triggerSeverityValidator = new CLimitedSetValidator(array('values' => array(TRIGGER_SEVERITY_NOT_CLASSIFIED, TRIGGER_SEVERITY_INFORMATION, TRIGGER_SEVERITY_WARNING, TRIGGER_SEVERITY_AVERAGE, TRIGGER_SEVERITY_HIGH, TRIGGER_SEVERITY_DISASTER))); $discoveryObjectValidator = new CLimitedSetValidator(array('values' => array_keys(discovery_object2str()))); $triggerValueValidator = new CLimitedSetValidator(array('values' => array_keys(trigger_value2str()))); $eventTypeValidator = new CLimitedSetValidator(array('values' => array_keys(eventType()))); $conditionValue = $condition['value']; // validate condition values depending on condition type switch ($condition['conditiontype']) { case CONDITION_TYPE_HOST_GROUP: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_TEMPLATE: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_TRIGGER: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_HOST: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_DRULE: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_DCHECK: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_PROXY: if (!$conditionValue) { $this->setError(_('Empty action condition.')); } break; case CONDITION_TYPE_DOBJECT: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$discoveryObjectValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition discovery object.')); } break; case CONDITION_TYPE_TIME_PERIOD: if (!$timePeriodValidator->validate($conditionValue)) { $this->setError($timePeriodValidator->getError()); } break; case CONDITION_TYPE_DHOST_IP: $ipRangeValidator = new CIPRangeValidator(); if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$ipRangeValidator->validate($conditionValue)) { $this->setError($ipRangeValidator->getError()); } break; case CONDITION_TYPE_DSERVICE_TYPE: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$discoveryCheckTypeValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition discovery check.')); } break; case CONDITION_TYPE_DSERVICE_PORT: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!validate_port_list($conditionValue)) { $this->setError(_s('Incorrect action condition port "%1$s".', $conditionValue)); } break; case CONDITION_TYPE_DSTATUS: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$discoveryObjectStatusValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition discovery status.')); } break; case CONDITION_TYPE_MAINTENANCE: if (!zbx_empty($conditionValue)) { $this->setError(_('Maintenance action condition value must be empty.')); } break; case CONDITION_TYPE_TRIGGER_SEVERITY: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$triggerSeverityValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition trigger severity.')); } break; case CONDITION_TYPE_TRIGGER_VALUE: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$triggerValueValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition trigger value.')); } break; case CONDITION_TYPE_EVENT_TYPE: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } elseif (!$eventTypeValidator->validate($conditionValue)) { $this->setError(_('Incorrect action condition event type.')); } break; case CONDITION_TYPE_TRIGGER_NAME: case CONDITION_TYPE_DUPTIME: case CONDITION_TYPE_DVALUE: case CONDITION_TYPE_APPLICATION: case CONDITION_TYPE_HOST_NAME: case CONDITION_TYPE_HOST_METADATA: if (zbx_empty($conditionValue)) { $this->setError(_('Empty action condition.')); } break; default: $this->setError(_('Incorrect action condition type.')); } // If no error is not set, return true. return !(bool) $this->getError(); }
/** * Check required fields by type. Values for fields must not be empty. * * @param array $mediatype An array of media type data. * @param string $mediatype['description'] Name of the media type. * @param string $mediatype['type'] E-mail, Script, SMS, Jabber and Ez Texting. * * @throws APIException if the input is invalid. */ protected function checkRequiredFieldsByType(array $mediatype) { $type_validator = new CLimitedSetValidator(['values' => array_keys(media_type2str())]); if (!$type_validator->validate($mediatype['type'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['type'], 'type', $mediatype['description'])); } $required_fields_by_type = [MEDIA_TYPE_EMAIL => ['smtp_server', 'smtp_helo', 'smtp_email'], MEDIA_TYPE_EXEC => ['exec_path'], MEDIA_TYPE_SMS => ['gsm_modem'], MEDIA_TYPE_JABBER => ['username'], MEDIA_TYPE_EZ_TEXTING => ['exec_path', 'username']]; foreach ($required_fields_by_type[$mediatype['type']] as $field) { // Check if fields set on Create method. For update method they are checked when type is changed. if (!array_key_exists($field, $mediatype)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Field "%1$s" is required for media type "%2$s".', $field, $mediatype['description'])); } elseif (array_key_exists($field, $mediatype) && ($mediatype[$field] === '' || $mediatype[$field] === null)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Field "%1$s" is missing a value for media type "%2$s".', $field, $mediatype['description'])); } } }
/** * Validate the input parameters for the update() method. * * @param array $maps maps data array * @param array $db_maps db maps data array * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $maps, array $db_maps) { if (!$maps) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $user_data = self::$userData; // Validate given IDs. $this->checkObjectIds($maps, 'sysmapid', _('No "%1$s" given for map.'), _('Empty map ID.'), _('Incorrect map ID.')); $check_names = []; foreach ($maps as $map) { // Check if this map exists and user has write permissions. if (!array_key_exists($map['sysmapid'], $db_maps)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // Validate "name" field. if (array_key_exists('name', $map)) { if (is_array($map['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif ($map['name'] === '' || $map['name'] === null || $map['name'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Map name cannot be empty.')); } if ($db_maps[$map['sysmapid']]['name'] !== $map['name']) { $check_names[] = $map; } } } if ($check_names) { // Check for duplicate names. $duplicate = CArrayHelper::findDuplicate($check_names, 'name'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "name" value "%1$s" for map.', $duplicate['name'])); } $db_map_names = $this->get(['output' => ['sysmapid', 'name'], 'filter' => ['name' => zbx_objectValues($check_names, 'name')], 'nopermissions' => true]); $db_map_names = zbx_toHash($db_map_names, 'name'); // Check for existing names. foreach ($check_names as $map) { if (array_key_exists($map['name'], $db_map_names) && bccomp($db_map_names[$map['name']]['sysmapid'], $map['sysmapid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" already exists.', $map['name'])); } } } $private_validator = new CLimitedSetValidator(['values' => [PUBLIC_SHARING, PRIVATE_SHARING]]); $permission_validator = new CLimitedSetValidator(['values' => [PERM_READ, PERM_READ_WRITE]]); foreach ($maps as $map) { // Check if owner can be set. if (array_key_exists('userid', $map)) { if ($map['userid'] === '' || $map['userid'] === null || $map['userid'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Map owner cannot be empty.')); } elseif ($map['userid'] != $user_data['userid'] && $user_data['type'] != USER_TYPE_SUPER_ADMIN && $user_data['type'] != USER_TYPE_ZABBIX_ADMIN) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Only administrators can set map owner.')); } } // Unset extra field. unset($db_maps[$map['sysmapid']]['userid']); $map = array_merge($db_maps[$map['sysmapid']], $map); // Check "width" and "height" fields. if ($map['width'] > 65535 || $map['width'] < 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "width" value for map "%1$s".', $map['name'])); } if ($map['height'] > 65535 || $map['height'] < 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "height" value for map "%1$s".', $map['name'])); } if (!$private_validator->validate($map['private'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "private" value "%1$s" for map "%2$s".', $map['private'], $map['name'])); } $userids = []; // Map user shares. if (array_key_exists('users', $map)) { if (!is_array($map['users'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $required_fields = ['userid', 'permission']; foreach ($map['users'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User sharing is missing parameters: %1$s for map "%2$s".', implode(', ', $missing_keys), $map['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for map "%2$s".', $field, $map['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in users for map "%2$s".', $share['permission'], $map['name'])); } if ($map['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" is public and read-only sharing is disallowed.', $map['name'])); } if (array_key_exists($share['userid'], $userids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate userid "%1$s" in users for map "%2$s".', $share['userid'], $map['name'])); } $userids[$share['userid']] = $share['userid']; } } if (array_key_exists('userid', $map) && $map['userid']) { $userids[$map['userid']] = $map['userid']; } // Users validation. if ($userids) { $db_users = API::User()->get(['userids' => $userids, 'countOutput' => true]); if (count($userids) != $db_users) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user ID specified for map "%1$s".', $map['name'])); } } // Map user group shares. if (array_key_exists('userGroups', $map)) { if (!is_array($map['userGroups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $shared_user_groupids = []; $required_fields = ['usrgrpid', 'permission']; foreach ($map['userGroups'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group sharing is missing parameters: %1$s for map "%2$s".', implode(', ', $missing_keys), $map['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for map "%2$s".', $field, $map['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in user groups for map "%2$s".', $share['permission'], $map['name'])); } if ($map['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" is public and read-only sharing is disallowed.', $map['name'])); } if (array_key_exists($share['usrgrpid'], $shared_user_groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate usrgrpid "%1$s" in user groups for map "%2$s".', $share['usrgrpid'], $map['name'])); } $shared_user_groupids[$share['usrgrpid']] = $share['usrgrpid']; } if ($shared_user_groupids) { $db_user_groups = API::UserGroup()->get(['usrgrpids' => $shared_user_groupids, 'countOutput' => true]); if (count($shared_user_groupids) != $db_user_groups) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user group ID specified for map "%1$s".', $map['name'])); } } unset($shared_user_groupids); } // Map labels. $map_labels = ['label_type' => ['typeName' => _('icon')]]; if (array_key_exists('label_format', $map) && $map['label_format'] == SYSMAP_LABEL_ADVANCED_ON) { $map_labels['label_type_hostgroup'] = ['string' => 'label_string_hostgroup', 'typeName' => _('host group')]; $map_labels['label_type_host'] = ['string' => 'label_string_host', 'typeName' => _('host')]; $map_labels['label_type_trigger'] = ['string' => 'label_string_trigger', 'typeName' => _('trigger')]; $map_labels['label_type_map'] = ['string' => 'label_string_map', 'typeName' => _('map')]; $map_labels['label_type_image'] = ['string' => 'label_string_image', 'typeName' => _('image')]; } foreach ($map_labels as $label_name => $labelData) { if (!array_key_exists($label_name, $map)) { continue; } if (sysmapElementLabel($map[$label_name]) === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if ($map[$label_name] == MAP_LABEL_TYPE_CUSTOM) { if (!array_key_exists('string', $labelData)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if (!array_key_exists($labelData['string'], $map) || zbx_empty($map[$labelData['string']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Custom label for map "%2$s" elements of type "%1$s" may not be empty.', $labelData['typeName'], $map['name'])); } } if ($label_name === 'label_type_image' && $map[$label_name] == MAP_LABEL_TYPE_STATUS) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if ($label_name === 'label_type' || $label_name === 'label_type_host') { continue; } if ($map[$label_name] == MAP_LABEL_TYPE_IP) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } } // Validating grid options. $possibleGridSizes = [20, 40, 50, 75, 100]; // Grid size. if (array_key_exists('grid_size', $map) && !in_array($map['grid_size'], $possibleGridSizes)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s".', $map['grid_size'], implode('", "', $possibleGridSizes))); } // Grid auto align. if (array_key_exists('grid_align', $map) && $map['grid_align'] != SYSMAP_GRID_ALIGN_ON && $map['grid_align'] != SYSMAP_GRID_ALIGN_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_align". Choices are: "%2$s" and "%3$s"', $map['grid_align'], SYSMAP_GRID_ALIGN_ON, SYSMAP_GRID_ALIGN_OFF)); } // Grid show. if (array_key_exists('grid_show', $map) && $map['grid_show'] != SYSMAP_GRID_SHOW_ON && $map['grid_show'] != SYSMAP_GRID_SHOW_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s" and "%3$s".', $map['grid_show'], SYSMAP_GRID_SHOW_ON, SYSMAP_GRID_SHOW_OFF)); } // Urls. if (array_key_exists('urls', $map) && !empty($map['urls'])) { $urlNames = zbx_toHash($map['urls'], 'name'); foreach ($map['urls'] as $url) { if ($url['name'] === '' || $url['url'] === '') { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL should have both "name" and "url" fields for map "%1$s".', $map['name'])); } if (!array_key_exists($url['name'], $urlNames)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL name should be unique for map "%1$s".', $map['name'])); } unset($urlNames[$url['name']]); } } if (array_key_exists('selements', $map) && !is_array($map['selements'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } // Map selement links. if (array_key_exists('links', $map) && $map['links']) { $selementids = zbx_objectValues($map['selements'], 'selementid'); foreach ($map['links'] as $link) { if (!in_array($link['selementid1'], $selementids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid1 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid1'], $map['name'])); } if (!in_array($link['selementid2'], $selementids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid2 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid2'], $map['name'])); } } } } }
/** * Validate items array for bar reports - IDs, color, permissions, etc. * Color validation for graph items is only for "Distribution of values for multiple periods" section ($config == 1). * Automatically set caption like item name if none is set. If no axis side is set, set LEFT side as default. * * @param array $items * * @return mixed valid items array on success or false on failure */ function validateBarReportItems($items = array()) { $config = getRequest('config', BR_DISTRIBUTION_MULTIPLE_PERIODS); if (!isset($items) || !$items) { return false; } $fields = array('itemid', 'calc_fnc'); if ($config == BR_DISTRIBUTION_MULTIPLE_PERIODS) { array_push($fields, 'color'); } foreach ($items as $item) { foreach ($fields as $field) { if (!isset($item[$field])) { show_error_message(_s('Missing "%1$s" field for item.', $field)); return false; } } $itemIds[$item['itemid']] = $item['itemid']; } $validItems = API::Item()->get(array('output' => array('itemid', 'hostid', 'name', 'key_', 'value_type'), 'selectHosts' => array('name'), 'webitems' => true, 'itemids' => $itemIds, 'preservekeys' => true)); $items = zbx_toHash($items, 'itemid'); $allowedValueTypes = array(ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); foreach ($validItems as &$item) { if (!in_array($item['value_type'], $allowedValueTypes)) { show_error_message(_s('Cannot add a non-numeric item "%1$s".', $item['name'])); return false; } // add host name and set caption like item name for valid items $item['host'] = reset($item['hosts']); unset($item['hosts']); // if no caption set, set default caption like item name if (!isset($items[$item['itemid']]['caption']) || zbx_empty($items[$item['itemid']]['caption'])) { $item['caption'] = $item['name']; } else { $validItems[$item['itemid']]['caption'] = $items[$item['itemid']]['caption']; } if (!isset($items[$item['itemid']]['axisside']) || zbx_empty($items[$item['itemid']]['axisside'])) { $items[$item['itemid']]['axisside'] = GRAPH_YAXIS_SIDE_LEFT; } } unset($item); // check axis value. 0 = count $calcFncValidator = new CLimitedSetValidator(array('values' => array(0, CALC_FNC_MIN, CALC_FNC_AVG, CALC_FNC_MAX))); $axisValidator = new CLimitedSetValidator(array('values' => array(GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT))); if ($config == BR_DISTRIBUTION_MULTIPLE_PERIODS) { $colorValidator = new CColorValidator(); } foreach ($items as $item) { if (!$calcFncValidator->validate($item['calc_fnc'])) { show_error_message(_s('Incorrect value for field "%1$s".', 'calc_fnc')); return false; } if (!$axisValidator->validate($item['axisside'])) { show_error_message(_s('Incorrect value for field "%1$s".', 'axisside')); return false; } if ($config == BR_DISTRIBUTION_MULTIPLE_PERIODS) { if (!$colorValidator->validate($item['color'])) { show_error_message($colorValidator->getError()); return false; } $validItems[$item['itemid']]['color'] = $item['color']; } $validItems[$item['itemid']]['calc_fnc'] = $item['calc_fnc']; $validItems[$item['itemid']]['axisside'] = $item['axisside']; } return $validItems; }
/** * Validates the input parameters for the update() method. * * @param array $screens * @param array $db_screens array of existing screens with screen IDs as keys. * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $screens, array $db_screens) { if (!$screens) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $user_data = self::$userData; // Validate given IDs. $this->checkObjectIds($screens, 'screenid', _('No "%1$s" given for screen.'), _('Empty screen ID.'), _('Incorrect screen ID.')); $check_names = []; foreach ($screens as $screen) { $this->validateScreenSize($screen); if (!array_key_exists($screen['screenid'], $db_screens)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } $screens = $this->extendFromObjects(zbx_toHash($screens, 'screenid'), $db_screens, ['name']); foreach ($screens as $screen) { // "templateid" is not allowed if (array_key_exists('templateid', $screen)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot update "templateid" for screen "%1$s".', $screen['name'])); } if (array_key_exists('name', $screen)) { // Validate "name" field. if (array_key_exists('name', $screen)) { if (is_array($screen['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif ($screen['name'] === '' || $screen['name'] === null || $screen['name'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Screen name cannot be empty.')); } if ($db_screens[$screen['screenid']]['name'] !== $screen['name']) { $check_names[] = $screen; } } } } if ($check_names) { // Check for duplicate names. $duplicate = CArrayHelper::findDuplicate($check_names, 'name'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "name" value "%1$s" for screen.', $duplicate['name'])); } $db_screen_names = $this->get(['output' => ['screenid', 'name'], 'filter' => ['name' => zbx_objectValues($check_names, 'name')], 'nopermissions' => true]); $db_screen_names = zbx_toHash($db_screen_names, 'name'); // Check for existing names. foreach ($check_names as $screen) { if (array_key_exists($screen['name'], $db_screen_names) && bccomp($db_screen_names[$screen['name']]['screenid'], $screen['screenid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" already exists.', $screen['name'])); } } } $private_validator = new CLimitedSetValidator(['values' => [PUBLIC_SHARING, PRIVATE_SHARING]]); $permission_validator = new CLimitedSetValidator(['values' => [PERM_READ, PERM_READ_WRITE]]); foreach ($screens as $screen) { // Check if owner can be set. if (array_key_exists('userid', $screen)) { if ($screen['userid'] === '' || $screen['userid'] === null || $screen['userid'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Screen owner cannot be empty.')); } elseif ($screen['userid'] != $user_data['userid'] && $user_data['type'] != USER_TYPE_SUPER_ADMIN && $user_data['type'] != USER_TYPE_ZABBIX_ADMIN) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Only administrators can set screen owner.')); } } // Unset extra field. unset($db_screens[$screen['screenid']]['userid']); $screen = array_merge($db_screens[$screen['screenid']], $screen); if (!$private_validator->validate($screen['private'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "private" value "%1$s" for screen "%2$s".', $screen['private'], $screen['name'])); } $userids = []; // Screen user shares. if (array_key_exists('users', $screen)) { if (!is_array($screen['users'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $required_fields = ['userid', 'permission']; foreach ($screen['users'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User sharing is missing parameters: %1$s for screen "%2$s".', implode(', ', $missing_keys), $screen['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for screen "%2$s".', $field, $screen['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in users for screen "%2$s".', $share['permission'], $screen['name'])); } if ($screen['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" is public and read-only sharing is disallowed.', $screen['name'])); } if (array_key_exists($share['userid'], $userids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate userid "%1$s" in users for screen "%2$s".', $share['userid'], $screen['name'])); } $userids[$share['userid']] = $share['userid']; } } if (array_key_exists('userid', $screen) && $screen['userid']) { $userids[$screen['userid']] = $screen['userid']; } // Users validation. if ($userids) { $db_users = API::User()->get(['userids' => $userids, 'countOutput' => true]); if (count($userids) != $db_users) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user ID specified for screen "%1$s".', $screen['name'])); } } // Screen user group shares. if (array_key_exists('userGroups', $screen)) { if (!is_array($screen['userGroups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $shared_user_groupids = []; $required_fields = ['usrgrpid', 'permission']; foreach ($screen['userGroups'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group sharing is missing parameters: %1$s for screen "%2$s".', implode(', ', $missing_keys), $screen['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for screen "%2$s".', $field, $screen['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in user groups for screen "%2$s".', $share['permission'], $screen['name'])); } if ($screen['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" is public and read-only sharing is disallowed.', $screen['name'])); } if (array_key_exists($share['usrgrpid'], $shared_user_groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate usrgrpid "%1$s" in user groups for screen "%2$s".', $share['usrgrpid'], $screen['name'])); } $shared_user_groupids[$share['usrgrpid']] = $share['usrgrpid']; } if ($shared_user_groupids) { $db_user_groups = API::UserGroup()->get(['usrgrpids' => $shared_user_groupids, 'countOutput' => true]); if (count($shared_user_groupids) != $db_user_groups) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user group ID specified for screen "%1$s".', $screen['name'])); } } unset($shared_user_groupids); } } }