1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * Class containing methods for operations with discovery hosts.
24 *
25 * @package API
26 */
27class CDHost extends CApiService {
28
29	protected $tableName = 'dhosts';
30	protected $tableAlias = 'dh';
31	protected $sortColumns = ['dhostid', 'druleid'];
32
33	/**
34	 * Get host data.
35	 *
36	 * @param array  $options
37	 * @param array  $options['groupids']				HostGroup IDs
38	 * @param bool   $options['monitored_hosts']		only monitored Hosts
39	 * @param bool   $options['templated_hosts']		include templates in result
40	 * @param bool   $options['with_items']				only with items
41	 * @param bool   $options['with_triggers']			only with triggers
42	 * @param bool   $options['with_httptests']			only with http tests
43	 * @param bool   $options['with_graphs']			only with graphs
44	 * @param bool   $options['editable']				only with read-write permission. Ignored for SuperAdmins
45	 * @param bool   $options['selectTemplates']		select Templates
46	 * @param bool   $options['selectItems']			select Items
47	 * @param bool   $options['selectTriggers']			select Triggers
48	 * @param bool   $options['selectGraphs']			select Graphs
49	 * @param int    $options['count']					count Hosts, returned column name is rowscount
50	 * @param string $options['pattern']				search hosts by pattern in Host name
51	 * @param string $options['extendPattern']			search hosts by pattern in Host name, ip and DNS
52	 * @param int    $options['limit']					limit selection
53	 * @param string $options['sortfield']				field to sort by
54	 * @param string $options['sortorder']				sort order
55	 *
56	 * @return array									Host data as array or false if error
57	 */
58	public function get($options = []) {
59		$result = [];
60
61		$sqlParts = [
62			'select'	=> ['dhosts' => 'dh.dhostid'],
63			'from'		=> ['dhosts' => 'dhosts dh'],
64			'where'		=> [],
65			'group'		=> [],
66			'order'		=> [],
67			'limit'		=> null
68		];
69
70		$defOptions = [
71			'druleids'					=> null,
72			'dhostids'					=> null,
73			'dserviceids'				=> null,
74			'editable'					=> false,
75			'nopermissions'				=> null,
76			// filter
77			'filter'					=> null,
78			'search'					=> null,
79			'searchByAny'				=> null,
80			'startSearch'				=> null,
81			'excludeSearch'				=> null,
82			'searchWildcardsEnabled'	=> null,
83			// output
84			'output'					=> API_OUTPUT_EXTEND,
85			'selectDRules'				=> null,
86			'selectDServices'			=> null,
87			'countOutput'				=> null,
88			'groupCount'				=> null,
89			'preservekeys'				=> null,
90			'sortfield'					=> '',
91			'sortorder'					=> '',
92			'limit'						=> null,
93			'limitSelects'				=> null
94		];
95		$options = zbx_array_merge($defOptions, $options);
96
97		if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
98			return [];
99		}
100
101// dhostids
102		if (!is_null($options['dhostids'])) {
103			zbx_value2array($options['dhostids']);
104			$sqlParts['where']['dhostid'] = dbConditionInt('dh.dhostid', $options['dhostids']);
105		}
106
107// druleids
108		if (!is_null($options['druleids'])) {
109			zbx_value2array($options['druleids']);
110
111			$sqlParts['where']['druleid'] = dbConditionInt('dh.druleid', $options['druleids']);
112
113			if (!is_null($options['groupCount'])) {
114				$sqlParts['group']['druleid'] = 'dh.druleid';
115			}
116		}
117
118// dserviceids
119		if (!is_null($options['dserviceids'])) {
120			zbx_value2array($options['dserviceids']);
121
122			$sqlParts['from']['dservices'] = 'dservices ds';
123			$sqlParts['where'][] = dbConditionInt('ds.dserviceid', $options['dserviceids']);
124			$sqlParts['where']['dhds'] = 'dh.dhostid=ds.dhostid';
125
126			if (!is_null($options['groupCount'])) {
127				$sqlParts['group']['dserviceids'] = 'ds.dserviceid';
128			}
129		}
130
131// filter
132		if (is_array($options['filter'])) {
133			$this->dbFilter('dhosts dh', $options, $sqlParts);
134		}
135
136// search
137		if (is_array($options['search'])) {
138			zbx_db_search('dhosts dh', $options, $sqlParts);
139		}
140
141// limit
142		if (zbx_ctype_digit($options['limit']) && $options['limit']) {
143			$sqlParts['limit'] = $options['limit'];
144		}
145//-------
146
147		$sqlParts = $this->applyQueryOutputOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
148		$sqlParts = $this->applyQuerySortOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
149		$res = DBselect($this->createSelectQueryFromParts($sqlParts), $sqlParts['limit']);
150		while ($dhost = DBfetch($res)) {
151			if (!is_null($options['countOutput'])) {
152				if (!is_null($options['groupCount']))
153					$result[] = $dhost;
154				else
155					$result = $dhost['rowscount'];
156			}
157			else {
158				$result[$dhost['dhostid']] = $dhost;
159			}
160		}
161
162		if (!is_null($options['countOutput'])) {
163			return $result;
164		}
165
166		if ($result) {
167			$result = $this->addRelatedObjects($options, $result);
168			$result = $this->unsetExtraFields($result, ['druleid'], $options['output']);
169		}
170
171// removing keys (hash -> array)
172		if (is_null($options['preservekeys'])) {
173			$result = zbx_cleanHashes($result);
174		}
175
176	return $result;
177	}
178
179	protected function applyQueryOutputOptions($tableName, $tableAlias, array $options, array $sqlParts) {
180		$sqlParts = parent::applyQueryOutputOptions($tableName, $tableAlias, $options, $sqlParts);
181
182		if ($options['countOutput'] === null) {
183			if ($options['selectDRules'] !== null) {
184				$sqlParts = $this->addQuerySelect('dh.druleid', $sqlParts);
185			}
186		}
187
188		return $sqlParts;
189	}
190
191	protected function addRelatedObjects(array $options, array $result) {
192		$result = parent::addRelatedObjects($options, $result);
193
194		$dhostIds = array_keys($result);
195
196		// select_drules
197		if ($options['selectDRules'] !== null && $options['selectDRules'] != API_OUTPUT_COUNT) {
198			$relationMap = $this->createRelationMap($result, 'dhostid', 'druleid');
199			$drules = API::DRule()->get([
200				'output' => $options['selectDRules'],
201				'druleids' => $relationMap->getRelatedIds(),
202				'preservekeys' => true
203			]);
204
205			if (!is_null($options['limitSelects'])) {
206				order_result($drules, 'name');
207			}
208
209			$result = $relationMap->mapMany($result, $drules, 'drules', $options['limitSelects']);
210		}
211
212		// selectDServices
213		if (!is_null($options['selectDServices'])) {
214			if ($options['selectDServices'] != API_OUTPUT_COUNT) {
215				$dservices = API::DService()->get([
216					'output' => $this->outputExtend($options['selectDServices'], ['dserviceid', 'dhostid']),
217					'dhostids' => $dhostIds,
218					'preservekeys' => true
219				]);
220				$relationMap = $this->createRelationMap($dservices, 'dhostid', 'dserviceid');
221
222				$dservices = $this->unsetExtraFields($dservices, ['dserviceid', 'dhostid'], $options['selectDServices']);
223				if (!is_null($options['limitSelects'])) {
224					order_result($dservices, 'name');
225				}
226				$result = $relationMap->mapMany($result, $dservices, 'dservices', $options['limitSelects']);
227			}
228			else {
229				$dservices = API::DService()->get([
230					'output' => $options['selectDServices'],
231					'dhostids' => $dhostIds,
232					'countOutput' => true,
233					'groupCount' => true
234				]);
235				$dservices = zbx_toHash($dservices, 'dhostid');
236				foreach ($result as $dhostid => $dhost) {
237					if (isset($dservices[$dhostid]))
238						$result[$dhostid]['dservices'] = $dservices[$dhostid]['rowscount'];
239					else
240						$result[$dhostid]['dservices'] = 0;
241				}
242			}
243		}
244
245		return $result;
246	}
247}
248