PageRenderTime 44ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/zabbix-2.0.1/frontends/php/api/classes/CApplication.php

#
PHP | 851 lines | 648 code | 94 blank | 109 comment | 121 complexity | bf41c42a192f61ecbe677de25285d332 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. <?php
  2. /*
  3. ** Zabbix
  4. ** Copyright (C) 2000-2011 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. <?php
  22. /**
  23. * @package API
  24. */
  25. class CApplication extends CZBXAPI {
  26. protected $tableName = 'applications';
  27. protected $tableAlias = 'a';
  28. /**
  29. * Get Applications data
  30. *
  31. * @param array $options
  32. * @param array $options['itemids']
  33. * @param array $options['hostids']
  34. * @param array $options['groupids']
  35. * @param array $options['triggerids']
  36. * @param array $options['applicationids']
  37. * @param boolean $options['status']
  38. * @param boolean $options['editable']
  39. * @param boolean $options['count']
  40. * @param string $options['pattern']
  41. * @param int $options['limit']
  42. * @param string $options['order']
  43. * @return array|int item data as array or false if error
  44. */
  45. public function get($options = array()) {
  46. $result = array();
  47. $userType = self::$userData['type'];
  48. $userid = self::$userData['userid'];
  49. $sortColumns = array('applicationid', 'name');
  50. $subselectsAllowedOutputs = array(API_OUTPUT_REFER, API_OUTPUT_EXTEND);
  51. $sqlParts = array(
  52. 'select' => array('apps' => 'a.applicationid'),
  53. 'from' => array('applications' => 'applications a'),
  54. 'where' => array(),
  55. 'group' => array(),
  56. 'order' => array(),
  57. 'limit' => null
  58. );
  59. $defOptions = array(
  60. 'nodeids' => null,
  61. 'groupids' => null,
  62. 'templateids' => null,
  63. 'hostids' => null,
  64. 'itemids' => null,
  65. 'applicationids' => null,
  66. 'templated' => null,
  67. 'editable' => null,
  68. 'inherited' => null,
  69. 'nopermissions' => null,
  70. // filter
  71. 'filter' => null,
  72. 'search' => null,
  73. 'searchByAny' => null,
  74. 'startSearch' => null,
  75. 'exludeSearch' => null,
  76. 'searchWildcardsEnabled' => null,
  77. // output
  78. 'output' => API_OUTPUT_REFER,
  79. 'expandData' => null,
  80. 'selectHosts' => null,
  81. 'selectItems' => null,
  82. 'countOutput' => null,
  83. 'groupCount' => null,
  84. 'preservekeys' => null,
  85. 'sortfield' => '',
  86. 'sortorder' => '',
  87. 'limit' => null
  88. );
  89. $options = zbx_array_merge($defOptions, $options);
  90. // editable + PERMISSION CHECK
  91. if (USER_TYPE_SUPER_ADMIN == $userType || $options['nopermissions']) {
  92. }
  93. else {
  94. $permission = $options['editable'] ? PERM_READ_WRITE : PERM_READ_ONLY;
  95. $sqlParts['from']['hosts_groups'] = 'hosts_groups hg';
  96. $sqlParts['from']['rights'] = 'rights r';
  97. $sqlParts['from']['users_groups'] = 'users_groups ug';
  98. $sqlParts['where'][] = 'hg.hostid=a.hostid';
  99. $sqlParts['where'][] = 'r.id=hg.groupid ';
  100. $sqlParts['where'][] = 'r.groupid=ug.usrgrpid';
  101. $sqlParts['where'][] = 'ug.userid='.$userid;
  102. $sqlParts['where'][] = 'r.permission>='.$permission;
  103. $sqlParts['where'][] = 'NOT EXISTS('.
  104. ' SELECT hgg.groupid'.
  105. ' FROM hosts_groups hgg,rights rr,users_groups gg'.
  106. ' WHERE hgg.hostid=hg.hostid'.
  107. ' AND rr.id=hgg.groupid'.
  108. ' AND rr.groupid=gg.usrgrpid'.
  109. ' AND gg.userid='.$userid.
  110. ' AND rr.permission<'.$permission.')';
  111. }
  112. // nodeids
  113. $nodeids = !is_null($options['nodeids']) ? $options['nodeids'] : get_current_nodeid();
  114. // groupids
  115. if (!is_null($options['groupids'])) {
  116. zbx_value2array($options['groupids']);
  117. if ($options['output'] != API_OUTPUT_SHORTEN) {
  118. $sqlParts['select']['groupid'] = 'hg.groupid';
  119. }
  120. $sqlParts['from']['hosts_groups'] = 'hosts_groups hg';
  121. $sqlParts['where']['ahg'] = 'a.hostid=hg.hostid';
  122. $sqlParts['where'][] = DBcondition('hg.groupid', $options['groupids']);
  123. if (!is_null($options['groupCount'])) {
  124. $sqlParts['group']['hg'] = 'hg.groupid';
  125. }
  126. }
  127. // templateids
  128. if (!is_null($options['templateids'])) {
  129. zbx_value2array($options['templateids']);
  130. if (!is_null($options['hostids'])) {
  131. zbx_value2array($options['hostids']);
  132. $options['hostids'] = array_merge($options['hostids'], $options['templateids']);
  133. }
  134. else {
  135. $options['hostids'] = $options['templateids'];
  136. }
  137. }
  138. // hostids
  139. if (!is_null($options['hostids'])) {
  140. zbx_value2array($options['hostids']);
  141. if ($options['output'] != API_OUTPUT_EXTEND) {
  142. $sqlParts['select']['hostid'] = 'a.hostid';
  143. }
  144. $sqlParts['where']['hostid'] = DBcondition('a.hostid', $options['hostids']);
  145. if (!is_null($options['groupCount'])) {
  146. $sqlParts['group']['hostid'] = 'a.hostid';
  147. }
  148. }
  149. // expandData
  150. if (!is_null($options['expandData'])) {
  151. $sqlParts['select']['host'] = 'h.host';
  152. $sqlParts['from']['hosts'] = 'hosts h';
  153. $sqlParts['where']['ah'] = 'a.hostid=h.hostid';
  154. }
  155. // itemids
  156. if (!is_null($options['itemids'])) {
  157. zbx_value2array($options['itemids']);
  158. if ($options['output'] != API_OUTPUT_SHORTEN) {
  159. $sqlParts['select']['itemid'] = 'ia.itemid';
  160. }
  161. $sqlParts['from']['items_applications'] = 'items_applications ia';
  162. $sqlParts['where'][] = DBcondition('ia.itemid', $options['itemids']);
  163. $sqlParts['where']['aia'] = 'a.applicationid=ia.applicationid';
  164. }
  165. // applicationids
  166. if (!is_null($options['applicationids'])) {
  167. zbx_value2array($options['applicationids']);
  168. if ($options['output'] != API_OUTPUT_SHORTEN) {
  169. $sqlParts['select']['applicationid'] = 'a.applicationid';
  170. }
  171. $sqlParts['where'][] = DBcondition('a.applicationid', $options['applicationids']);
  172. }
  173. // templated
  174. if (!is_null($options['templated'])) {
  175. $sqlParts['from']['hosts'] = 'hosts h';
  176. $sqlParts['where']['ah'] = 'a.hostid=h.hostid';
  177. if ($options['templated']) {
  178. $sqlParts['where'][] = 'h.status='.HOST_STATUS_TEMPLATE;
  179. }
  180. else {
  181. $sqlParts['where'][] = 'h.status<>'.HOST_STATUS_TEMPLATE;
  182. }
  183. }
  184. // inherited
  185. if (!is_null($options['inherited'])) {
  186. if ($options['inherited']) {
  187. $sqlParts['where'][] = 'a.templateid IS NOT NULL';
  188. }
  189. else {
  190. $sqlParts['where'][] = 'a.templateid IS NULL';
  191. }
  192. }
  193. // output
  194. if ($options['output'] == API_OUTPUT_EXTEND) {
  195. $sqlParts['select']['apps'] = 'a.*';
  196. }
  197. // countOutput
  198. if (!is_null($options['countOutput'])) {
  199. $options['sortfield'] = '';
  200. $sqlParts['select'] = array('count(DISTINCT a.applicationid) as rowscount');
  201. // groupCount
  202. if (!is_null($options['groupCount'])) {
  203. foreach ($sqlParts['group'] as $key => $fields) {
  204. $sqlParts['select'][$key] = $fields;
  205. }
  206. }
  207. }
  208. // search
  209. if (is_array($options['search'])) {
  210. zbx_db_search('applications a', $options, $sqlParts);
  211. }
  212. // filter
  213. if (is_array($options['filter'])) {
  214. zbx_db_filter('applications a', $options, $sqlParts);
  215. }
  216. // sorting
  217. zbx_db_sorting($sqlParts, $options, $sortColumns, 'a');
  218. // limit
  219. if (zbx_ctype_digit($options['limit']) && $options['limit']) {
  220. $sqlParts['limit'] = $options['limit'];
  221. }
  222. $applicationids = array();
  223. $sqlParts['select'] = array_unique($sqlParts['select']);
  224. $sqlParts['from'] = array_unique($sqlParts['from']);
  225. $sqlParts['where'] = array_unique($sqlParts['where']);
  226. $sqlParts['group'] = array_unique($sqlParts['group']);
  227. $sqlParts['order'] = array_unique($sqlParts['order']);
  228. $sqlSelect = '';
  229. $sqlFrom = '';
  230. $sqlWhere = '';
  231. $sqlGroup = '';
  232. $sqlOrder = '';
  233. if (!empty($sqlParts['select'])) {
  234. $sqlSelect .= implode(',', $sqlParts['select']);
  235. }
  236. if (!empty($sqlParts['from'])) {
  237. $sqlFrom .= implode(',', $sqlParts['from']);
  238. }
  239. if (!empty($sqlParts['where'])) {
  240. $sqlWhere .= ' AND '.implode(' AND ', $sqlParts['where']);
  241. }
  242. if (!empty($sqlParts['group'])) {
  243. $sqlWhere .= ' GROUP BY '.implode(',', $sqlParts['group']);
  244. }
  245. if (!empty($sqlParts['order'])) {
  246. $sqlOrder .= ' ORDER BY '.implode(',', $sqlParts['order']);
  247. }
  248. $sqlLimit = $sqlParts['limit'];
  249. $sql = 'SELECT '.zbx_db_distinct($sqlParts).' '.$sqlSelect.
  250. ' FROM '.$sqlFrom.
  251. ' WHERE '.DBin_node('a.applicationid', $nodeids).
  252. $sqlWhere.
  253. $sqlGroup.
  254. $sqlOrder;
  255. $res = DBselect($sql, $sqlLimit);
  256. while ($application = DBfetch($res)) {
  257. if (!is_null($options['countOutput'])) {
  258. if (!is_null($options['groupCount'])) {
  259. $result[] = $application;
  260. }
  261. else {
  262. $result = $application['rowscount'];
  263. }
  264. }
  265. else {
  266. $applicationids[$application['applicationid']] = $application['applicationid'];
  267. if ($options['output'] == API_OUTPUT_SHORTEN) {
  268. $result[$application['applicationid']] = array('applicationid' => $application['applicationid']);
  269. }
  270. else {
  271. if (!isset($result[$application['applicationid']])) {
  272. $result[$application['applicationid']]= array();
  273. }
  274. if (!is_null($options['selectHosts']) && !isset($result[$application['applicationid']]['hosts'])) {
  275. $result[$application['applicationid']]['hosts'] = array();
  276. }
  277. if (!is_null($options['selectItems']) && !isset($result[$application['applicationid']]['items'])) {
  278. $result[$application['applicationid']]['items'] = array();
  279. }
  280. // hostids
  281. if (isset($application['hostid']) && is_null($options['selectHosts'])) {
  282. if (!isset($result[$application['applicationid']]['hosts'])) {
  283. $result[$application['applicationid']]['hosts'] = array();
  284. }
  285. $result[$application['applicationid']]['hosts'][] = array('hostid' => $application['hostid']);
  286. }
  287. // itemids
  288. if (isset($application['itemid']) && is_null($options['selectItems'])) {
  289. if (!isset($result[$application['applicationid']]['items'])) {
  290. $result[$application['applicationid']]['items'] = array();
  291. }
  292. $result[$application['applicationid']]['items'][] = array('itemid' => $application['itemid']);
  293. unset($application['itemid']);
  294. }
  295. $result[$application['applicationid']] += $application;
  296. }
  297. }
  298. }
  299. if (!is_null($options['countOutput'])) {
  300. return $result;
  301. }
  302. // adding objects
  303. // adding hosts
  304. if ($options['selectHosts'] !== null && (is_array($options['selectHosts']) || str_in_array($options['selectHosts'], $subselectsAllowedOutputs))) {
  305. $objParams = array(
  306. 'output' => $options['selectHosts'],
  307. 'applicationids' => $applicationids,
  308. 'nopermissions' => 1,
  309. 'templated_hosts' => true,
  310. 'preservekeys' => 1
  311. );
  312. $hosts = API::Host()->get($objParams);
  313. foreach ($hosts as $hostid => $host) {
  314. $iapplications = $host['applications'];
  315. unset($host['applications']);
  316. foreach ($iapplications as $application) {
  317. $result[$application['applicationid']]['hosts'][] = $host;
  318. }
  319. }
  320. }
  321. // adding objects
  322. // adding items
  323. if (!is_null($options['selectItems']) && str_in_array($options['selectItems'], $subselectsAllowedOutputs)) {
  324. $objParams = array(
  325. 'output' => $options['selectItems'],
  326. 'applicationids' => $applicationids,
  327. 'filter' => array('flags' => array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)),
  328. 'nopermissions' => 1,
  329. 'preservekeys' => 1
  330. );
  331. $items = API::Item()->get($objParams);
  332. foreach ($items as $itemid => $item) {
  333. $iapplications = $item['applications'];
  334. unset($item['applications']);
  335. foreach ($iapplications as $application) {
  336. $result[$application['applicationid']]['items'][] = $item;
  337. }
  338. }
  339. }
  340. // removing keys (hash -> array)
  341. if (is_null($options['preservekeys'])) {
  342. $result = zbx_cleanHashes($result);
  343. }
  344. return $result;
  345. }
  346. public function exists($object) {
  347. $keyFields = array(array('hostid', 'host'), 'name');
  348. $options = array(
  349. 'filter' => zbx_array_mintersect($keyFields, $object),
  350. 'output' => API_OUTPUT_SHORTEN,
  351. 'nopermissions' => 1,
  352. 'limit' => 1
  353. );
  354. if (isset($object['node'])) {
  355. $options['nodeids'] = getNodeIdByNodeName($object['node']);
  356. }
  357. elseif (isset($object['nodeids'])) {
  358. $options['nodeids'] = $object['nodeids'];
  359. }
  360. $objs = $this->get($options);
  361. return !empty($objs);
  362. }
  363. public function checkInput(&$applications, $method) {
  364. $create = ($method == 'create');
  365. $update = ($method == 'update');
  366. $delete = ($method == 'delete');
  367. // permissions
  368. if ($update || $delete) {
  369. $itemDbFields = array('applicationid' => null);
  370. $dbApplications = $this->get(array(
  371. 'output' => API_OUTPUT_EXTEND,
  372. 'applicationids' => zbx_objectValues($applications, 'applicationid'),
  373. 'editable' => 1,
  374. 'preservekeys' => 1
  375. ));
  376. }
  377. else {
  378. $itemDbFields = array('name' => null, 'hostid' => null);
  379. $dbHosts = API::Host()->get(array(
  380. 'output' => array('hostid', 'host', 'status'),
  381. 'hostids' => zbx_objectValues($applications, 'hostid'),
  382. 'templated_hosts' => 1,
  383. 'editable' => 1,
  384. 'preservekeys' => 1
  385. ));
  386. }
  387. foreach ($applications as &$application) {
  388. if (!check_db_fields($itemDbFields, $application)) {
  389. self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function'));
  390. }
  391. unset($application['templateid']);
  392. // check permissions by hostid
  393. if ($create) {
  394. if (!isset($dbHosts[$application['hostid']])) {
  395. self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!'));
  396. }
  397. }
  398. // check permissions by applicationid
  399. if ($delete || $update) {
  400. if (!isset($dbApplications[$application['applicationid']])) {
  401. self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!'));
  402. }
  403. }
  404. // check on operating with templated applications
  405. if ($delete || $update) {
  406. if ($dbApplications[$application['applicationid']]['templateid'] != 0) {
  407. self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot interact templated applications');
  408. }
  409. }
  410. if ($update) {
  411. if (!isset($application['hostid'])) {
  412. $application['hostid'] = $dbApplications[$application['applicationid']]['hostid'];
  413. }
  414. }
  415. // check existance
  416. if ($update || $create) {
  417. $applicationsExists = $this->get(array(
  418. 'output' => API_OUTPUT_EXTEND,
  419. 'filter' => array(
  420. 'hostid' => $application['hostid'],
  421. 'name' => $application['name']
  422. ),
  423. 'nopermissions' => 1
  424. ));
  425. foreach ($applicationsExists as $applicationExists) {
  426. if (!$update || (bccomp($applicationExists['applicationid'], $application['applicationid']) != 0)) {
  427. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Application "%1$s" already exists.', $application['name']));
  428. }
  429. }
  430. }
  431. }
  432. unset($application);
  433. }
  434. /**
  435. * Add Applications
  436. *
  437. * @param array $applications
  438. * @param array $app_data['name']
  439. * @param array $app_data['hostid']
  440. * @return array
  441. */
  442. public function create($applications) {
  443. $applications = zbx_toArray($applications);
  444. $this->checkInput($applications, __FUNCTION__);
  445. $this->createReal($applications);
  446. $this->inherit($applications);
  447. return array('applicationids' => zbx_objectValues($applications, 'applicationid'));
  448. }
  449. /**
  450. * Update Applications
  451. *
  452. * @param array $applications
  453. * @param array $app_data['name']
  454. * @param array $app_data['hostid']
  455. * @return array
  456. */
  457. public function update($applications) {
  458. $applications = zbx_toArray($applications);
  459. $this->checkInput($applications, __FUNCTION__);
  460. $this->updateReal($applications);
  461. $this->inherit($applications);
  462. return array('applicationids' => zbx_objectValues($applications, 'applicationids'));
  463. }
  464. protected function createReal(&$applications) {
  465. if (empty($applications)) {
  466. return true;
  467. }
  468. $applicationids = DB::insert('applications', $applications);
  469. foreach ($applications as $anum => $application) {
  470. $applications[$anum]['applicationid'] = $applicationids[$anum];
  471. }
  472. // TODO: REMOVE info
  473. $applicationsCreated = $this->get(array(
  474. 'applicationids' => $applicationids,
  475. 'output' => API_OUTPUT_EXTEND,
  476. 'selectHosts' => API_OUTPUT_EXTEND,
  477. 'nopermissions' => 1
  478. ));
  479. foreach ($applicationsCreated as $applicationCreated) {
  480. $host = reset($applicationCreated['hosts']);
  481. info(_s('Created: Application "%1$s" on "%2$s".', $applicationCreated['name'], $host['name']));
  482. }
  483. }
  484. protected function updateReal($applications) {
  485. $update = array();
  486. foreach ($applications as $application) {
  487. $update[] = array(
  488. 'values' => $application,
  489. 'where' => array('applicationid' => $application['applicationid'])
  490. );
  491. }
  492. DB::update('applications', $update);
  493. // TODO: REMOVE info
  494. $applicationsUpd = $this->get(array(
  495. 'applicationids' => zbx_objectValues($applications, 'applicationid'),
  496. 'output' => API_OUTPUT_EXTEND,
  497. 'selectHosts' => API_OUTPUT_EXTEND,
  498. 'nopermissions' => 1,
  499. ));
  500. foreach ($applicationsUpd as $applicationUpd) {
  501. $host = reset($applicationUpd['hosts']);
  502. info(_s('Updated: Application "%1$s" on "%2$s".', $applicationUpd['name'], $host['name']));
  503. }
  504. }
  505. /**
  506. * Delete Applications
  507. *
  508. * @param array $applicationids
  509. * @return array
  510. */
  511. public function delete($applicationids, $nopermissions = false) {
  512. $applicationids = zbx_toArray($applicationids);
  513. // TODO: remove $nopermissions hack
  514. $options = array(
  515. 'applicationids' => $applicationids,
  516. 'editable' => true,
  517. 'output' => API_OUTPUT_EXTEND,
  518. 'preservekeys' => true,
  519. 'selectHosts' => array('name', 'hostid')
  520. );
  521. $delApplications = $this->get($options);
  522. if (!$nopermissions) {
  523. foreach ($applicationids as $applicationid) {
  524. if (!isset($delApplications[$applicationid])) {
  525. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  526. }
  527. if ($delApplications[$applicationid]['templateid'] != 0) {
  528. self::exception(ZBX_API_ERROR_PERMISSIONS, 'Cannot delete templated application.');
  529. }
  530. }
  531. }
  532. $parentApplicationids = $applicationids;
  533. $childApplicationids = array();
  534. do {
  535. $dbApplications = DBselect('SELECT a.applicationid FROM applications a WHERE '.DBcondition('a.templateid', $parentApplicationids));
  536. $parentApplicationids = array();
  537. while ($dbApplication = DBfetch($dbApplications)) {
  538. $parentApplicationids[] = $dbApplication['applicationid'];
  539. $childApplicationids[$dbApplication['applicationid']] = $dbApplication['applicationid'];
  540. }
  541. } while (!empty($parentApplicationids));
  542. $options = array(
  543. 'applicationids' => $childApplicationids,
  544. 'output' => API_OUTPUT_EXTEND,
  545. 'nopermissions' => true,
  546. 'preservekeys' => true,
  547. 'selectHosts' => array('name', 'hostid')
  548. );
  549. $delApplicationChilds = $this->get($options);
  550. $delApplications = zbx_array_merge($delApplications, $delApplicationChilds);
  551. $applicationids = array_merge($applicationids, $childApplicationids);
  552. // check if app is used by web scenario
  553. $sql = 'SELECT ht.name,ht.applicationid'.
  554. ' FROM httptest ht'.
  555. ' WHERE '.DBcondition('ht.applicationid', $applicationids);
  556. $res = DBselect($sql);
  557. if ($info = DBfetch($res)) {
  558. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Application "%1$s" used by scenario "%2$s" and can\'t be deleted.', $delApplications[$info['applicationid']]['name'], $info['name']));
  559. }
  560. DB::delete('applications', array('applicationid' => $applicationids));
  561. // TODO: remove info from API
  562. foreach ($delApplications as $delApplication) {
  563. $host = reset($delApplication['hosts']);
  564. info(_s('Deleted: Application "%1$s" on "%2$s".', $delApplication['name'], $host['name']));
  565. }
  566. return array('applicationids' => $applicationids);
  567. }
  568. /**
  569. * Add Items to applications
  570. *
  571. * @param array $data
  572. * @param array $data['applications']
  573. * @param array $data['items']
  574. * @return boolean
  575. */
  576. public function massAdd($data) {
  577. if (empty($data['applications'])) {
  578. self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.'));
  579. }
  580. $applications = zbx_toArray($data['applications']);
  581. $items = zbx_toArray($data['items']);
  582. $applicationids = zbx_objectValues($applications, 'applicationid');
  583. $itemids = zbx_objectValues($items, 'itemid');
  584. // validate permissions
  585. $appOptions = array(
  586. 'applicationids' => $applicationids,
  587. 'editable' => 1,
  588. 'output' => API_OUTPUT_EXTEND,
  589. 'preservekeys' => 1
  590. );
  591. $allowedApplications = $this->get($appOptions);
  592. foreach ($applications as $application) {
  593. if (!isset($allowedApplications[$application['applicationid']])) {
  594. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  595. }
  596. }
  597. $itemOptions = array(
  598. 'itemids' => $itemids,
  599. 'editable' => 1,
  600. 'output' => API_OUTPUT_EXTEND,
  601. 'preservekeys' => 1
  602. );
  603. $allowedItems = API::Item()->get($itemOptions);
  604. foreach ($items as $num => $item) {
  605. if (!isset($allowedItems[$item['itemid']])) {
  606. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  607. }
  608. }
  609. $linkedDb = DBselect(
  610. 'SELECT ia.itemid, ia.applicationid'.
  611. ' FROM items_applications ia'.
  612. ' WHERE '.DBcondition('ia.itemid', $itemids).
  613. ' AND '.DBcondition('ia.applicationid', $applicationids)
  614. );
  615. while ($pair = DBfetch($linkedDb)) {
  616. $linked[$pair['applicationid']] = array($pair['itemid'] => $pair['itemid']);
  617. }
  618. $appsInsert = array();
  619. foreach ($applicationids as $applicationid) {
  620. foreach ($itemids as $inum => $itemid) {
  621. if (isset($linked[$applicationid]) && isset($linked[$applicationid][$itemid])) {
  622. continue;
  623. }
  624. $appsInsert[] = array(
  625. 'itemid' => $itemid,
  626. 'applicationid' => $applicationid
  627. );
  628. }
  629. }
  630. DB::insert('items_applications', $appsInsert);
  631. foreach ($itemids as $inum => $itemid) {
  632. $dbChilds = DBselect('SELECT i.itemid,i.hostid FROM items i WHERE i.templateid='.$itemid);
  633. while ($child = DBfetch($dbChilds)) {
  634. $dbApps = DBselect(
  635. 'SELECT a1.applicationid'.
  636. ' FROM applications a1,applications a2'.
  637. ' WHERE a1.name=a2.name'.
  638. ' AND a1.hostid='.$child['hostid'].
  639. ' AND '.DBcondition('a2.applicationid', $applicationids)
  640. );
  641. $childApplications = array();
  642. while ($app = DBfetch($dbApps)) {
  643. $childApplications[] = $app;
  644. }
  645. $result = $this->massAdd(array('items' => $child, 'applications' => $childApplications));
  646. if (!$result) {
  647. self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot add items.');
  648. }
  649. }
  650. }
  651. return array('applicationids'=> $applicationids);
  652. }
  653. protected function inherit($applications, $hostids = null) {
  654. if (empty($applications)) {
  655. return $applications;
  656. }
  657. $applications = zbx_toHash($applications, 'applicationid');
  658. $chdHosts = API::Host()->get(array(
  659. 'output' => array('hostid', 'host'),
  660. 'templateids' => zbx_objectValues($applications, 'hostid'),
  661. 'hostids' => $hostids,
  662. 'preservekeys' => 1,
  663. 'nopermissions' => 1,
  664. 'templated_hosts' => 1
  665. ));
  666. if (empty($chdHosts)) {
  667. return true;
  668. }
  669. $insertApplications = array();
  670. $updateApplications = array();
  671. foreach ($chdHosts as $hostid => $host) {
  672. $templateids = zbx_toHash($host['templates'], 'templateid');
  673. // skip applications not from parent templates of current host
  674. $parentApplications = array();
  675. foreach ($applications as $applicationid => $application) {
  676. if (isset($templateids[$application['hostid']])) {
  677. $parentApplications[$applicationid] = $application;
  678. }
  679. }
  680. // check existing items to decide insert or update
  681. $exApplications = $this->get(array(
  682. 'output' => API_OUTPUT_EXTEND,
  683. 'hostids' => $hostid,
  684. 'preservekeys' => true,
  685. 'nopermissions' => true
  686. ));
  687. $exApplicationsNames = zbx_toHash($exApplications, 'name');
  688. $exApplicationsTpl = zbx_toHash($exApplications, 'templateid');
  689. foreach ($parentApplications as $applicationid => $application) {
  690. $exApplication = null;
  691. // update by tempalteid
  692. if (isset($exApplicationsTpl[$applicationid])) {
  693. $exApplication = $exApplicationsTpl[$applicationid];
  694. }
  695. // update by name
  696. if (isset($application['name']) && isset($exApplicationsNames[$application['name']])) {
  697. $exApplication = $exApplicationsNames[$application['name']];
  698. if ($exApplication['templateid'] > 0 && bccomp($exApplication['templateid'], $application['applicationid'] != 0)) {
  699. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Application "%1$s" already exists for host "%2$s".', $exApplication['name'], $host['name']));
  700. }
  701. }
  702. $newApplication = $application;
  703. $newApplication['hostid'] = $host['hostid'];
  704. $newApplication['templateid'] = $application['applicationid'];
  705. if ($exApplication) {
  706. $newApplication['applicationid'] = $exApplication['applicationid'];
  707. $updateApplications[] = $newApplication;
  708. }
  709. else {
  710. $insertApplications[] = $newApplication;
  711. }
  712. }
  713. }
  714. $this->createReal($insertApplications);
  715. $this->updateReal($updateApplications);
  716. $inheritedApplications = array_merge($insertApplications, $updateApplications);
  717. $this->inherit($inheritedApplications);
  718. return true;
  719. }
  720. public function syncTemplates($data) {
  721. $data['templateids'] = zbx_toArray($data['templateids']);
  722. $data['hostids'] = zbx_toArray($data['hostids']);
  723. $options = array(
  724. 'hostids' => $data['hostids'],
  725. 'editable' => 1,
  726. 'preservekeys' => 1,
  727. 'templated_hosts' => 1,
  728. 'output' => API_OUTPUT_SHORTEN
  729. );
  730. $allowedHosts = API::Host()->get($options);
  731. foreach ($data['hostids'] as $hostid) {
  732. if (!isset($allowedHosts[$hostid])) {
  733. self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.'));
  734. }
  735. }
  736. $options = array(
  737. 'templateids' => $data['templateids'],
  738. 'preservekeys' => 1,
  739. 'output' => API_OUTPUT_SHORTEN
  740. );
  741. $allowedTemplates = API::Template()->get($options);
  742. foreach ($data['templateids'] as $templateid) {
  743. if (!isset($allowedTemplates[$templateid])) {
  744. self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.'));
  745. }
  746. }
  747. $options = array(
  748. 'hostids' => $data['templateids'],
  749. 'preservekeys' => 1,
  750. 'output' => API_OUTPUT_EXTEND
  751. );
  752. $applications = $this->get($options);
  753. $this->inherit($applications, $data['hostids']);
  754. return true;
  755. }
  756. }
  757. ?>