public function checkExpression($expression) { $length = zbx_strlen($expression); $symbolNum = 0; try { if (zbx_empty(trim($expression))) { throw new Exception('Empty expression.'); } // Check expr start symbol $startSymbol = zbx_substr(trim($expression), 0, 1); if ($startSymbol != '(' && $startSymbol != '{' && $startSymbol != '-' && !zbx_ctype_digit($startSymbol)) { throw new Exception('Incorrect trigger expression.'); } for ($symbolNum = 0; $symbolNum < $length; $symbolNum++) { $symbol = zbx_substr($expression, $symbolNum, 1); // SDI($symbol); $this->parseOpenParts($this->previous['last']); $this->parseCloseParts($symbol); // SDII($this->currExpr); if ($this->inParameter($symbol)) { $this->setPreviousSymbol($symbol); continue; } $this->checkSymbolSequence($symbol); $this->setPreviousSymbol($symbol); // SDII($this->symbols); } $symbolNum = 0; $simpleExpression = $expression; $this->checkBraces(); $this->checkParts($simpleExpression); $this->checkSimpleExpression($simpleExpression); } catch (Exception $e) { $symbolNum = $symbolNum > 0 ? --$symbolNum : $symbolNum; $this->errors[] = $e->getMessage(); $this->errors[] = 'Check expression part starting from " ' . zbx_substr($expression, $symbolNum) . ' "'; } }
function zbx_str2links($text) { $result = array(); if (zbx_empty($text)) { return $result; } preg_match_all('#https?://[^\\n\\t\\r ]+#u', $text, $matches, PREG_OFFSET_CAPTURE); $start = 0; foreach ($matches[0] as $match) { $result[] = zbx_substr($text, $start, $match[1] - $start); $result[] = new CLink($match[0], $match[0], null, null, true); $start = $match[1] + zbx_strlen($match[0]); } $result[] = zbx_substr($text, $start, zbx_strlen($text)); return $result; }
$itemFormList->addRow(_('Flexible intervals'), new CDiv($delayFlexTable, 'objectgroup inlineblock border_dotted ui-corner-all'), false, 'row_flex_intervals'); // append new flexible interval to form list $newFlexInt = new CSpan(array(_('Interval (in sec)'), SPACE, new CNumericBox('new_delay_flex[delay]', $this->data['new_delay_flex']['delay'], 5, 'no', false, false), SPACE, _('Period'), SPACE, new CTextBox('new_delay_flex[period]', $this->data['new_delay_flex']['period'], 20), SPACE, new CButton('add_delay_flex', _('Add'), null, 'formlist'))); $newFlexInt->setAttribute('id', 'row-new-delay-flex-fields'); $maxFlexMsg = new CSpan(_('Maximum number of flexible intervals added'), 'red'); $maxFlexMsg->setAttribute('id', 'row-new-delay-flex-max-reached'); $maxFlexMsg->setAttribute('style', 'display: none;'); $itemFormList->addRow(_('New flexible interval'), array($newFlexInt, $maxFlexMsg), false, 'row_new_delay_flex', 'new'); if ($this->data['is_discovery_rule']) { $itemFormList->addRow(_('Keep lost resources period (in days)'), new CTextBox('lifetime', $this->data['lifetime'], ZBX_TEXTBOX_SMALL_SIZE, false, 64)); // append filter to formlist if (!empty($this->data['filter'])) { // exploding filter to two parts: before first ':' and after $pos = zbx_strpos($this->data['filter'], ':'); $filter_macro = zbx_substr($this->data['filter'], 0, $pos); $filter_value = zbx_substr($this->data['filter'], $pos + 1); } else { $filter_macro = ''; $filter_value = ''; } $itemFormList->addRow(_('Filter'), array(_('Macro'), SPACE, new CTextBox('filter_macro', $filter_macro, 13), SPACE, _('Regexp'), SPACE, new CTextBox('filter_value', $filter_value, 20))); $itemFormList->addRow(_('Allowed hosts'), new CTextBox('trapper_hosts', $this->data['trapper_hosts'], ZBX_TEXTBOX_STANDARD_SIZE), false, 'row_trapper_hosts'); } else { $dataConfig = select_config(); $keepHistory = array(); $keepHistory[] = new CNumericBox('history', $this->data['history'], 8); if ($dataConfig['hk_history_global'] && !$data['parent_discoveryid'] && !$data['is_template']) { $keepHistory[] = SPACE; if (CWebUser::getType() == USER_TYPE_SUPER_ADMIN) { $keepHistory[] = new CSpan(_x('Overridden by', 'item_form')); $keepHistory[] = SPACE;
/** * Format item lastvalue depending on it's value type. * * @param array $item * * @return string */ function formatItemValueType(array $item) { if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT || $item['value_type'] == ITEM_VALUE_TYPE_UINT64) { $value = convert_units($item['lastvalue'], $item['units']); } elseif ($item['value_type'] == ITEM_VALUE_TYPE_STR || $item['value_type'] == ITEM_VALUE_TYPE_TEXT || $item['value_type'] == ITEM_VALUE_TYPE_LOG) { $value = $item['lastvalue']; if (zbx_strlen($value) > 20) { $value = zbx_substr($value, 0, 20) . ' ...'; } } else { $value = _('Unknown value type'); } return $value; }
/** * Format history value. * First format the value according to the configuration of the item. Then apply the value mapping to the formatted (!) * value. * * @param mixed $value * @param array $item * @param int $item['value_type'] type of the value: ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64, ... * @param string $item['units'] units of item * @param int $item['valuemapid'] id of mapping set of values * @param bool $trim * * @return string */ function formatHistoryValue($value, array $item, $trim = true) { $mapping = false; // format value if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT || $item['value_type'] == ITEM_VALUE_TYPE_UINT64) { $value = convert_units(array('value' => $value, 'units' => $item['units'])); } elseif ($item['value_type'] != ITEM_VALUE_TYPE_STR && $item['value_type'] != ITEM_VALUE_TYPE_TEXT && $item['value_type'] != ITEM_VALUE_TYPE_LOG) { $value = _('Unknown value type'); } // apply value mapping switch ($item['value_type']) { case ITEM_VALUE_TYPE_STR: $mapping = getMappedValue($value, $item['valuemapid']); // break; is not missing here // break; is not missing here case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: if ($trim && zbx_strlen($value) > 20) { $value = zbx_substr($value, 0, 20) . '...'; } if ($mapping !== false) { $value = $mapping . ' (' . $value . ')'; } break; default: $value = applyValueMap($value, $item['valuemapid']); } return $value; }
/** * Creates and returns a trigger status cell for the trigger overview table. * * @see get_triggers_overview() * * @param array $triggerHosts an array with the data about the trigger for each host * @param string $hostName the name of the cells corresponding host * @param string $screenId * * @return CCol */ function get_trigger_overview_cells($triggerHosts, $hostName, $screenId = null) { $ack = null; $css_class = null; $desc = array(); $config = select_config(); // for how long triggers should blink on status change (set by user in administration->general) if (isset($triggerHosts[$hostName])) { // problem trigger if ($triggerHosts[$hostName]['value'] == TRIGGER_VALUE_TRUE) { $css_class = getSeverityStyle($triggerHosts[$hostName]['priority']); $ack = null; if ($config['event_ack_enable'] == 1) { $event = get_last_event_by_triggerid($triggerHosts[$hostName]['triggerid']); if ($event) { if ($screenId) { global $page; $ack_menu = array(_('Acknowledge'), 'acknow.php?eventid=' . $event['eventid'] . '&screenid=' . $screenId . '&backurl=' . $page['file']); } else { $ack_menu = array(_('Acknowledge'), 'acknow.php?eventid=' . $event['eventid'] . '&backurl=overview.php', array('tw' => '_blank')); } if ($event['acknowledged'] == 1) { $ack = new CImg('images/general/tick.png', 'ack'); } } } } else { $css_class = 'normal'; } $style = 'cursor: pointer; '; // set blinking gif as background if trigger age is less then $config['blink_period'] if ($config['blink_period'] > 0 && time() - $triggerHosts[$hostName]['lastchange'] < $config['blink_period']) { $style .= 'background-image: url(images/gradients/blink.gif); background-position: top left; background-repeat: repeat;'; } unset($item_menu); $tr_ov_menu = array(array(_('Trigger'), null, null, array('outer' => array('pum_oheader'), 'inner' => array('pum_iheader'))), array(_('Events'), 'events.php?triggerid=' . $triggerHosts[$hostName]['triggerid'], array('tw' => '_blank'))); if (isset($ack_menu)) { $tr_ov_menu[] = $ack_menu; } $dbItems = DBselect('SELECT DISTINCT i.itemid,i.name,i.key_,i.value_type' . ' FROM items i,functions f' . ' WHERE f.itemid=i.itemid' . ' AND f.triggerid=' . $triggerHosts[$hostName]['triggerid']); while ($item = DBfetch($dbItems)) { $description = itemName($item); switch ($item['value_type']) { case ITEM_VALUE_TYPE_UINT64: case ITEM_VALUE_TYPE_FLOAT: $action = 'showgraph'; $status_bar = _('Show graph of item') . ' \'' . $description . '\''; break; case ITEM_VALUE_TYPE_LOG: case ITEM_VALUE_TYPE_STR: case ITEM_VALUE_TYPE_TEXT: default: $action = 'showlatest'; $status_bar = _('Show values of item') . ' \'' . $description . '\''; break; } if (zbx_strlen($description) > 25) { $description = zbx_substr($description, 0, 22) . '...'; } $item_menu[$action][] = array($description, 'history.php?action=' . $action . '&itemid=' . $item['itemid'] . '&period=3600', array('tw' => '', 'sb' => $status_bar)); } if (isset($item_menu['showgraph'])) { $tr_ov_menu[] = array(_('Graphs'), null, null, array('outer' => array('pum_oheader'), 'inner' => array('pum_iheader'))); $tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showgraph']); } if (isset($item_menu['showlatest'])) { $tr_ov_menu[] = array(_('Values'), null, null, array('outer' => array('pum_oheader'), 'inner' => array('pum_iheader'))); $tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showlatest']); } unset($item_menu); // dependency: triggers on which depends this $triggerid = !empty($triggerHosts[$hostName]['triggerid']) ? $triggerHosts[$hostName]['triggerid'] : 0; $dep_table = new CTableInfo(); $dep_table->setAttribute('style', 'width: 200px;'); $dep_table->addRow(bold(_('Depends on') . ':')); $dependency = false; $dep_res = DBselect('SELECT td.* FROM trigger_depends td WHERE td.triggerid_down=' . $triggerid); while ($dep_row = DBfetch($dep_res)) { $dep_table->addRow(SPACE . '-' . SPACE . CTriggerHelper::expandDescriptionById($dep_row['triggerid_up'])); $dependency = true; } if ($dependency) { $img = new Cimg('images/general/arrow_down2.png', 'DEP_DOWN'); $img->setAttribute('style', 'vertical-align: middle; border: 0px;'); $img->setHint($dep_table, '', '', false); array_push($desc, $img); } unset($img, $dep_table, $dependency); // triggers that depend on this $dep_table = new CTableInfo(); $dep_table->setAttribute('style', 'width: 200px;'); $dep_table->addRow(bold(_('Dependent') . ':')); $dependency = false; $dep_res = DBselect('SELECT td.* FROM trigger_depends td WHERE td.triggerid_up=' . $triggerid); while ($dep_row = DBfetch($dep_res)) { $dep_table->addRow(SPACE . '-' . SPACE . CTriggerHelper::expandDescriptionById($dep_row['triggerid_down'])); $dependency = true; } if ($dependency) { $img = new Cimg('images/general/arrow_up2.png', 'DEP_UP'); $img->setAttribute('style', 'vertical-align: middle; border: 0px;'); $img->setHint($dep_table, '', '', false); array_push($desc, $img); } unset($img, $dep_table, $dependency); } if (is_array($desc) && count($desc) > 0 || $ack) { $tableColumn = new CCol(array($desc, $ack), $css_class . ' hosts'); } else { $tableColumn = new CCol(SPACE, $css_class . ' hosts'); } if (isset($style)) { $tableColumn->setAttribute('style', $style); } if (isset($tr_ov_menu)) { $tr_ov_menu = new CPUMenu($tr_ov_menu, 170); $tableColumn->onClick($tr_ov_menu->getOnActionJS()); $tableColumn->addAction('onmouseover', 'jQuery(this).css({border: "1px dotted #0C0CF0", padding: "0 2px"})'); $tableColumn->addAction('onmouseout', 'jQuery(this).css({border: "", padding: "1px 3px"})'); } return $tableColumn; }
if (uint_in_array(CWebUser::$data['type'], array(USER_TYPE_ZABBIX_ADMIN, USER_TYPE_SUPER_ADMIN))) { $userMediaFormList = new CFormList('userMediaFormList'); $userForm->addVar('user_medias', $this->data['user_medias']); $mediaTableInfo = new CTableInfo(_('No media found.')); foreach ($this->data['user_medias'] as $id => $media) { if (!isset($media['active']) || !$media['active']) { $status = new CLink(_('Enabled'), '#', 'enabled'); $status->onClick('return create_var("' . $userForm->getName() . '","disable_media",' . $id . ', true);'); } else { $status = new CLink(_('Disabled'), '#', 'disabled'); $status->onClick('return create_var("' . $userForm->getName() . '","enable_media",' . $id . ', true);'); } $mediaUrl = '?dstfrm=' . $userForm->getName() . '&media=' . $id . '&mediatypeid=' . $media['mediatypeid'] . '&sendto=' . urlencode($media['sendto']) . '&period=' . $media['period'] . '&severity=' . $media['severity'] . '&active=' . $media['active']; foreach (getSeverityCaption() as $key => $caption) { $mediaActive = $media['severity'] & 1 << $key; $mediaSeverity[$key] = new CSpan(zbx_substr($caption, 0, 1), $mediaActive ? 'enabled' : null); $mediaSeverity[$key]->setHint($caption . ($mediaActive ? ' (on)' : ' (off)')); } $mediaTableInfo->addRow(array(new CCheckBox('user_medias_to_del[' . $id . ']', null, null, $id), new CSpan($media['description'], 'nowrap'), new CSpan($media['sendto'], 'nowrap'), new CSpan($media['period'], 'nowrap'), $mediaSeverity, $status, new CButton('edit_media', _('Edit'), 'return PopUp("popup_media.php' . $mediaUrl . '", 550, 400);', 'link_menu'))); } $userMediaFormList->addRow(_('Media'), array($mediaTableInfo, new CButton('add_media', _('Add'), 'return PopUp("popup_media.php?dstfrm=' . $userForm->getName() . '", 550, 400);', 'link_menu'), SPACE, SPACE, count($this->data['user_medias']) > 0 ? new CSubmit('del_user_media', _('Delete selected'), null, 'link_menu') : null)); } /* * Profile fields */ if ($this->data['is_profile']) { $zbxSounds = getSounds(); $userMessagingFormList = new CFormList('userMessagingFormList'); $userMessagingFormList->addRow(_('Frontend messaging'), new CCheckBox('messages[enabled]', $this->data['messages']['enabled'], null, 1)); $userMessagingFormList->addRow(_('Message timeout (seconds)'), new CNumericBox('messages[timeout]', $this->data['messages']['timeout'], 5), false, 'timeout_row'); $repeatSound = new CComboBox('messages[sounds.repeat]', $this->data['messages']['sounds.repeat'], 'javascript: if (IE) { submit(); }');
function add_audit_details($action, $resourcetype, $resourceid, $resourcename, $details = null) { if (zbx_strlen($resourcename) > 255) { $resourcename = zbx_substr($resourcename, 0, 252) . '...'; } $ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; $values = array('userid' => CWebUser::$data['userid'], 'clock' => time(), 'ip' => substr($ip, 0, 39), 'action' => $action, 'resourcetype' => $resourcetype, 'resourceid' => $resourceid, 'resourcename' => $resourcename, 'details' => $details); try { DB::insert('auditlog', array($values)); return true; } catch (DBException $e) { return false; } }
function zbx_str2links($text) { // $value = preg_replace('#(https?|ftp|file)://[^\n\t\r ]+#u', '<a href="$0">$0</a>', $value); $result = array(); if (empty($text)) { return $result; } preg_match_all('#https?://[^\\n\\t\\r ]+#u', $text, $matches, PREG_OFFSET_CAPTURE); $start = 0; foreach ($matches[0] as $match) { $result[] = zbx_substr($text, $start, $match[1] - $start); $result[] = new CLink($match[0], $match[0], null, null, true); $start = $match[1] + zbx_strlen($match[0]); } $result[] = zbx_substr($text, $start, zbx_strlen($text)); return $result; }
/** * Replace macros in trigger description by values. * All macros are resolved in one go. * * @param array $trigger * @param array $macroValues * * @return array */ protected function replaceMacroValues(array $trigger, array $macroValues) { $macroBegin = false; for ($i = 0; $i < zbx_strlen($trigger['description']); $i++) { $c = zbx_substr($trigger['description'], $i, 1); switch ($c) { case '{': $macroBegin = $i; break; case '}': if ($macroBegin !== false) { $macro = zbx_substr($trigger['description'], $macroBegin, $i - $macroBegin + 1); if (isset($macroValues[$macro])) { $replace = $macroValues[$macro]; } elseif ($this->isAllowedMacro($macro)) { $replace = UNRESOLVED_MACRO_STRING; } else { $replace = false; } if ($replace !== false) { $trigger['description'] = zbx_substr_replace($trigger['description'], $replace, $macroBegin, zbx_strlen($macro)); // - 1 because for loop adds 1 on next iteration $i = $macroBegin + zbx_strlen($replace) - 1; $macroBegin = false; } } break; } } return $trigger; }
/** * Check item key and return info about an error if one is present * * @param string $key item key, e.g. system.run[cat /etc/passwd | awk -F: '{ print $1 }'] * @return array * */ function check_item_key($key) { $key_strlen = zbx_strlen($key); //empty string if ($key_strlen == 0) { return array(false, S_KEY_CANNOT_BE_EMPTY); } //key is larger then 255 chars if ($key_strlen > 255) { return array(false, sprintf(S_KEY_TOO_LARGE, 255)); } $characters = array(); //gathering characters into array, because we can't just work with them ar one if it's a unicode string for ($i = 0; $i < $key_strlen; $i++) { $characters[] = zbx_substr($key, $i, 1); } //checking every character, one by one for ($current_char = 0; $current_char < $key_strlen; $current_char++) { if (!preg_match("/" . ZBX_PREG_KEY_NAME . "/", $characters[$current_char])) { break; //$current_char now points to a first 'not a key name' char } } //no function specified? if ($current_char == $key_strlen) { return array('valid' => true, 'description' => S_KEY_IS_VALID); } else { if ($characters[$current_char] == '[') { $state = 0; //0 - initial, 1 - inside quoted param, 2 - inside unquoted param $nest_level = 0; //for every char, starting after '[' for ($i = $current_char + 1; $i < $key_strlen; $i++) { switch ($state) { //initial state case 0: if ($characters[$i] == ',') { //do nothing } else { if ($characters[$i] == ']' && isset($characters[$i + 1]) && $characters[$i + 1] == '[' && $nest_level == 0) { $i++; } else { if ($characters[$i] == '"') { $state = 1; } else { if ($characters[$i] == '[') { $nest_level++; } else { if ($characters[$i] == ']' && $nest_level != 0) { $nest_level--; //skipping spaces while (isset($characters[$i + 1]) && $characters[$i + 1] == ' ') { $i++; } //all nestings are closed correctly if ($nest_level == 0 && isset($characters[$i + 1]) && $characters[$i + 1] == ']' && !isset($characters[$i + 2])) { return array('valid' => true, 'description' => S_KEY_IS_VALID); } if ((!isset($characters[$i + 1]) || $characters[$i + 1] != ',') && !($nest_level != 0 && isset($characters[$i + 1]) && $characters[$i + 1] == ']')) { return array('valid' => false, 'description' => sprintf(S_INCORRECT_SYNTAX_NEAR, $characters[$current_char], $current_char)); } } else { if ($characters[$i] == ']' && $nest_level == 0) { if (isset($characters[$i + 1])) { return array('valid' => false, 'description' => sprintf(S_INCORRECT_USAGE_OF_BRACKETS, $characters[$i + 1])); } else { return array('valid' => true, 'description' => S_KEY_IS_VALID); } } else { if ($characters[$i] != ' ') { $state = 2; } } } } } } } break; //quoted //quoted case 1: //ending quote is reached if ($characters[$i] == '"') { //skipping spaces while (isset($characters[$i + 1]) && $characters[$i + 1] == ' ') { $i++; } //Zapcat if ($nest_level == 0 && isset($characters[$i + 1]) && isset($characters[$i + 2]) && $characters[$i + 1] == ']' && $characters[$i + 2] == '[') { $state = 0; break; } if ($nest_level == 0 && isset($characters[$i + 1]) && $characters[$i + 1] == ']' && !isset($characters[$i + 2])) { return array('valid' => true, 'description' => S_KEY_IS_VALID); } else { if ($nest_level == 0 && $characters[$i + 1] == ']' && isset($characters[$i + 2])) { return array('valid' => false, 'description' => sprintf(S_INCORRECT_USAGE_OF_BRACKETS, $characters[$i + 2])); } } if ((!isset($characters[$i + 1]) || $characters[$i + 1] != ',') && !($nest_level != 0 && isset($characters[$i + 1]) && $characters[$i + 1] == ']')) { return array('valid' => false, 'description' => sprintf(S_INCORRECT_SYNTAX_NEAR, $characters[$current_char], $current_char)); } $state = 0; } else { if ($characters[$i] == '\\' && isset($characters[$i + 1]) && $characters[$i + 1] == '"') { $i++; } } break; //unquoted //unquoted case 2: //Zapcat if ($nest_level == 0 && $characters[$i] == ']' && isset($characters[$i + 1]) && $characters[$i + 1] == '[') { $i--; $state = 0; } else { if ($characters[$i] == ',' || $characters[$i] == ']' && $nest_level != 0) { $i--; $state = 0; } else { if ($characters[$i] == ']' && $nest_level == 0) { if (isset($characters[$i + 1])) { return array('valid' => false, 'description' => sprintf(S_INCORRECT_USAGE_OF_BRACKETS, $characters[$i + 1])); } else { return array('valid' => true, 'description' => S_KEY_IS_VALID); } } } } break; } } return array('valid' => false, 'description' => S_INVALID_KEY_FORMAT); } else { return array('valid' => false, 'description' => sprintf(S_INVALID_CHARACTER_AT_POSITION, $characters[$current_char], $current_char)); } } }
function rebuild_expression_tree($expression, &$treeLevel, $action, $actionid, $newPart) { $newExp = ''; $lastLevel = true; if ($actionid != $treeLevel['openSymbolNum'] . '_' . $treeLevel['closeSymbolNum'] && ($treeLevel['levelType'] == 'independent' || $treeLevel['levelType'] == 'grouping')) { $sStart = !isset($treeLevel['openSymbol']) ? $treeLevel['openSymbolNum'] : $treeLevel['openSymbolNum'] + zbx_strlen($treeLevel['openSymbol']); $sEnd = !isset($treeLevel['closeSymbol']) ? $treeLevel['closeSymbolNum'] : $treeLevel['closeSymbolNum'] - zbx_strlen($treeLevel['closeSymbol']); /*$sStart = $treeLevel['levelType'] == 'independent' ? $treeLevel['openSymbolNum'] : $treeLevel['openSymbolNum']+(isset($treeLevel['openSymbol']) ? zbx_strlen($treeLevel['openSymbol']) : 0); $sEnd = $treeLevel['levelType'] == 'independent' ? $treeLevel['closeSymbolNum']+1 : $treeLevel['closeSymbolNum'];*/ // SDI("Total start: {$sStart}; Total end: {$sEnd};"); if (isset($treeLevel['parts'])) { $parts =& $treeLevel['parts']; } else { $parts = array(); } $fPart = reset($parts); if (count($parts) == 1 && $sStart == $fPart['openSymbolNum'] && $sEnd == $fPart['closeSymbolNum']) { return (isset($fPart['openSymbol']) && $fPart['levelType'] == 'grouping' ? $fPart['openSymbol'] : '') . trim(rebuild_expression_tree($expression, $fPart, $action, $actionid, $newPart)) . (isset($fPart['closeSymbol']) && $fPart['levelType'] == 'grouping' ? $fPart['closeSymbol'] : ''); } $operand = '|'; reset($parts); $bParts = array(); $opPos = find_next_operand($expression, $sStart, $sEnd, $parts, $bParts, $operand); if (!is_int($opPos) || $opPos >= $sEnd) { $operand = '&'; reset($parts); $bParts = array(); $opPos = find_next_operand($expression, $sStart, $sEnd, $parts, $bParts, $operand); } if (is_int($opPos) && $opPos < $sEnd) { $lastLevel = false; $prev = $sStart; $levelNewExpression = array(); while (is_int($opPos) && $opPos < $sEnd || $prev < $sEnd) { unset($newTreeLevel); if (count($bParts) == 1) { $fbPart = reset($bParts); } if (count($bParts) == 1 && zbx_substr($expression, $fbPart['openSymbolNum'], $fbPart['closeSymbolNum'] - $fbPart['openSymbolNum'] + (isset($fbPart['closeSymbol']) ? zbx_strlen($fbPart['closeSymbol']) : 0)) == trim(zbx_substr($expression, $prev + ($prev > $sStart ? zbx_strlen($operand) : 0), (is_int($opPos) && $opPos < $sEnd ? $opPos - zbx_strlen($operand) : $sEnd) - $prev))) { $newTreeLevel =& $bParts[key($bParts)]; } else { $newTreeLevel = array('levelType' => 'grouping', 'openSymbolNum' => $prev + ($prev > $sStart ? zbx_strlen($operand) : 0), 'closeSymbolNum' => is_int($opPos) && $opPos < $sEnd ? $opPos - zbx_strlen($operand) : $sEnd); if (is_array($bParts) && count($bParts) > 0) { $newTreeLevel['parts'] =& $bParts; } } // SDI("{$treeLevel['levelType']} parts:".count($treeLevel['parts'])); unset($bParts); $bParts = array(); $prev = is_int($opPos) && $opPos < $sEnd ? $opPos : $sEnd; $opPos = find_next_operand($expression, $prev + zbx_strlen($operand), $sEnd, $parts, $bParts, $operand); // SDI('>>>>>>>>>>>>>>>>>>>newTreeLevel parts count:'.(isset($newTreeLevel['parts']) ? count($newTreeLevel['parts']): 0)); // if(isset($newTreeLevel['parts'])) SDII($newTreeLevel['parts']); $newLevelExpression = rebuild_expression_tree($expression, $newTreeLevel, $action, $actionid, $newPart); if ($newLevelExpression) { $levelNewExpression[] = (isset($newTreeLevel['openSymbol']) && $newTreeLevel['levelType'] == 'grouping' ? $newTreeLevel['openSymbol'] : '') . trim($newLevelExpression) . (isset($newTreeLevel['closeSymbol']) && $newTreeLevel['levelType'] == 'grouping' ? $newTreeLevel['closeSymbol'] : ''); } // SDI("After {$treeLevel['levelType']} parts:".count($treeLevel['parts'])); } $newExp .= implode(' ' . $operand . ' ', $levelNewExpression); } } if ($lastLevel) { $curLevelVal = trim(zbx_substr($expression, $treeLevel['openSymbolNum'], $treeLevel['closeSymbolNum'] - $treeLevel['openSymbolNum'] + 1)); if ($actionid == $treeLevel['openSymbolNum'] . '_' . $treeLevel['closeSymbolNum']) { switch ($action) { case 'R': /* remove */ break; case 'r': /* Replace */ $newExp .= $newPart; break; case '&': /* add */ /* add */ case '|': /* add */ $newExp .= $curLevelVal . ' ' . $action . ' ' . $newPart; break; } } else { $newExp .= $curLevelVal; } } // SDI("<<<<<<<<<<<<<<<<<<<<<<<<< New expression return: {$newExp}"); return $newExp; }