/** * Updates trigger records in database. * * @param array $triggers */ protected function updateReal(array $triggers) { $triggers = zbx_toArray($triggers); $infos = []; $triggerIds = zbx_objectValues($triggers, 'triggerid'); $dbTriggers = $this->get(['output' => API_OUTPUT_EXTEND, 'triggerids' => $triggerIds, 'selectHosts' => ['name'], 'selectDependencies' => ['triggerid'], 'preservekeys' => true, 'nopermissions' => true]); $dbTriggers = CMacrosResolverHelper::resolveTriggerExpressions($dbTriggers); $changedPriorityTriggerIds = []; foreach ($triggers as &$trigger) { $descriptionChanged = false; $expressionChanged = false; $dbTrigger = $dbTriggers[$trigger['triggerid']]; $hosts = zbx_objectValues($dbTrigger['hosts'], 'name'); if (isset($trigger['description']) && strcmp($dbTrigger['description'], $trigger['description']) != 0) { $descriptionChanged = true; } else { $trigger['description'] = $dbTrigger['description']; } if (isset($trigger['expression']) && $dbTrigger['expression'] !== $trigger['expression']) { $this->validateItems($trigger); $expressionChanged = true; $expressionFull = $trigger['expression']; } if ($expressionChanged) { // check the expression $expressionData = new CTriggerExpression(); if (!$expressionData->parse($expressionFull)) { self::exception(ZBX_API_ERROR_PARAMETERS, $expressionData->error); } // remove triggers if expression is changed in a way that trigger will not appear in current host $oldExpressionData = new CTriggerExpression(); $oldExpressionData->parse($dbTrigger['expression']); // check if at least one template has stayed in expression, this means that child trigger will stay in host $oldTemplates = $oldExpressionData->getHosts(); $newTemplates = zbx_toHash($expressionData->getHosts()); $proceed = true; foreach ($oldTemplates as $oldTemplate) { if (isset($newTemplates[$oldTemplate])) { $proceed = false; break; } } // proceed if there is possibility that child triggers should be deleted if ($proceed) { $sql = 'SELECT t.triggerid' . ' FROM triggers t' . ' WHERE t.templateid=' . zbx_dbstr($trigger['triggerid']); $cTrigCursor = DBselect($sql); $cTrigIds = []; while ($cTrig = DBfetch($cTrigCursor)) { // get templates linked to templated trigger host $templateNames = DBfetchArrayAssoc(DBselect('SELECT h.name' . ' FROM hosts h, hosts_templates ht, items i, functions f' . ' WHERE h.hostid = ht.templateid AND ht.hostid = i.hostid AND i.itemid = f.itemid AND' . ' f.triggerid=' . zbx_dbstr($cTrig['triggerid'])), 'name'); // if we have at least one template linked to trigger host inside trigger expression, // then we don't delete this trigger $expressionHosts = $expressionData->getHosts(); foreach ($expressionHosts as $templateName) { if (isset($templateNames[$templateName])) { continue 2; } } $cTrigIds[] = $cTrig['triggerid']; } $this->deleteByIds($cTrigIds); } DB::delete('functions', ['triggerid' => $trigger['triggerid']]); try { $trigger['expression'] = implode_exp($expressionFull, $trigger['triggerid'], $hosts); } catch (Exception $e) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot implode expression "%s".', $expressionFull) . ' ' . $e->getMessage()); } // if the expression has changed, we must revalidate the existing dependencies if (!isset($trigger['dependencies'])) { $trigger['dependencies'] = zbx_objectValues($dbTrigger['dependencies'], 'triggerid'); } } $triggerUpdate = $trigger; if (!$descriptionChanged) { unset($triggerUpdate['description']); } if (!$expressionChanged) { unset($triggerUpdate['expression']); } // skip updating read only values unset($triggerUpdate['state'], $triggerUpdate['value'], $triggerUpdate['lastchange'], $triggerUpdate['error']); DB::update('triggers', ['values' => $triggerUpdate, 'where' => ['triggerid' => $trigger['triggerid']]]); // update service status if (isset($trigger['priority']) && $trigger['priority'] != $dbTrigger['priority']) { $changedPriorityTriggerIds[] = $trigger['triggerid']; } // restore the full expression to properly validate dependencies $trigger['expression'] = $expressionChanged ? $expressionFull : $dbTrigger['expression']; $infos[] = _s('Updated: Trigger "%1$s" on "%2$s".', $trigger['description'], implode(', ', $hosts)); add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, $dbTrigger['triggerid'], $dbTrigger['description'], null, $dbTrigger, $triggerUpdate); } unset($trigger); if ($changedPriorityTriggerIds && $this->usedInItServices($changedPriorityTriggerIds)) { updateItServices(); } foreach ($infos as $info) { info($info); } }
/** * Delete services. * * @param array $serviceIds * * @return array */ public function delete(array $serviceIds) { $this->validateDelete($serviceIds); DB::delete($this->tableName(), array('serviceid' => $serviceIds)); updateItServices(); return array('serviceids' => $serviceIds); }