<?php /* ---------------------------------------------------------------------------- NagiosQL ------------------------------------------------------------------------------- (c) 2005-2022 by Martin Willisegger Project : NagiosQL Component : Data processing class Website : https://sourceforge.net/projects/nagiosql/ Version : 3.5.0 GIT Repo : https://gitlab.com/wizonet/NagiosQL -----------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------- Class: Data processing class ------------------------------------------------------------------------------- Includes all functions used to manipulate the configuration data inside the database Name: NagDataClass -----------------------------------------------------------------------------*/ namespace functions; use function in_array; use function is_array; class NagDataClass { /* Define class variables */ public $arrSession = array(); /* Session content */ public $intDomainId = 0; /* Configuration domain ID */ public $strUserName = ''; /* Logged in Username */ public $strErrorMessage = ''; /* String including error messages */ public $strInfoMessage = ''; /* String including information messages */ /* Class includes */ /** @var MysqliDbClass */ public $myDBClass; /* Database class reference */ /** @var NagVisualClass */ public $myVisClass; /* NagiosQL visual class object */ /** @var NagConfigClass */ public $myConfigClass; /* NagiosQL configuration class object */ /** * NagDataClass constructor. * @param array $arrSession PHP Session array */ public function __construct(array $arrSession) { if (isset($arrSession['domain'])) { $this->intDomainId = (int)$arrSession['domain']; } if (isset($arrSession['username'])) { $this->strUserName = $arrSession['username']; } $this->arrSession = $arrSession; } /** * Copies one or more records in a data table. Alternatively, an individual record ID * are specified, or the values of the $_POST['chbId_n'] variable is used where n * is the record ID. * @param string $strTableName Table name * @param string $strKeyField Key field of the table * @param int $intDataId Single data ID to copy * @param int $intDomainId Target domain ID * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataCopyEasy(string $strTableName, string $strKeyField, int $intDataId = 0, int $intDomainId = -1): int { /* Define variables */ $arrRelations = array(); $intError = 0; $intNumber = 0; $intReturn = 0; $strAccess = $this->myVisClass->getAccessGroups('write'); if ($intDomainId === -1) { $intDomainId = $this->intDomainId; } /* Get all data ID from target table */ $strAccWhere = "WHERE `access_group` IN ($strAccess)"; if (($strTableName === 'tbl_user') || ($strTableName === 'tbl_group')) { $strAccWhere = ''; } /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . "` $strAccWhere ORDER BY `id`"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn === false) { $this->processClassMessage(translate('Error while selecting data from database:') . '::' . $this->myDBClass->strErrorMessage . '::', $this->strErrorMessage); return 1; } if ($intDataCount !== 0) { for ($i = 0; $i < $intDataCount; $i++) { /* Skip common domain value */ if ((int)$arrData[$i]['id'] === 0) { continue; } /* Build the name of the form variable */ $strChbName = 'chbId_' . $arrData[$i]['id']; /* If a form variable with this name exists or a matching single data ID was passed */ if (((filter_input(INPUT_POST, $strChbName, FILTER_UNSAFE_RAW) !== null) && ($intDataId === 0)) || ($intDataId === (int)$arrData[$i]['id'])) { /* Get all data of this data ID */ /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $strTableName . '` WHERE `id`=' . $arrData[$i]['id']; $this->myDBClass->hasSingleDataset($strSQL, $arrData[$i]); /* Build a temporary config name */ $strNewName = $this->buildTempConfigName( $strTableName, $strKeyField, $intDomainId, $intDataCount, $arrData, $i ); /* Build the INSERT command based on the table name */ if ($strTableName === 'tbl_service') { $strSQLInsert = $this->buildInsertSQL( $strTableName, 'service_description', $intDomainId, $strNewName, $arrData, $i); } else { $strSQLInsert = $this->buildInsertSQL( $strTableName, $strKeyField, $intDomainId, $strNewName, $arrData, $i); } /* Insert the master dataset */ $intCheck = 0; $booReturn = $this->myDBClass->insertData($strSQLInsert); $intMasterId = $this->myDBClass->intLastId; if ($booReturn === false) { $intCheck++; } /* Copy relations */ if (($this->tableRelations($strTableName, $arrRelations) === 0) && ($intCheck === 0)) { foreach ($arrRelations as $elem) { /* Normal 1:n relation */ if ((int)$elem['type'] === 2) { $intCheck = $this->insertRelationType2($arrData, $i, $elem, $intMasterId, $intCheck); } elseif ((int)$elem['type'] === 3) { /* 1:n relation for templates */ $intCheck = $this->insertRelationType3($arrData, $i, $elem, $intMasterId, $intCheck); } elseif ((int)$elem['type'] === 4) { /* Special relation for free variables */ $intCheck = $this->insertRelationType4($arrData, $i, $elem, $intMasterId, $intCheck); } elseif ((int)$elem['type'] === 5) { /* 1:n relation for tbl_lnkServicegroupToService */ $intCheck = $this->insertRelationType5($arrData, $i, $elem, $intMasterId, $intCheck); } elseif ((int)$elem['type'] === 6) { /* 1:n relation for services */ $intCheck = $this->insertRelationType6($arrData, $i, $elem, $intMasterId, $intCheck); } } /* 1:n relation for time definitions */ if ($strTableName === 'tbl_timeperiod') { $intCheck = $this->insertRelationTimedefinition($arrData, $i, $intMasterId, $intCheck); } /* 1:n relation for groups */ if ($strTableName === 'tbl_group') { $intCheck = $this->insertRelationGroup($arrData, $i, $intMasterId, $intCheck); } /* 1:n relation for service to host connections */ if ($strTableName === 'tbl_host') { $intCheck = $this->insertRelationHost($arrData, $i, $intMasterId, $intCheck); } } /* Write logfile */ if ($intCheck !== 0) { /* Error */ $intError++; $this->writeLog(translate('Data set copy failed - table [new name]:') . ' ' . $strTableName . ' [' . $strNewName . ']'); $this->processClassMessage(translate('Data set copy failed - table [new name]:') . ' ' . $strTableName . ' [' . $strNewName . ']::', $this->strInfoMessage); } else { /* Success */ $this->writeLog(translate('Data set copied - table [new name]:') . ' ' . $strTableName . ' [' . $strNewName . ']'); $this->processClassMessage(translate('Data set copied - table [new name]:') . ' ' . $strTableName . ' [' . $strNewName . ']::', $this->strInfoMessage); } $intNumber++; } } /* Error processing */ if ($intNumber > 0) { if ($intError === 0) { /* Success */ $this->processClassMessage(translate('Data were successfully inserted to the data base!') . '::', $this->strInfoMessage); $this->updateStatusTable($strTableName); } else { /* Error */ $this->processClassMessage(translate('Error while inserting the data into the database:') . '::' . $this->myDBClass->strErrorMessage, $this->strInfoMessage); $intReturn = 1; } } else { $this->processClassMessage(translate('No dataset copied. Maybe the dataset does not exist or you do ' . 'not have write permission.') . '::', $this->strErrorMessage); $intReturn = 1; } } else { $this->processClassMessage(translate('No dataset copied. Maybe the dataset does not exist or you do not ' . 'have write permission.') . '::', $this->strErrorMessage); $intReturn = 1; } return $intReturn; } /** * Merge message strings and check for duplicate messages * @param string $strNewMessage New message to add * @param string|null $strOldMessage Modified message string (by reference) */ public function processClassMessage(string $strNewMessage, string &$strOldMessage = null): int { $strNewMessage = str_replace('::::', '::', $strNewMessage); if (($strOldMessage !== '') && ($strNewMessage !== '')) { if (substr_count($strOldMessage, $strNewMessage) === 0) { $strOldMessage .= $strNewMessage; } } else { $strOldMessage .= $strNewMessage; } return 0; } /** * Build a temporary configuration name * @param string $strTableName Table name * @param string $strKeyField Configuration field name * @param int $intDomainId Domain ID * @param int $intCount Dataset counter * @param array $arrData Data array * @param int $intID Data array key * @return string Temporary configuration name */ private function buildTempConfigName(string $strTableName, string $strKeyField, int $intDomainId, int $intCount, array $arrData, int $intID): string { /* Define variables */ $strNewName = ''; for ($y = 1; $y <= $intCount; $y++) { $strNewName = $arrData[$intID][$strKeyField] . " ($y)"; if (($strTableName === 'tbl_user') || ($strTableName === 'tbl_group') || ($strTableName === 'tbl_datadomain') || ($strTableName === 'tbl_configtarget')) { /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` WHERE `' . $strKeyField . "`='$strNewName'"; } else if ($strTableName === 'tbl_service') { $strNewName = $arrData[$intID]['service_description'] . " ($y)"; /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` WHERE `' . $strKeyField . "`='" . $arrData[$intID][$strKeyField] . "' AND `service_description`='$strNewName'"; } else { /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` ' . 'WHERE `' . $strKeyField . "`='$strNewName' AND `config_id`=$intDomainId"; } $strFieldData = $this->myDBClass->getFieldData($strSQL); /* If the name is unused -> break the loop */ if ($strFieldData === '') { break; } } /* Manually overwrite new name for extinfo tables */ if ($strTableName === 'tbl_hostextinfo') { $strNewName = '0'; } if ($strTableName === 'tbl_serviceextinfo') { $strNewName = '0'; } return $strNewName; } /** * Build an INSERT command based on the table name * @param string $strTableName Table name * @param string $strKeyField Configuration field name * @param int $intDomainId Domain ID * @param string $strNewName New configuration name * @param array $arrData Data array * @param int $intID Data array key * @return string SQL INSERT command */ private function buildInsertSQL(string $strTableName, string $strKeyField, int $intDomainId, string $strNewName, array $arrData, int $intID): string { /** @noinspection SqlResolve */ $strSQLInsert = 'INSERT INTO `' . $strTableName . '` SET `' . $strKeyField . "`='" . $strNewName . "'"; foreach ($arrData[$intID] as $key => $value) { if ($value === null) { $value = ''; } if (($key !== $strKeyField) && ($key !== 'active') && ($key !== 'last_modified') && ($key !== 'id') && ($key !== 'config_id')) { /* Manually set some NULL values based on field names */ $value = $this->setNullValues($strTableName, $key, $value); /* If the data value is not "NULL", add single quotes to the value */ if ($value !== 'NULL') { $strSQLInsert .= ',`' . $key . "`='" . addslashes($value) . "'"; } else { $strSQLInsert .= ',`' . $key . '`=' . $value; } } } if (($strTableName === 'tbl_user') || ($strTableName === 'tbl_group') || ($strTableName === 'tbl_datadomain') || ($strTableName === 'tbl_configtarget')) { $strSQLInsert .= ",`active`='0', `last_modified`=NOW()"; } else { $strSQLInsert .= ",`active`='0', `config_id`=$intDomainId, `last_modified`=NOW()"; } return $strSQLInsert; } /** * Manually set some NULL values based on field names (key) * @param string $strTableName Table name * @param string $key Data key (field name) * @param string $value Data value (field key) * @return NULL|string Manipulated data value */ private function setNullValues(string $strTableName, string $key, string $value): ?string { $arrNull = array('normal_check_interval', 'retry_check_interval', 'max_check_attempts', 'low_flap_threshold', 'high_flap_threshold', 'freshness_threshold', 'notification_interval', 'first_notification_delay', 'check_interval', 'retry_interval'); if (in_array($key, $arrNull, true) && ($value === '')) { $value = 'NULL'; } /* manually set some NULL values based on table name */ if (($strTableName === 'tbl_serviceextinfo') && ($key === 'service_description')) { $value = '0'; } /* Do not copy the password in tbl_user */ if (($strTableName === 'tbl_user') && ($key === 'password')) { $value = 'xxxxxxx'; } /* Do not copy nodelete and webserver authentification values in tbl_user */ if ($key === 'nodelete') { $value = '0'; } if ($key === 'wsauth') { $value = '0'; } return $value; } /** * Returns an array of all datafields of a table, which has an 1:1 or 1:n relation * to another table. * @param string $strTable Table name * @param array|null $arrRelations Array with relations * @return int 0 = successful / 1 = error */ public function tableRelations(string $strTable, array &$arrRelations = null): int { /* Define variable */ $arrRelations = array(); $arrData = array(); $intDC = 0; $intReturn = 1; /* Get relation data */ $strSQL = "SELECT * FROM `tbl_relationinformation` WHERE `master`='$strTable' AND `fullRelation`=0"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booReturn && ($intDC !== 0)) { foreach ($arrData as $elem) { $arrRelations[] = array('tableName1' => $elem['tableName1'], 'tableName2' => $elem['tableName2'], 'fieldName' => $elem['fieldName'], 'linkTable' => $elem['linkTable'], 'target1' => $elem['target1'], 'target2' => $elem['target2'], 'type' => $elem['type']); } $intReturn = 0; } return $intReturn; } /** * Insert a normal 1:n relation * @param array $arrData Database value array * @param integer $intID Database array key * @param array $elem Link table information * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationType2(array $arrData, int $intID, array $elem, int $intMasterId, int $intCheck): int { $arrRelData = array(); $intRelDataCount = 0; if ((int)$arrData[$intID][$elem['fieldName']] !== 0) { /** @noinspection SqlResolve */ $strSQL = 'SELECT `idSlave`, `exclude` FROM `' . $elem['linkTable'] . '` ' . 'WHERE `idMaster`=' . $arrData[$intID]['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrRelData, $intRelDataCount); if ($booReturn && ($intRelDataCount !== 0)) { foreach ($arrRelData as $elem2) { /** @noinspection SqlResolve */ $strSQLRel = 'INSERT INTO `' . $elem['linkTable'] . '` ' . "SET `idMaster`=$intMasterId, `idSlave`=" . $elem2['idSlave'] . ', ' . '`exclude`=' . $elem2['exclude']; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } } return $intCheck; } /** * Insert a 1:n relation for templates * @param array $arrData Database value array * @param integer $intID Database array key * @param array $elem Link table information * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationType3(array $arrData, int $intID, array $elem, int $intMasterId, int $intCheck): int { $arrRelData = array(); $intRelDataCount = 0; if ((int)$arrData[$intID][$elem['fieldName']] === 1) { /** @noinspection SqlResolve */ $strSQL = 'SELECT `idSlave`,`idSort`,`idTable` FROM `' . $elem['linkTable'] . '` ' . 'WHERE `idMaster`=' . $arrData[$intID]['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrRelData, $intRelDataCount); if ($booReturn && ($intRelDataCount !== 0)) { foreach ($arrRelData as $elem2) { /** @noinspection SqlResolve */ $strSQLRel = 'INSERT INTO `' . $elem['linkTable'] . '` ' . "SET `idMaster`=$intMasterId, `idSlave`=" . $elem2['idSlave'] . ', ' . '`idTable`=' . $elem2['idTable'] . ', `idSort`=' . $elem2['idSort']; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } } return $intCheck; } /** * Insert a special relation for free variables * @param array $arrData Database value array * @param integer $intID Database array key * @param array $elem Link table information * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationType4(array $arrData, int $intID, array $elem, int $intMasterId, int $intCheck): int { $arrRelData = array(); $arrDataVar = array(); $intRelDataCount = 0; $intDCVar = 0; if ((int)$arrData[$intID][$elem['fieldName']] !== 0) { /** @noinspection SqlResolve */ $strSQL = 'SELECT `idSlave` FROM `' . $elem['linkTable'] . '` ' . 'WHERE `idMaster` = ' . $arrData[$intID]['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrRelData, $intRelDataCount); if ($booReturn && ($intRelDataCount !== 0)) { foreach ($arrRelData as $elem2) { /* Copy variables and link them to the new master */ $strSQLVar = 'SELECT * FROM `tbl_variabledefinition` WHERE `id`=' . $elem2['idSlave']; $booReturn = $this->myDBClass->hasDataArray($strSQLVar, $arrDataVar, $intDCVar); if ($booReturn && ($intDCVar !== 0)) { $strSQLInsVar = 'INSERT INTO `tbl_variabledefinition` ' . "SET `name`='" . addslashes($arrDataVar[0]['name']) . "', " . "`value`='" . addslashes($arrDataVar[0]['value']) . "', " . '`last_modified`=NOW()'; $booReturn = $this->myDBClass->insertData($strSQLInsVar); if ($booReturn === false) { $intCheck++; } /** @noinspection SqlResolve */ $strSQLRel = 'INSERT INTO `' . $elem['linkTable'] . '` ' . "SET `idMaster`=$intMasterId, " . '`idSlave`=' . $this->myDBClass->intLastId; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } } } return $intCheck; } /** * Insert a 1:n relation for tbl_lnkServicegroupToService * @param array $arrData Database value array * @param integer $intID Database array key * @param array $elem Link table information * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationType5(array $arrData, int $intID, array $elem, int $intMasterId, int $intCheck): int { $arrRelData = array(); $intRelDataCount = 0; if ((int)$arrData[$intID][$elem['fieldName']] !== 0) { $strSQL = 'SELECT `idSlaveH`,`idSlaveHG`,`idSlaveS`,`exclude` ' . 'FROM `' . $elem['linkTable'] . '` WHERE `idMaster`=' . $arrData[$intID]['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrRelData, $intRelDataCount); if ($booReturn && ($intRelDataCount !== 0)) { foreach ($arrRelData as $elem2) { /** @noinspection SqlResolve */ $strSQLRel = 'INSERT INTO `' . $elem['linkTable'] . '` ' . "SET `idMaster`=$intMasterId, `idSlaveH`=" . $elem2['idSlaveH'] . ', ' . '`idSlaveHG`=' . $elem2['idSlaveHG'] . ', `idSlaveS`=' . $elem2['idSlaveS'] . ', `exclude`=' . $elem2['exclude']; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } } return $intCheck; } /** * Insert a 1:n relation for services * @param array $arrData Database value array * @param integer $intID Database array key * @param array $elem Link table information * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationType6(array $arrData, int $intID, array $elem, int $intMasterId, int $intCheck): int { $arrRelData = array(); $intRelDataCount = 0; if ((int)$arrData[$intID][$elem['fieldName']] !== 0) { $strSQL = 'SELECT `idSlave`, `strSlave`, `exclude` ' . 'FROM `' . $elem['linkTable'] . '` WHERE `idMaster`=' . $arrData[$intID]['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrRelData, $intRelDataCount); if ($booReturn && ($intRelDataCount !== 0)) { foreach ($arrRelData as $elem2) { /** @noinspection SqlResolve */ $strSQLRel = 'INSERT INTO `' . $elem['linkTable'] . '` ' . "SET `idMaster`=$intMasterId, `idSlave`=" . $elem2['idSlave'] . ', ' . "`strSlave`='" . addslashes($elem2['strSlave']) . "', " . '`exclude`=' . $elem2['exclude']; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } } return $intCheck; } /** * Insert a 1:n relation for time definitions * @param array $arrData Database value array * @param integer $intID Database array key * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationTimedefinition(array $arrData, int $intID, int $intMasterId, int $intCheck): int { $arrRelDataTP = array(); $intRelDataCountTP = 0; $strSQL = 'SELECT * FROM `tbl_timedefinition` WHERE `tipId`=' . $arrData[$intID]['id']; $this->myDBClass->hasDataArray($strSQL, $arrRelDataTP, $intRelDataCountTP); if ($intRelDataCountTP !== 0) { foreach ($arrRelDataTP as $elem) { $strSQLRel = 'INSERT INTO `tbl_timedefinition` (`tipId`,`definition`,`range`,' . "`last_modified`) VALUES ($intMasterId,'" . addslashes($elem['definition']) . "'," . "'" . addslashes($elem['range']) . "',now())"; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } return $intCheck; } /** * Insert a 1:n relation for user groups * @param array $arrData Database value array * @param integer $intID Database array key * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationGroup(array $arrData, int $intID, int $intMasterId, int $intCheck): int { $arrRelDataTP = array(); $intRelDataCountTP = 0; $strSQL = 'SELECT * FROM `tbl_lnkGroupToUser` WHERE `idMaster`=' . $arrData[$intID]['id']; $this->myDBClass->hasDataArray($strSQL, $arrRelDataTP, $intRelDataCountTP); if ($intRelDataCountTP !== 0) { foreach ($arrRelDataTP as $elem2) { $strSQLRel = 'INSERT INTO `tbl_lnkGroupToUser` (`idMaster`,`idSlave`,`read`,`write`,`link`) ' . "VALUES ($intMasterId,'" . $elem2['idSlave'] . "','" . $elem2['read'] . "'," . "'" . $elem2['write'] . "','" . $elem2['link'] . "')"; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } return $intCheck; } /** * Insert a 1:n relation fot service to host connections * @param array $arrData Database value array * @param integer $intID Database array key * @param integer $intMasterId Data ID of master table * @param integer $intCheck Check error counter (before processing) * @return integer Check error counter (after processing) */ private function insertRelationHost(array $arrData, int $intID, int $intMasterId, int $intCheck): int { $arrRelDataSH = array(); $intRelDataCountSH = 0; $strSQL = 'SELECT * FROM `tbl_lnkServiceToHost` WHERE `idSlave`=' . $arrData[$intID]['id']; $this->myDBClass->hasDataArray($strSQL, $arrRelDataSH, $intRelDataCountSH); if ($intRelDataCountSH !== 0) { foreach ($arrRelDataSH as $elem2) { $strSQLRel = 'INSERT INTO `tbl_lnkServiceToHost` (`idMaster`,`idSlave`,`exclude`) ' . "VALUES ('" . $elem2['idMaster'] . "',$intMasterId,'" . $elem2['exclude'] . "')"; $booReturn = $this->myDBClass->insertData($strSQLRel); if ($booReturn === false) { $intCheck++; } } } return $intCheck; } /** * Saving a given string to the logbook * @param string $strLogMessage Message string * @return int 0 = successful / 1 = error */ public function writeLog(string $strLogMessage): int { /* Variable definition */ $strRemoteAdress = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP); $intReturn = 0; /* Write log message to database */ if ($strRemoteAdress !== null) { /* Webinterface */ $strUserName = $this->strUserName; $strDomain = $this->myDBClass->getFieldData('SELECT `domain` FROM `tbl_datadomain` ' . 'WHERE `id`=' . $this->intDomainId); $booReturn = $this->myDBClass->insertData("INSERT INTO `tbl_logbook` SET `user`='" . $strUserName . "'," . "`time`=NOW(), `ipadress`='" . $strRemoteAdress . "', `domain`='$strDomain'," . "`entry`='" . addslashes($strLogMessage) . "'"); } else { /* Scriptinginterface */ $strUserName = 'scripting'; $strRemoteUser = filter_input(INPUT_SERVER, 'REMOTE_USER', FILTER_UNSAFE_RAW); $strHostname = filter_input(INPUT_SERVER, 'REMOTE_HOST', FILTER_UNSAFE_RAW); $strSSHClient = filter_input(INPUT_SERVER, 'SSH_CLIENT', FILTER_UNSAFE_RAW); if ($strRemoteUser !== null) { $strUserName .= ' - ' . $strRemoteUser; } $strDomain = $this->myDBClass->getFieldData('SELECT `domain` FROM `tbl_datadomain` ' . 'WHERE `id`=' . $this->intDomainId); if ($strHostname !== null) { $booReturn = $this->myDBClass->insertData("INSERT INTO `tbl_logbook` SET `user`='" . $strUserName . "'," . "`time`=NOW(), `ipadress`='" . $strHostname . "', `domain`='$strDomain', " . "`entry`='" . addslashes($strLogMessage) . "'"); } elseif ($strSSHClient !== null) { $arrSSHClient = explode(' ', $strSSHClient); $booReturn = $this->myDBClass->insertData("INSERT INTO `tbl_logbook` SET `user`='" . $strUserName . "'," . "`time`=NOW(), `ipadress`='" . $arrSSHClient[0] . "', `domain`='$strDomain', " . "`entry`='" . addslashes($strLogMessage) . "'"); } else { $booReturn = $this->myDBClass->insertData("INSERT INTO `tbl_logbook` SET `user`='" . $strUserName . "'," . "`time`=NOW(), `ipadress`='unknown', `domain`='$strDomain', " . "`entry`='" . addslashes($strLogMessage) . "'"); } } if ($booReturn === false) { $intReturn = 1; } return $intReturn; } /** * Update the date inside the status table (used for last modified date) * @param string $strTable Table name * @return int 0 = successful / 1 = error */ public function updateStatusTable(string $strTable): int { /* Define variable */ $arrData = array(); $intDC = 0; $intReturn = 1; /* Does the entry exist? */ $strSQL = "SELECT * FROM `tbl_tablestatus` WHERE `tableName`='$strTable' AND `domainId`=" . $this->intDomainId; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booReturn && ($intDC !== 0)) { $strSQL = 'UPDATE `tbl_tablestatus` SET `updateTime`=NOW() ' . "WHERE `tableName`='$strTable' AND `domainId`=" . $this->intDomainId; $booReturn = $this->dataInsert($strSQL, $intDataID); if ($booReturn) { $intReturn = 0; } } elseif ($booReturn) { $strSQL = 'INSERT INTO `tbl_tablestatus` ' . "SET `updateTime`=NOW(), `tableName`='$strTable', `domainId`=" . $this->intDomainId; $booReturn = $this->dataInsert($strSQL, $intDataID); if ($booReturn) { $intReturn = 0; } } return $intReturn; } /** * PRIVATE functions */ /** * Sends an SQL string to the database server * @param string $strSQL SQL Command * @param int|null $intDataID Data ID of last inserted dataset (by reference) * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataInsert(string $strSQL, int &$intDataID = null): int { /* Define variables */ $intReturn = 0; /* Send the SQL command to the database server */ $booReturn = $this->myDBClass->insertData($strSQL); $intDataID = $this->myDBClass->intLastId; /* Was the SQL command processed successfully? */ if ($booReturn) { $this->processClassMessage(translate('Data were successfully inserted to the data base!') . '::', $this->strInfoMessage); } else { $this->processClassMessage(translate('Error while inserting the data into the database:') . '::' . $this->myDBClass->strErrorMessage . '::', $this->strErrorMessage); $intReturn = 1; } return $intReturn; } /** * Removes one or more dataset(s) from a table. Optinal a single data ID can be passed or the values will be * processed through the POST variable $_POST['chbId_n'] where 'n' represents the data ID. * -> This function does not delete any relation data! <- * @param string $strTableName Table name * @param int $intDataId Single data ID * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataDeleteEasy(string $strTableName, int $intDataId = 0): int { /* Define variables */ $strNoDelete1 = ''; $strNoDelete2 = ''; $intReturn = 0; $arrData = array(); /* Special rule for tables with "nodelete" cells */ if (($strTableName === 'tbl_datadomain') || ($strTableName === 'tbl_configtarget') || ($strTableName === 'tbl_user')) { $strNoDelete1 = "AND `nodelete` <> '1'"; $strNoDelete2 = "WHERE `nodelete` <> '1'"; } /* Delete a single data set */ if ($intDataId !== 0) { /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $strTableName . "` WHERE `id` = $intDataId $strNoDelete1"; $booReturn = $this->myDBClass->insertData($strSQL); if ($booReturn === false) { $this->processClassMessage(translate('Delete failed because a database error:') . '::' . $this->myDBClass->strErrorMessage . '::', $this->strInfoMessage); $intReturn = 1; } elseif ($this->myDBClass->intAffectedRows === 0) { $this->processClassMessage(translate('No data deleted. The dataset probably does not exist or ' . 'is protected from deletion.') . '::', $this->strErrorMessage); $intReturn = 1; } else { $this->strInfoMessage .= translate('Dataset successfully deleted. Affected rows:') . ' ' . $this->myDBClass->intAffectedRows . '::'; $this->writeLog(translate('Delete dataset id:') . " $intDataId " . translate('- from table:') . " $strTableName " . translate('- with affected rows:') . ' ' . $this->myDBClass->intAffectedRows); $this->updateStatusTable($strTableName); } /* Delete data sets based on form POST parameter */ } else { /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` '; $strSQL .= $strNoDelete2; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn && ($intDataCount !== 0)) { $intDeleteCount = 0; foreach ($arrData as $elem) { $strChbName = 'chbId_' . $elem['id']; /* Should this data id to be deleted? */ if ((filter_input(INPUT_POST, $strChbName) !== null) && (filter_input(INPUT_POST, $strChbName, FILTER_UNSAFE_RAW) === 'on')) { /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $strTableName . '` WHERE `id` = ' . $elem['id']; $booReturn = $this->myDBClass->insertData($strSQL); if ($booReturn === false) { $this->processClassMessage(translate('Delete failed because a database error:') . '::' . $this->myDBClass->strErrorMessage . '::', $this->strInfoMessage); $intReturn = 1; } else { $intDeleteCount += $this->myDBClass->intAffectedRows; } } } /* Process messsages */ if ($intDeleteCount === 0) { $this->processClassMessage(translate('No data deleted. Probably the dataset does not exist or ' . 'it is protected from delete.') . '::', $this->strErrorMessage); $intReturn = 1; } elseif ($intReturn === 0) { $this->processClassMessage(translate('Dataset successfully deleted. Affected rows:') . ' ' . $intDeleteCount . '::', $this->strInfoMessage); $this->writeLog(translate('Deleted data from table:') . " $strTableName " . translate('- with affected rows:') . ' ' . $this->myDBClass->intAffectedRows); $this->updateStatusTable($strTableName); } } else { $this->processClassMessage(translate('No data deleted. Probably the dataset does not exist or it is ' . 'protected from delete.') . '::', $this->strErrorMessage); $intReturn = 1; } } return $intReturn; } /** * Removes one or more dataset(s) from a table. Optinal a single data ID can be passed or the values will be * processed through the POST variable $_POST['chbId_n'] where 'n' represents the data ID. * -> This function does also delete relation data! <- * @param string $strTableName Table name * @param int $intDataId Single data ID * @param int $intForce Force deletion (1 = force, 1 = no force) * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataDeleteFull(string $strTableName, int $intDataId = 0, int $intForce = 0): int { /* Define variables */ $arrRelations = array(); $arrData = array(); $arrConfigId = array(); /* Get write access groups */ $strAccess = $this->myVisClass->getAccessGroups('write'); /* Get all relations */ $this->fullTableRelations($strTableName, $arrRelations); /* Get all datasets */ if ($strTableName === 'tbl_group') { /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '`'; } else { /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` ' . 'WHERE `config_id`=' . $this->intDomainId . " AND `access_group` IN ($strAccess)"; } $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn && ($intDataCount !== 0)) { $intDeleteCount = 0; $strInfoMessage = ''; $strErrorMessage = ''; foreach ($arrData as $elem) { $strChbName = 'chbId_' . $elem['id']; /* Single ID */ if (($intDataId !== 0) && ($intDataId !== (int)$elem['id'])) { continue; } /* Should this data id to be deleted? */ if ((($intDataId === (int)$elem['id']) || ((filter_input(INPUT_POST, $strChbName) !== null) && (filter_input(INPUT_POST, $strChbName, FILTER_UNSAFE_RAW) === 'on'))) && (($this->infoRelation($strTableName, $elem['id'], 'id', 1) === 0) || ($intForce === 1))) { /* Delete relations */ if (!is_array($arrRelations)) { $arrRelations = array(); } foreach ($arrRelations as $rel) { $strSQL = ''; /* Process flags */ $arrFlags = explode(',', $rel['flags']); /* Simple 1:n relation */ if ((int)$arrFlags[3] === 1) { /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $rel['tableName1'] . '` ' . 'WHERE `' . $rel['fieldName'] . '`=' . $elem['id']; } /* Simple 1:1 relation */ if ((int)$arrFlags[3] === 0) { /* Delete relation */ if ((int)$arrFlags[2] === 0) { /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $rel['tableName1'] . '` ' . 'WHERE `' . $rel['fieldName'] . '`=' . $elem['id']; /* Set slave to 0 */ } elseif ((int)$arrFlags[2] === 2) { $strSQL = 'UPDATE `' . $rel['tableName1'] . '` SET `' . $rel['fieldName'] . '`=0 ' . 'WHERE `' . $rel['fieldName'] . '`=' . $elem['id']; } } /* Special 1:n relation for variables */ if ((int)$arrFlags[3] === 2) { /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $rel['tableName1'] . '` WHERE `idMaster`=' . $elem['id']; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn && ($intDataCount !== 0)) { foreach ($arrData as $vardata) { $strSQL = 'DELETE FROM `tbl_variabledefinition` ' . 'WHERE `id`=' . $vardata['idSlave']; $this->myDBClass->insertData($strSQL); } } /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $rel['tableName1'] . '` WHERE `idMaster`=' . $elem['id']; } /* Special 1:n relation for time definitions */ if ((int)$arrFlags[3] === 3) { $strSQL = 'DELETE FROM `tbl_timedefinition` WHERE `tipId`=' . $elem['id']; $this->myDBClass->insertData($strSQL); } if ($strSQL !== '') { $this->myDBClass->insertData($strSQL); } } /* Delete host configuration file */ if (($strTableName === 'tbl_host') && ($this->intDomainId !== 0)) { $strSQL = 'SELECT `host_name` FROM `tbl_host` WHERE `id`=' . $elem['id']; $strHost = $this->myDBClass->getFieldData($strSQL); $intRetConf = $this->myConfigClass->getConfigSets($arrConfigId); if ($intRetConf !== 1) { $intReturn = 0; foreach ($arrConfigId as $intConfigId) { $intReturn += $this->myConfigClass->moveFile( 'host', $strHost . '.cfg', $intConfigId ); } if ($intReturn === 0) { $this->processClassMessage(translate('The assigned, no longer used configuration ' . 'files were deleted successfully!') . '::', $strInfoMessage); $this->writeLog(translate('Host file deleted:') . ' ' . $strHost . '.cfg'); } else { $strErrorMessage .= translate('Errors while deleting the old configuration file - ' . 'please check!:') . ' ::' . $this->myConfigClass->strErrorMessage . '::'; } } } /* Delete service configuration file */ if (($strTableName === 'tbl_service') && ($this->intDomainId !== 0)) { $strSQL = 'SELECT `config_name` FROM `tbl_service` WHERE `id`=' . $elem['id']; $strService = $this->myDBClass->getFieldData($strSQL); $strSQL = "SELECT * FROM `tbl_service` WHERE `config_name` = '$strService'"; $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($intDataCount === 1) { $intRetConf = $this->myConfigClass->getConfigSets($arrConfigId); if ($intRetConf !== 1) { $intReturn = 0; foreach ($arrConfigId as $intConfigId) { $intReturn += $this->myConfigClass->moveFile( 'service', $strService . '.cfg', $intConfigId ); } if ($intReturn === 0) { $this->processClassMessage(translate('The assigned, no longer used ' . 'configuration files were deleted successfully!') . '::', $strInfoMessage); $this->writeLog(translate('Host file deleted:') . ' ' . $strService . '.cfg'); } else { $strErrorMessage .= translate('Errors while deleting the old configuration ' . 'file - please check!:') . '::' . $this->myConfigClass->strErrorMessage . '::'; } } } } /* Delete main entry */ /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $strTableName . '` WHERE `id`=' . $elem['id']; $this->myDBClass->insertData($strSQL); $intDeleteCount++; } } /* Process messages */ if ($intDeleteCount === 0) { $this->processClassMessage(translate('No data deleted. Probably the dataset does not exist, it is ' . 'protected from deletion, you do not have write permission or it has relations to other ' . 'configurations which cannot be deleted. Use the "info" function for detailed informations ' . 'about relations!') . '::', $this->strErrorMessage); return 1; } $this->updateStatusTable($strTableName); $this->processClassMessage(translate('Dataset successfully deleted. Affected rows:') . ' ' . $intDeleteCount . '::', $this->strInfoMessage); $this->writeLog(translate('Deleted data from table:') . " $strTableName " . translate('- with affected rows:') . ' ' . $intDeleteCount); $this->processClassMessage($strInfoMessage, $this->strInfoMessage); $this->processClassMessage($strErrorMessage, $this->strErrorMessage); return 0; } $this->processClassMessage(translate('No data deleted. Probably the dataset does not exist, it is ' . 'protected from deletion or you do not have write permission.') . '::' . $this->myDBClass->strErrorMessage, $this->strErrorMessage); return 1; } /** * Returns an array with any data fields from a table with existing relations to another table. This function * returns also passive relations which are not used in configurations. * This function is used for a full deletion of a configuration entry or to find out if a configuration is used * in another way. * @param string $strTable Table name * @param array|null $arrRelations Array with relations * @return int 0 = no field with relation / 1 = at least one field with relation * Status message is stored in message class variables * Data array: tableName Table include the relation data * fieldName Field name include the relation data * flags Pos 1 -> 0=Normal field / 1=Required field (field type) * Pos 2 -> 0=delete / 1=keep data / 2=set to 0 (normal deletion option) * Pos 3 -> 0=delete / 2=set to 0 (force deletion option) * Pos 4 -> 0=1:1 / 1=1:n / (relation type) * 2=1:n (variables) / 3=1:n (timedef) */ public function fullTableRelations(string $strTable, array &$arrRelations = null): int { /* Define variable */ $arrRelations = array(); $arrData = array(); $intDC = 0; $intReturn = 0; /* Get relation data */ $strSQL = "SELECT * FROM `tbl_relationinformation` WHERE `master`='$strTable' AND `fullRelation`=1"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booReturn && ($intDC !== 0)) { foreach ($arrData as $elem) { $arrRelations[] = array('tableName1' => $elem['tableName1'], 'fieldName' => $elem['fieldName'], 'target1' => $elem['target1'], 'targetKey' => $elem['targetKey'], 'flags' => $elem['flags']); } $intReturn = 1; } return $intReturn; } /** * Searches any relation in the database and returns them as relation information * @param string $strTable Database table name * @param int $intMasterId Data ID from master table * @param string $strMasterfield Info field name from master table * @param int $intReporting Output as text - 0=yes, 1=no * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function infoRelation(string $strTable, int $intMasterId, string $strMasterfield, int $intReporting = 0): int { $intDeletion = 0; $arrDSCount = array(); $arrRelations = array(); $arrData = array(); $arrDataCheck = array(); $intReturn = $this->fullTableRelations($strTable, $arrRelations); if (($intReturn === 1) && ($intMasterId !== 0)) { /* Get master field data */ $strNewMasterfield = str_replace(',', '`,`', $strMasterfield); $strSQL = 'SELECT `' . $strNewMasterfield . '` FROM `' . $strTable . "` WHERE `id` = $intMasterId"; $this->myDBClass->hasSingleDataset($strSQL, $arrSource); if (substr_count($strMasterfield, ',') !== 0) { $arrTarget = explode(',', $strMasterfield); $strName = $arrSource[$arrTarget[0]] . '-' . $arrSource[$arrTarget[1]]; } else { $strName = $arrSource[$strMasterfield]; } $this->strInfoMessage .= '<span class="blackmessage">' . translate('Relation information for <b>') . $strName . translate('</b> of table <b>') . $strTable . ':</b></span>::'; $this->strInfoMessage .= '<span class="bluemessage">'; /* Walk through relations */ foreach ($arrRelations as $elem) { /* Process flags */ $arrFlags = explode(',', $elem['flags']); if ($elem['fieldName'] === 'check_command') { /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $elem['tableName1'] . '` ' . 'WHERE SUBSTRING_INDEX(`' . $elem['fieldName'] . "`,'!',1)= $intMasterId"; } else { /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $elem['tableName1'] . '` WHERE `' . $elem['fieldName'] . "`= $intMasterId"; } $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); /* Take only used relations */ if ($booReturn && ($intDataCount !== 0)) { /* Relation type */ if ((int)$arrFlags[3] === 1) { foreach ($arrData as $data) { if ($elem['fieldName'] === 'idMaster') { $strRef = 'idSlave'; /* Process special tables */ if ($elem['target1'] === 'tbl_service') { if ($elem['tableName1'] === 'tbl_lnkServicegroupToService') { $strRef = 'idSlaveS'; } } elseif ($elem['target1'] === 'tbl_host') { if ($elem['tableName1'] === 'tbl_lnkServicegroupToService') { $strRef = 'idSlaveH'; } } elseif ($elem['target1'] === 'tbl_hostgroup') { if ($elem['tableName1'] === 'tbl_lnkServicegroupToService') { $strRef = 'idSlaveHG'; } } } else { $strRef = 'idMaster'; } /* Get data */ /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $elem['tableName1'] . '` ' . 'LEFT JOIN `' . $elem['target1'] . '` ON `' . $strRef . '` = `id` ' . 'WHERE `' . $elem['fieldName'] . '` = ' . $data[$elem['fieldName']] . ' ' . 'AND `' . $strRef . '`=' . $data[$strRef]; $this->myDBClass->hasSingleDataset($strSQL, $arrDSTarget); if (substr_count($elem['targetKey'], ',') !== 0) { $arrTarget = explode(',', $elem['targetKey']); $strTarget = $arrDSTarget[$arrTarget[0]] . '-' . $arrDSTarget[$arrTarget[1]]; } else { $strTarget = $arrDSTarget[$elem['targetKey']]; } /* If the field is market as "required", check for any other entries */ if ((int)$arrFlags[0] === 1) { /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $elem['tableName1'] . '` ' . 'WHERE `' . $strRef . '` = ' . $arrDSTarget[$strRef]; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrDSCount, $intDCCount); if ($booReturn && ($intDCCount > 1)) { $this->strInfoMessage .= translate('Relation to <b>') . $elem['target1'] . translate('</b>, entry <b>') . $strTarget . '</b> - <span style="color:#00CC00;">' . translate('deletion <b>possible</b>') . '</span>::'; } else { $this->strInfoMessage .= translate('Relation to <b>') . $elem['target1'] . translate('</b>, entry <b>') . $strTarget . '</b> - <span style="color:#FF0000;">' . translate('deletion <b>not possible</b>') . '</span>::'; $intDeletion = 1; } } else { $this->strInfoMessage .= translate('Relation to <b>') . $elem['target1'] . translate('</b>, entry <b>') . $strTarget . '</b> - <span style="color:#00CC00;">' . translate('deletion <b>possible</b>') . '</span>::'; } } } elseif ((int)$arrFlags[3] === 0) { /* Fetch remote entry */ /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $elem['tableName1'] . '` ' . 'WHERE `' . $elem['fieldName'] . "`=$intMasterId"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrDataCheck, $intDCCheck); if ($booReturn && ($intDCCheck !== 0)) { foreach ($arrDataCheck as $data) { if (substr_count($elem['targetKey'], ',') !== 0) { $arrTarget = explode(',', $elem['targetKey']); $strTarget = $data[$arrTarget[0]] . '-' . $data[$arrTarget[1]]; } else { $strTarget = $data[$elem['targetKey']]; } if ((int)$arrFlags[0] === 1) { $this->strInfoMessage .= translate('Relation to <b>') . $elem['tableName1'] . translate('</b>, entry <b>') . $strTarget . '</b> - <span style="color:#FF0000;">' . translate('deletion <b>not possible</b>') . '</span>::'; $intDeletion = 1; } else { $this->strInfoMessage .= translate('Relation to <b>') . $elem['tableName1'] . translate('</b>, entry <b>') . $strTarget . '</b> - <span style="color:#00CC00;">' . translate('deletion <b>possible</b>') . '</span>::'; } } } } } } $this->strInfoMessage .= '</span>::'; } if ($intReporting === 1) { $this->strInfoMessage = ''; } return $intDeletion; } /** * Update the datasets for 1:n (optional 1:n:m) relations in the database table * @param string $strTable Database table name * @param int $intMasterId Data ID from master table * @param array $arrSlaveId Array with all data IDs from slave table * @param int $intMulti 0 = for 1:n relations * 1 = for 1:n:n relations * @return int 0 = successful / 1 = error */ public function dataUpdateRelation(string $strTable, int $intMasterId, array $arrSlaveId, int $intMulti = 0): int { $intReturn = 0; /* Remove any old relations */ $intReturn1 = $this->dataDeleteRelation($strTable, $intMasterId); if ($intReturn1 !== 0) { $intReturn = 1; } /* Insert the new relations */ if ($intReturn === 0) { $intReturn2 = $this->dataInsertRelation($strTable, $intMasterId, $arrSlaveId, $intMulti); if ($intReturn2 !== 0) { $intReturn = 1; } } return $intReturn; } /** * Removes any relation from the database * @param string $strTable Database table name * @param int $intMasterId Data ID from master table * @return int 0 = successful / 1 = error */ public function dataDeleteRelation(string $strTable, int $intMasterId): int { /* Define variables */ $intDataId = 0; /* Define the SQL statement */ /** @noinspection SqlResolve */ $strSQL = 'DELETE FROM `' . $strTable . "` WHERE `idMaster`=$intMasterId"; return $this->dataInsert($strSQL, $intDataId); } /** * Inserts any necessary dataset for an 1:n (optional 1:n:n) relation to the database table * @param string $strTable Database table name * @param int $intMasterId Data ID from master table * @param array $arrSlaveId Array with all data IDs from slave table * @param int $intMulti 0 = for 1:n relations * 1 = for 1:n:n relations * @return int 0 = successful / 1 = error */ public function dataInsertRelation(string $strTable, int $intMasterId, array $arrSlaveId, int $intMulti = 0): int { /* Define variables */ $intReturn = 0; $intDataId = 0; $strSQL = ''; /* Walk through the slave data ID array */ foreach ($arrSlaveId as $elem) { /* Pass empty and '*' values */ if ($elem === '0') { continue; } if ($elem === '*') { continue; } /* Process exclude values */ if (0 === strpos($elem, 'e')) { $elem = str_replace('e', '', $elem); $intExclude = 1; } else { $intExclude = 0; } /* Define the SQL statement */ if ($intMulti !== 0) { $arrValues = explode('::', $elem); /** @noinspection SqlResolve */ $strSQL = 'INSERT INTO `' . $strTable . "` SET `idMaster`=$intMasterId, `idSlaveH`=" . $arrValues[0] . ', `idSlaveHG`=' . $arrValues[1] . ', `idSlaveS`=' . $arrValues[2] . ", `exclude`=$intExclude"; } else if (($strTable === 'tbl_lnkServicedependencyToService_DS') || ($strTable === 'tbl_lnkServicedependencyToService_S') || ($strTable === 'tbl_lnkServiceescalationToService')) { /* Get service description */ $strSQLSrv = "SELECT `service_description` FROM `tbl_service` WHERE id=$elem"; $strService = $this->myDBClass->getFieldData($strSQLSrv); /** @noinspection SqlResolve */ $strSQL = 'INSERT INTO `' . $strTable . "` SET `idMaster`=$intMasterId, `idSlave`=$elem, " . "`strSlave`='" . addslashes($strService) . "', `exclude`=$intExclude"; } elseif (($strTable === 'tbl_lnkServiceToService') || ($strTable === 'tbl_lnkServicetemplateToService')) { $arrValues = explode('-', $elem); if (isset($arrValues[0], $arrValues[1])) { /** @noinspection SqlResolve */ $strSQL = 'INSERT INTO `' . $strTable . "` SET `idMaster`=$intMasterId, `idSlave`=$arrValues[0], " . " `idHost`=$arrValues[1]"; } } elseif (($strTable !== 'tbl_lnkTimeperiodToTimeperiod') && ($strTable !== 'tbl_lnkDatadomainToConfigtarget')) { /** @noinspection SqlResolve */ $strSQL = 'INSERT INTO `' . $strTable . '` ' . "SET `idMaster`=$intMasterId, `idSlave`=$elem, `exclude`=$intExclude"; } else { /** @noinspection SqlResolve */ $strSQL = 'INSERT INTO `' . $strTable . "` SET `idMaster`=$intMasterId, `idSlave`=$elem"; } /* Insert data */ $intReturn = $this->dataInsert($strSQL, $intDataId); if ($intReturn !== 0) { $intReturn = 1; } } return $intReturn; } /** * Deactivates one or many datasets in the table be setting 'active' to '0'. Alternatively, a single record * ID can be specified or evaluated by the values of $_POST['chbId_n'] passed parameters, where n is the * record ID must match. * @param string $strTableName Table name * @param int $intDataId Individual record ID, which is to be activated * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataDeactivate(string $strTableName, int $intDataId = 0): int { /* Define variables */ $intReturn = 1; $arrData = array(); /* Get write access groups */ $strAccess = $this->myVisClass->getAccessGroups('write'); /* Activate datasets */ /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` ' . 'WHERE `config_id`=' . $this->intDomainId . " AND `access_group` IN ($strAccess)"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn && ($intDataCount !== 0)) { $intActivateCount = 0; foreach ($arrData as $elem) { $strChbName = 'chbId_' . $elem['id']; /* was the current record is marked for activate? */ if ((($intDataId === (int)$elem['id']) || ((filter_input(INPUT_POST, $strChbName) !== null) && (filter_input(INPUT_POST, $strChbName, FILTER_UNSAFE_RAW) === 'on'))) && $this->infoRelation($strTableName, $elem['id'], 'id', 1) === 0) { /* Update dataset */ if (($strTableName === 'tbl_service') || ($strTableName === 'tbl_host')) { $strSQL = 'UPDATE `' . $strTableName . "` SET `active`='0', `last_modified`=now() " . 'WHERE `id`=' . $elem['id']; } else { $strSQL = 'UPDATE `' . $strTableName . "` SET `active`='0' WHERE `id`=" . $elem['id']; } $this->myDBClass->insertData($strSQL); $intActivateCount++; } } /* Process information */ if ($intActivateCount === 0) { $this->processClassMessage(translate('No dataset deactivated. Maybe the dataset does not exist, it ' . 'is protected from deactivation, no dataset was selected or you do not have write permission. ' . 'Use the "info" function for detailed informations about relations!') . '::', $this->strErrorMessage); } else { $this->updateStatusTable($strTableName); $this->processClassMessage(translate('Dataset successfully deactivated. Affected rows:') . ' ' . $intActivateCount . '::', $this->strInfoMessage); $this->writeLog(translate('Deactivate dataset from table:') . " $strTableName " . translate('- with affected rows:') . ' ' . $this->myDBClass->intAffectedRows); $intReturn = 0; } } else { $this->processClassMessage(translate('No dataset deactivated. Maybe the dataset does not exist or you ' . 'do not have write permission.') . '::', $this->strErrorMessage); } return $intReturn; } /** * Activates one or many datasets in the table be setting 'active' to '1'. Alternatively, a single record ID can * be specified or evaluated by the values of $_POST['chbId_n'] passed parameters, where n is the record ID must * match. * @param string $strTableName Table name * @param int $intDataId Individual record ID, which is to be activated * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function dataActivate(string $strTableName, int $intDataId = 0): int { /* Define variables */ $intReturn = 1; $arrData = array(); /* Get write access groups */ $strAccess = $this->myVisClass->getAccessGroups('write'); /* Activate datasets */ /** @noinspection SqlResolve */ $strSQL = 'SELECT `id` FROM `' . $strTableName . '` ' . 'WHERE `config_id`=' . $this->intDomainId . " AND `access_group` IN ($strAccess)"; $booReturn = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDataCount); if ($booReturn && ($intDataCount !== 0)) { $intActivateCount = 0; foreach ($arrData as $elem) { $strChbName = 'chbId_' . $elem['id']; /* was the current record marked for activate? */ if (($intDataId === (int)$elem['id']) || ((filter_input(INPUT_POST, $strChbName) !== null) && (filter_input(INPUT_POST, $strChbName, FILTER_UNSAFE_RAW) === 'on'))) { /* Update dataset */ if (($strTableName === 'tbl_service') || ($strTableName === 'tbl_host')) { $strSQL = 'UPDATE `' . $strTableName . "` SET `active`='1', `last_modified`=now() " . 'WHERE `id`=' . $elem['id']; } else { $strSQL = 'UPDATE `' . $strTableName . "` SET `active`='1' WHERE `id`=" . $elem['id']; } $this->myDBClass->insertData($strSQL); $intActivateCount++; } } /* Process information */ if ($intActivateCount === 0) { $this->processClassMessage(translate('No dataset activated. Maybe the dataset does not exist, no ' . 'dataset was selected or you do not have write permission.') . '::', $this->strErrorMessage); } else { $this->updateStatusTable($strTableName); $this->processClassMessage(translate('Dataset successfully activated. Affected rows:') . ' ' . $intActivateCount . '::', $this->strInfoMessage); $this->writeLog(translate('Activate dataset from table:') . " $strTableName " . translate('- with affected rows:') . ' ' . $this->myDBClass->intAffectedRows); $intReturn = 0; } } else { $this->processClassMessage(translate('No dataset activated. Maybe the dataset does not exist or you do ' . 'not have write permission.') . '::', $this->strErrorMessage); } return $intReturn; } /** * Updates the hash field im some configuration objects * @param string $strTable Table name * @param int $intId Data ID * @return int 0 = successful / 1 = error * Status message is stored in message class variables */ public function updateHash(string $strTable, int $intId): int { /* Define variables */ $strRawString = ''; $arrData = array(); $intDC = 0; $intDataID = 0; /* Service table */ if ($strTable === 'tbl_service') { /* Get any hosts and host_groups */ $strSQL = 'SELECT `host_name` AS `item_name` FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkServiceToHost` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION SELECT `hostgroup_name` AS `item_name` FROM `tbl_hostgroup` ' . 'LEFT JOIN `tbl_lnkServiceToHostgroup` ON `idSlave`=`id` ' . 'WHERE `idMaster`=' . $intId . ' ORDER BY `item_name`'; $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { foreach ($arrData as $elem) { $strRawString .= $elem['item_name'] . ','; } } $strSQL = 'SELECT * FROM `tbl_service` WHERE `id`=' . $intId; $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { if ($arrData[0]['service_description'] !== '') { $strRawString .= $arrData[0]['service_description'] . ','; } if ($arrData[0]['display_name'] !== '') { $strRawString .= $arrData[0]['display_name'] . ','; } if ($arrData[0]['check_command'] !== '') { $arrField = explode('!', $arrData[0]['check_command']); $strCommand = strstr($arrData[0]['check_command'], '!'); $strSQLRel = 'SELECT `command_name` FROM `tbl_command` WHERE `id`=' . $arrField[0]; $strName = $this->myDBClass->getFieldData($strSQLRel); $strRawString .= $strName . $strCommand . ','; } } } if (($strTable === 'tbl_hostdependency') || ($strTable === 'tbl_servicedependency')) { /* Get * values */ /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $strTable . '` WHERE `id`=' . $intId; $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { if (isset($arrData[0]['dependent_host_name']) && ((int)$arrData[0]['dependent_host_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['dependent_hostgroup_name']) && ((int)$arrData[0]['dependent_hostgroup_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['host_name']) && ((int)$arrData[0]['host_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['hostgroup_name']) && ((int)$arrData[0]['hostgroup_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['dependent_service_description']) && ((int)$arrData[0]['dependent_service_description'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['service_description']) && ((int)$arrData[0]['service_description'] === 2)) { $strRawString .= 'any,'; } } if ($strTable === 'tbl_hostdependency') { /* Get any hosts and host_groups */ $strSQL = 'SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkHostdependencyToHost_DH` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . "LEFT JOIN `tbl_lnkHostdependencyToHostgroup_DH` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkHostdependencyToHost_H` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . 'LEFT JOIN `tbl_lnkHostdependencyToHostgroup_H` ON `idSlave`=`id` WHERE `idMaster`=' . $intId; } if ($strTable === 'tbl_servicedependency') { /* Get any hosts and host_groups */ $strSQL = 'SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkServicedependencyToHost_DH` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . 'LEFT JOIN `tbl_lnkServicedependencyToHostgroup_DH` ON `idSlave`=`id` ' . "WHERE `idMaster`=$intId " . 'UNION ALL SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkServicedependencyToHost_H` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . 'LEFT JOIN `tbl_lnkServicedependencyToHostgroup_H` ON `idSlave`=`id` ' . "WHERE `idMaster`=$intId " . 'UNION ALL SELECT `strSlave` AS `item_name`, exclude ' . "FROM `tbl_lnkServicedependencyToService_DS` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `strSlave` AS `item_name`, exclude ' . "FROM `tbl_lnkServicedependencyToService_S` WHERE `idMaster`=$intId"; } $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { foreach ($arrData as $elem) { if ((int)$elem['exclude'] === 0) { $strRawString .= $elem['item_name'] . ','; } else { $strRawString .= 'not_' . $elem['item_name'] . ','; } } $strRawString = substr($strRawString, 0, -1); } } if (($strTable === 'tbl_hostescalation') || ($strTable === 'tbl_serviceescalation')) { /* Get * values */ /** @noinspection SqlResolve */ $strSQL = 'SELECT * FROM `' . $strTable . '` WHERE `id`=' . $intId; $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { if (isset($arrData[0]['host_name']) && ((int)$arrData[0]['host_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['hostgroup_name']) && ((int)$arrData[0]['hostgroup_name'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['contacts']) && ((int)$arrData[0]['contacts'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['contact_groups']) && ((int)$arrData[0]['contact_groups'] === 2)) { $strRawString .= 'any,'; } if (isset($arrData[0]['service_description']) && ((int)$arrData[0]['service_description'] === 2)) { $strRawString .= 'any,'; } } /* Get any hosts, host_groups, contacts and contact_groups */ if ($strTable === 'tbl_hostescalation') { $strSQL = 'SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkHostescalationToHost` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . "LEFT JOIN `tbl_lnkHostescalationToHostgroup` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `contact_name` AS `item_name`, exclude FROM `tbl_contact` ' . "LEFT JOIN `tbl_lnkHostescalationToContact` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `contactgroup_name` AS `item_name`, exclude FROM `tbl_contactgroup` ' . "LEFT JOIN `tbl_lnkHostescalationToContactgroup` ON `idSlave`=`id` WHERE `idMaster`=$intId"; } if ($strTable === 'tbl_serviceescalation') { $strSQL = 'SELECT `host_name` AS `item_name`, exclude FROM `tbl_host` ' . "LEFT JOIN `tbl_lnkServiceescalationToHost` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `hostgroup_name` AS `item_name`, exclude FROM `tbl_hostgroup` ' . "LEFT JOIN `tbl_lnkServiceescalationToHostgroup` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `contact_name` AS `item_name`, exclude FROM `tbl_contact` ' . "LEFT JOIN `tbl_lnkServiceescalationToContact` ON `idSlave`=`id` WHERE `idMaster`=$intId " . 'UNION ALL SELECT `contactgroup_name` AS `item_name`, exclude FROM `tbl_contactgroup` ' . 'LEFT JOIN `tbl_lnkServiceescalationToContactgroup` ON `idSlave`=`id` ' . "WHERE `idMaster`=$intId " . 'UNION ALL SELECT `strSlave` AS `item_name`, exclude ' . "FROM `tbl_lnkServiceescalationToService` WHERE `idMaster`=$intId"; } $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { foreach ($arrData as $elem) { if ((int)$elem['exclude'] === 0) { $strRawString .= $elem['item_name'] . ','; } else { $strRawString .= 'not_' . $elem['item_name'] . ','; } } $strRawString = substr($strRawString, 0, -1); } } if ($strTable === 'tbl_serviceextinfo') { /* Get any hosts and host_groups */ $strSQL = 'SELECT `tbl_host`.`host_name` AS `item_name` FROM `tbl_host` ' . 'LEFT JOIN `tbl_serviceextinfo` ON `tbl_host`.`id`=`tbl_serviceextinfo`.`host_name` ' . "WHERE `tbl_serviceextinfo`.`id`=$intId " . 'UNION SELECT `tbl_service`.`service_description` AS `item_name` FROM `tbl_service` ' . 'LEFT JOIN `tbl_serviceextinfo` ON ' . '`tbl_service`.`id`=`tbl_serviceextinfo`.`service_description` ' . "WHERE `tbl_serviceextinfo`.`id`=$intId ORDER BY `item_name`"; $booRet = $this->myDBClass->hasDataArray($strSQL, $arrData, $intDC); if ($booRet && ($intDC !== 0)) { foreach ($arrData as $elem) { $strRawString .= $elem['item_name'] . ','; } $strRawString = substr($strRawString, 0, -1); } } /* Remove blanks */ while (substr_count($strRawString, ' ') !== 0) { $strRawString = str_replace(' ', '', $strRawString); } /* Sort hash string */ $arrTemp = explode(',', $strRawString); sort($arrTemp); $strRawString = implode(',', $arrTemp); /* Update has in database */ $strSQL = 'UPDATE `' . $strTable . "` SET `import_hash`='" . sha1($strRawString) . "' WHERE `id`='$intId'"; return $this->dataInsert($strSQL, $intDataID); } }