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 */
25class CDHost extends CApiService {
26
27	protected $tableName = 'dhosts';
28	protected $tableAlias = 'dh';
29	protected $sortColumns = ['dhostid', 'druleid'];
30
31	/**
32	 * Get host data.
33	 *
34	 * @param array  $options
35	 * @param array  $options['groupids']				HostGroup IDs
36	 * @param bool   $options['monitored_hosts']		only monitored Hosts
37	 * @param bool   $options['templated_hosts']		include templates in result
38	 * @param bool   $options['with_items']				only with items
39	 * @param bool   $options['with_triggers']			only with triggers
40	 * @param bool   $options['with_httptests']			only with http tests
41	 * @param bool   $options['with_graphs']			only with graphs
42	 * @param bool   $options['editable']				only with read-write permission. Ignored for SuperAdmins
43	 * @param bool   $options['selectTemplates']		select Templates
44	 * @param bool   $options['selectItems']			select Items
45	 * @param bool   $options['selectTriggers']			select Triggers
46	 * @param bool   $options['selectGraphs']			select Graphs
47	 * @param int    $options['count']					count Hosts, returned column name is rowscount
48	 * @param string $options['pattern']				search hosts by pattern in Host name
49	 * @param string $options['extendPattern']			search hosts by pattern in Host name, ip and DNS
50	 * @param int    $options['limit']					limit selection
51	 * @param string $options['sortfield']				field to sort by
52	 * @param string $options['sortorder']				sort order
53	 *
54	 * @return array									Host data as array or false if error
55	 */
56	public function get($options = []) {
57		$result = [];
58
59		$sqlParts = [
60			'select'	=> ['dhosts' => 'dh.dhostid'],
61			'from'		=> ['dhosts' => 'dhosts dh'],
62			'where'		=> [],
63			'group'		=> [],
64			'order'		=> [],
65			'limit'		=> null
66		];
67
68		$defOptions = [
69			'druleids'					=> null,
70			'dhostids'					=> null,
71			'dserviceids'				=> null,
72			'editable'					=> false,
73			'nopermissions'				=> null,
74			// filter
75			'filter'					=> null,
76			'search'					=> null,
77			'searchByAny'				=> null,
78			'startSearch'				=> false,
79			'excludeSearch'				=> false,
80			'searchWildcardsEnabled'	=> null,
81			// output
82			'output'					=> API_OUTPUT_EXTEND,
83			'selectDRules'				=> null,
84			'selectDServices'			=> null,
85			'countOutput'				=> false,
86			'groupCount'				=> false,
87			'preservekeys'				=> false,
88			'sortfield'					=> '',
89			'sortorder'					=> '',
90			'limit'						=> null,
91			'limitSelects'				=> null
92		];
93		$options = zbx_array_merge($defOptions, $options);
94
95		if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
96			return [];
97		}
98
99// dhostids
100		if (!is_null($options['dhostids'])) {
101			zbx_value2array($options['dhostids']);
102			$sqlParts['where']['dhostid'] = dbConditionInt('dh.dhostid', $options['dhostids']);
103		}
104
105// druleids
106		if (!is_null($options['druleids'])) {
107			zbx_value2array($options['druleids']);
108
109			$sqlParts['where']['druleid'] = dbConditionInt('dh.druleid', $options['druleids']);
110
111			if ($options['groupCount']) {
112				$sqlParts['group']['druleid'] = 'dh.druleid';
113			}
114		}
115
116// dserviceids
117		if (!is_null($options['dserviceids'])) {
118			zbx_value2array($options['dserviceids']);
119
120			$sqlParts['from']['dservices'] = 'dservices ds';
121			$sqlParts['where'][] = dbConditionInt('ds.dserviceid', $options['dserviceids']);
122			$sqlParts['where']['dhds'] = 'dh.dhostid=ds.dhostid';
123
124			if ($options['groupCount']) {
125				$sqlParts['group']['dserviceids'] = 'ds.dserviceid';
126			}
127		}
128
129// filter
130		if (is_array($options['filter'])) {
131			$this->dbFilter('dhosts dh', $options, $sqlParts);
132		}
133
134// search
135		if (is_array($options['search'])) {
136			zbx_db_search('dhosts dh', $options, $sqlParts);
137		}
138
139// limit
140		if (zbx_ctype_digit($options['limit']) && $options['limit']) {
141			$sqlParts['limit'] = $options['limit'];
142		}
143//-------
144
145		$sqlParts = $this->applyQueryOutputOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
146		$sqlParts = $this->applyQuerySortOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
147		$res = DBselect(self::createSelectQueryFromParts($sqlParts), $sqlParts['limit']);
148		while ($dhost = DBfetch($res)) {
149			if ($options['countOutput']) {
150				if ($options['groupCount']) {
151					$result[] = $dhost;
152				}
153				else {
154					$result = $dhost['rowscount'];
155				}
156			}
157			else {
158				$result[$dhost['dhostid']] = $dhost;
159			}
160		}
161
162		if ($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 (!$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']) {
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					$result[$dhostid]['dservices'] = array_key_exists($dhostid, $dservices)
238						? $dservices[$dhostid]['rowscount']
239						: '0';
240				}
241			}
242		}
243
244		return $result;
245	}
246}
247