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	public const ACCESS_RULES = [
28		'get' => ['min_user_type' => USER_TYPE_ZABBIX_USER]
29	];
30
31	protected $tableName = 'dhosts';
32	protected $tableAlias = 'dh';
33	protected $sortColumns = ['dhostid', 'druleid'];
34
35	/**
36	 * Get host data.
37	 *
38	 * @param array  $options
39	 * @param array  $options['groupids']				HostGroup IDs
40	 * @param bool   $options['monitored_hosts']		only monitored Hosts
41	 * @param bool   $options['templated_hosts']		include templates in result
42	 * @param bool   $options['with_items']				only with items
43	 * @param bool   $options['with_triggers']			only with triggers
44	 * @param bool   $options['with_httptests']			only with http tests
45	 * @param bool   $options['with_graphs']			only with graphs
46	 * @param bool   $options['editable']				only with read-write permission. Ignored for SuperAdmins
47	 * @param bool   $options['selectTemplates']		select Templates
48	 * @param bool   $options['selectItems']			select Items
49	 * @param bool   $options['selectTriggers']			select Triggers
50	 * @param bool   $options['selectGraphs']			select Graphs
51	 * @param int    $options['count']					count Hosts, returned column name is rowscount
52	 * @param string $options['pattern']				search hosts by pattern in Host name
53	 * @param string $options['extendPattern']			search hosts by pattern in Host name, ip and DNS
54	 * @param int    $options['limit']					limit selection
55	 * @param string $options['sortfield']				field to sort by
56	 * @param string $options['sortorder']				sort order
57	 *
58	 * @return array									Host data as array or false if error
59	 */
60	public function get($options = []) {
61		$result = [];
62
63		$sqlParts = [
64			'select'	=> ['dhosts' => 'dh.dhostid'],
65			'from'		=> ['dhosts' => 'dhosts dh'],
66			'where'		=> [],
67			'group'		=> [],
68			'order'		=> [],
69			'limit'		=> null
70		];
71
72		$defOptions = [
73			'druleids'					=> null,
74			'dhostids'					=> null,
75			'dserviceids'				=> null,
76			'editable'					=> false,
77			'nopermissions'				=> null,
78			// filter
79			'filter'					=> null,
80			'search'					=> null,
81			'searchByAny'				=> null,
82			'startSearch'				=> false,
83			'excludeSearch'				=> false,
84			'searchWildcardsEnabled'	=> null,
85			// output
86			'output'					=> API_OUTPUT_EXTEND,
87			'selectDRules'				=> null,
88			'selectDServices'			=> null,
89			'countOutput'				=> false,
90			'groupCount'				=> false,
91			'preservekeys'				=> false,
92			'sortfield'					=> '',
93			'sortorder'					=> '',
94			'limit'						=> null,
95			'limitSelects'				=> null
96		];
97		$options = zbx_array_merge($defOptions, $options);
98
99		if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
100			return [];
101		}
102
103// dhostids
104		if (!is_null($options['dhostids'])) {
105			zbx_value2array($options['dhostids']);
106			$sqlParts['where']['dhostid'] = dbConditionInt('dh.dhostid', $options['dhostids']);
107		}
108
109// druleids
110		if (!is_null($options['druleids'])) {
111			zbx_value2array($options['druleids']);
112
113			$sqlParts['where']['druleid'] = dbConditionInt('dh.druleid', $options['druleids']);
114
115			if ($options['groupCount']) {
116				$sqlParts['group']['druleid'] = 'dh.druleid';
117			}
118		}
119
120// dserviceids
121		if (!is_null($options['dserviceids'])) {
122			zbx_value2array($options['dserviceids']);
123
124			$sqlParts['from']['dservices'] = 'dservices ds';
125			$sqlParts['where'][] = dbConditionInt('ds.dserviceid', $options['dserviceids']);
126			$sqlParts['where']['dhds'] = 'dh.dhostid=ds.dhostid';
127
128			if ($options['groupCount']) {
129				$sqlParts['group']['dserviceids'] = 'ds.dserviceid';
130			}
131		}
132
133// filter
134		if (is_array($options['filter'])) {
135			$this->dbFilter('dhosts dh', $options, $sqlParts);
136		}
137
138// search
139		if (is_array($options['search'])) {
140			zbx_db_search('dhosts dh', $options, $sqlParts);
141		}
142
143// limit
144		if (zbx_ctype_digit($options['limit']) && $options['limit']) {
145			$sqlParts['limit'] = $options['limit'];
146		}
147//-------
148
149		$sqlParts = $this->applyQueryOutputOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
150		$sqlParts = $this->applyQuerySortOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts);
151		$res = DBselect(self::createSelectQueryFromParts($sqlParts), $sqlParts['limit']);
152		while ($dhost = DBfetch($res)) {
153			if ($options['countOutput']) {
154				if ($options['groupCount']) {
155					$result[] = $dhost;
156				}
157				else {
158					$result = $dhost['rowscount'];
159				}
160			}
161			else {
162				$result[$dhost['dhostid']] = $dhost;
163			}
164		}
165
166		if ($options['countOutput']) {
167			return $result;
168		}
169
170		if ($result) {
171			$result = $this->addRelatedObjects($options, $result);
172			$result = $this->unsetExtraFields($result, ['druleid'], $options['output']);
173		}
174
175		// removing keys (hash -> array)
176		if (!$options['preservekeys']) {
177			$result = zbx_cleanHashes($result);
178		}
179
180		return $result;
181	}
182
183	protected function applyQueryOutputOptions($tableName, $tableAlias, array $options, array $sqlParts) {
184		$sqlParts = parent::applyQueryOutputOptions($tableName, $tableAlias, $options, $sqlParts);
185
186		if (!$options['countOutput']) {
187			if ($options['selectDRules'] !== null) {
188				$sqlParts = $this->addQuerySelect('dh.druleid', $sqlParts);
189			}
190		}
191
192		return $sqlParts;
193	}
194
195	protected function addRelatedObjects(array $options, array $result) {
196		$result = parent::addRelatedObjects($options, $result);
197
198		$dhostIds = array_keys($result);
199
200		// select_drules
201		if ($options['selectDRules'] !== null && $options['selectDRules'] != API_OUTPUT_COUNT) {
202			$relationMap = $this->createRelationMap($result, 'dhostid', 'druleid');
203			$drules = API::DRule()->get([
204				'output' => $options['selectDRules'],
205				'druleids' => $relationMap->getRelatedIds(),
206				'preservekeys' => true
207			]);
208
209			if (!is_null($options['limitSelects'])) {
210				order_result($drules, 'name');
211			}
212
213			$result = $relationMap->mapMany($result, $drules, 'drules', $options['limitSelects']);
214		}
215
216		// selectDServices
217		if (!is_null($options['selectDServices'])) {
218			if ($options['selectDServices'] != API_OUTPUT_COUNT) {
219				$dservices = API::DService()->get([
220					'output' => $this->outputExtend($options['selectDServices'], ['dserviceid', 'dhostid']),
221					'dhostids' => $dhostIds,
222					'preservekeys' => true
223				]);
224				$relationMap = $this->createRelationMap($dservices, 'dhostid', 'dserviceid');
225
226				$dservices = $this->unsetExtraFields($dservices, ['dserviceid', 'dhostid'], $options['selectDServices']);
227				if (!is_null($options['limitSelects'])) {
228					order_result($dservices, 'name');
229				}
230				$result = $relationMap->mapMany($result, $dservices, 'dservices', $options['limitSelects']);
231			}
232			else {
233				$dservices = API::DService()->get([
234					'output' => $options['selectDServices'],
235					'dhostids' => $dhostIds,
236					'countOutput' => true,
237					'groupCount' => true
238				]);
239				$dservices = zbx_toHash($dservices, 'dhostid');
240				foreach ($result as $dhostid => $dhost) {
241					$result[$dhostid]['dservices'] = array_key_exists($dhostid, $dservices)
242						? $dservices[$dhostid]['rowscount']
243						: '0';
244				}
245			}
246		}
247
248		return $result;
249	}
250}
251