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

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

#
PHP | 570 lines | 390 code | 83 blank | 97 comment | 64 complexity | e141ae3ed05215e53057bdf92408de55 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. * File containing Cimage class for API.
  24. * @package API
  25. */
  26. /**
  27. * Class containing methods for operations with images
  28. *
  29. */
  30. class CImage extends CZBXAPI {
  31. protected $tableName = 'images';
  32. protected $tableAlias = 'i';
  33. /**
  34. * Get images data
  35. *
  36. * @param array $options
  37. * @param array $options['itemids']
  38. * @param array $options['hostids']
  39. * @param array $options['groupids']
  40. * @param array $options['triggerids']
  41. * @param array $options['imageids']
  42. * @param boolean $options['status']
  43. * @param boolean $options['editable']
  44. * @param boolean $options['count']
  45. * @param string $options['pattern']
  46. * @param int $options['limit']
  47. * @param string $options['order']
  48. * @return array|boolean image data as array or false if error
  49. */
  50. public function get($options = array()) {
  51. $result = array();
  52. // allowed columns for sorting
  53. $sortColumns = array('imageid', 'name');
  54. $sqlParts = array(
  55. 'select' => array('images' => 'i.imageid'),
  56. 'from' => array('images' => 'images i'),
  57. 'where' => array(),
  58. 'order' => array(),
  59. 'limit' => null
  60. );
  61. $defOptions = array(
  62. 'nodeids' => null,
  63. 'imageids' => null,
  64. 'sysmapids' => null,
  65. // filter
  66. 'filter' => null,
  67. 'search' => null,
  68. 'searchByAny' => null,
  69. 'startSearch' => null,
  70. 'excludeSearch' => null,
  71. 'searchWildcardsEnabled' => null,
  72. // output
  73. 'output' => API_OUTPUT_REFER,
  74. 'select_image' => null,
  75. 'editable' => null,
  76. 'countOutput' => null,
  77. 'preservekeys' => null,
  78. 'sortfield' => '',
  79. 'sortorder' => '',
  80. 'limit' => null
  81. );
  82. $options = zbx_array_merge($defOptions, $options);
  83. // editable + PERMISSION CHECK
  84. if (!is_null($options['editable']) && (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN)) {
  85. return $result;
  86. }
  87. // nodeids
  88. $nodeids = !is_null($options['nodeids']) ? $options['nodeids'] : get_current_nodeid();
  89. // imageids
  90. if (!is_null($options['imageids'])) {
  91. zbx_value2array($options['imageids']);
  92. $sqlParts['where']['imageid'] = DBcondition('i.imageid', $options['imageids']);
  93. }
  94. // sysmapids
  95. if (!is_null($options['sysmapids'])) {
  96. zbx_value2array($options['sysmapids']);
  97. $sqlParts['select']['sm'] = 'sm.sysmapid';
  98. $sqlParts['from']['sysmaps'] = 'sysmaps sm';
  99. $sqlParts['from']['sysmaps_elements'] = 'sysmaps_elements se';
  100. $sqlParts['where']['sm'] = DBcondition('sm.sysmapid', $options['sysmapids']);
  101. $sqlParts['where']['smse'] = 'sm.sysmapid=se.sysmapid ';
  102. $sqlParts['where']['se'] = '('.
  103. 'se.iconid_off=i.imageid'.
  104. ' OR se.iconid_on=i.imageid'.
  105. ' OR se.iconid_disabled=i.imageid'.
  106. ' OR se.iconid_maintenance=i.imageid'.
  107. ' OR sm.backgroundid=i.imageid)';
  108. }
  109. // output
  110. if ($options['output'] == API_OUTPUT_EXTEND) {
  111. $sqlParts['select']['images'] = 'i.imageid, i.imagetype, i.name';
  112. }
  113. // count
  114. if (!is_null($options['countOutput'])) {
  115. $options['sortfield'] = '';
  116. $sqlParts['select'] = array('count(DISTINCT i.imageid) as rowscount');
  117. }
  118. // filter
  119. if (is_array($options['filter'])) {
  120. zbx_db_filter('images i', $options, $sqlParts);
  121. }
  122. // search
  123. if (is_array($options['search'])) {
  124. zbx_db_search('images i', $options, $sqlParts);
  125. }
  126. // sorting
  127. zbx_db_sorting($sqlParts, $options, $sortColumns, 'i');
  128. // limit
  129. if (zbx_ctype_digit($options['limit']) && $options['limit']) {
  130. $sqlParts['limit'] = $options['limit'];
  131. }
  132. $imageids = array();
  133. $sqlParts['select'] = array_unique($sqlParts['select']);
  134. $sqlParts['from'] = array_unique($sqlParts['from']);
  135. $sqlParts['where'] = array_unique($sqlParts['where']);
  136. $sqlParts['order'] = array_unique($sqlParts['order']);
  137. $sqlSelect = '';
  138. $sqlFrom = '';
  139. $sqlWhere = '';
  140. $sqlOrder = '';
  141. if (!empty($sqlParts['select'])) {
  142. $sqlSelect .= implode(',', $sqlParts['select']);
  143. }
  144. if (!empty($sqlParts['from'])) {
  145. $sqlFrom .= implode(',', $sqlParts['from']);
  146. }
  147. if (!empty($sqlParts['where'])) {
  148. $sqlWhere .= ' AND '.implode(' AND ', $sqlParts['where']);
  149. }
  150. if (!empty($sqlParts['order'])) {
  151. $sqlOrder .= ' ORDER BY '.implode(',', $sqlParts['order']);
  152. }
  153. $sql = 'SELECT '.zbx_db_distinct($sqlParts).' '.$sqlSelect.
  154. ' FROM '.$sqlFrom.
  155. ' WHERE '.DBin_node('i.imageid', $nodeids).
  156. $sqlWhere.
  157. $sqlOrder;
  158. $res = DBselect($sql, $sqlParts['limit']);
  159. while ($image = DBfetch($res)) {
  160. if ($options['countOutput']) {
  161. return $image['rowscount'];
  162. }
  163. else {
  164. $imageids[$image['imageid']] = $image['imageid'];
  165. if ($options['output'] == API_OUTPUT_SHORTEN) {
  166. $result[$image['imageid']] = array('imageid' => $image['imageid']);
  167. }
  168. else {
  169. if (!isset($result[$image['imageid']])) {
  170. $result[$image['imageid']] = array();
  171. }
  172. // sysmapds
  173. if (isset($image['sysmapid'])) {
  174. if (!isset($result[$image['imageid']]['sysmaps'])) {
  175. $result[$image['imageid']]['sysmaps'] = array();
  176. }
  177. $result[$image['imageid']]['sysmaps'][] = array('sysmapid' => $image['sysmapid']);
  178. }
  179. $result[$image['imageid']] += $image;
  180. }
  181. }
  182. }
  183. // adding objects
  184. if (!is_null($options['select_image'])) {
  185. $dbImg = DBselect('SELECT i.imageid,i.image FROM images i WHERE '.DBCondition('i.imageid', $imageids));
  186. while ($img = DBfetch($dbImg)) {
  187. // PostgreSQL and SQLite images are stored escaped in the DB
  188. $img['image'] = zbx_unescape_image($img['image']);
  189. $result[$img['imageid']]['image'] = base64_encode($img['image']);
  190. }
  191. }
  192. if (is_null($options['preservekeys'])) {
  193. $result = zbx_cleanHashes($result);
  194. }
  195. return $result;
  196. }
  197. /**
  198. * Get images
  199. *
  200. * @param array $image
  201. * @param array $image['name']
  202. * @param array $image['hostid']
  203. * @return array|boolean
  204. */
  205. public function getObjects($imageData) {
  206. $options = array(
  207. 'filter' => $imageData,
  208. 'output' => API_OUTPUT_EXTEND
  209. );
  210. if (isset($imageData['node']))
  211. $options['nodeids'] = getNodeIdByNodeName($imageData['node']);
  212. elseif (isset($imageData['nodeids']))
  213. $options['nodeids'] = $imageData['nodeids'];
  214. else
  215. $options['nodeids'] = get_current_nodeid(true);
  216. $result = $this->get($options);
  217. return $result;
  218. }
  219. /**
  220. * Check image existance
  221. *
  222. * @param array $images
  223. * @param array $images['name']
  224. * @return boolean
  225. */
  226. public function exists($object) {
  227. $keyFields = array(array('imageid', 'name'), 'imagetype');
  228. $options = array(
  229. 'filter' => zbx_array_mintersect($keyFields, $object),
  230. 'output' => API_OUTPUT_SHORTEN,
  231. 'nopermissions' => 1,
  232. 'limit' => 1
  233. );
  234. if (isset($object['node']))
  235. $options['nodeids'] = getNodeIdByNodeName($object['node']);
  236. elseif (isset($object['nodeids']))
  237. $options['nodeids'] = $object['nodeids'];
  238. $objs = $this->get($options);
  239. return !empty($objs);
  240. }
  241. /**
  242. * Add images
  243. *
  244. * @param array $images ['name' => string, 'image' => string, 'imagetype' => int]
  245. * @return array
  246. */
  247. public function create($images) {
  248. global $DB;
  249. $images = zbx_toArray($images);
  250. $imageids = array();
  251. if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
  252. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  253. }
  254. foreach ($images as $snum => $image) {
  255. $imageDbFields = array(
  256. 'name' => null,
  257. 'image' => null,
  258. 'imagetype' => 1
  259. );
  260. if (!check_db_fields($imageDbFields, $image)) {
  261. self::exception(ZBX_API_ERROR_PARAMETERS, 'Wrong fields for image [ '.$image['name'].' ]');
  262. }
  263. if ($this->exists(array('name' => $image['name']))) {
  264. self::exception(ZBX_API_ERROR_PARAMETERS, _('Image').' [ '.$image['name'].' ] '._('already exists'));
  265. }
  266. // Decode BASE64
  267. $image['image'] = base64_decode($image['image']);
  268. if (strlen($image['image']) > ZBX_MAX_IMAGE_SIZE) {
  269. self::exception(ZBX_API_ERROR_PARAMETERS, _('Image size must be less than 1MB'));
  270. }
  271. $imageid = get_dbid('images', 'imageid');
  272. $values = array(
  273. 'imageid' => $imageid,
  274. 'name' => zbx_dbstr($image['name']),
  275. 'imagetype' => $image['imagetype'],
  276. );
  277. switch ($DB['TYPE']) {
  278. case ZBX_DB_ORACLE:
  279. $values['image'] = 'EMPTY_BLOB()';
  280. $lob = oci_new_descriptor($DB['DB'], OCI_D_LOB);
  281. $sql = 'INSERT INTO images ('.implode(' ,', array_keys($values)).') VALUES ('.implode(',', $values).')'.
  282. ' returning image into :imgdata';
  283. $stmt = oci_parse($DB['DB'], $sql);
  284. if (!$stmt) {
  285. $e = oci_error($DB['DB']);
  286. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Parse SQL error [%1$s] in [%2$s].', $e['message'], $e['sqltext']));
  287. }
  288. oci_bind_by_name($stmt, ':imgdata', $lob, -1, OCI_B_BLOB);
  289. if (!oci_execute($stmt)) {
  290. $e = oci_error($stid);
  291. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Execute SQL error [%1$s] in [%2$s].', $e['message'], $e['sqltext']));
  292. }
  293. oci_free_statement($stmt);
  294. break;
  295. case ZBX_DB_DB2:
  296. $stmt = db2_prepare($DB['DB'], 'INSERT INTO images ('.implode(' ,', array_keys($values)).',image)'.
  297. ' VALUES ('.implode(',', $values).', ?)');
  298. if (!$stmt) {
  299. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  300. }
  301. $variable = $image['image'];
  302. if (!db2_bind_param($stmt, 1, "variable", DB2_PARAM_IN, DB2_BINARY)) {
  303. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  304. }
  305. if (!db2_execute($stmt)) {
  306. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  307. }
  308. break;
  309. case ZBX_DB_SQLITE3:
  310. $values['image'] = zbx_dbstr(bin2hex($image['image']));
  311. $sql = 'INSERT INTO images ('.implode(', ', array_keys($values)).') VALUES ('.implode(', ', $values).')';
  312. if (!DBexecute($sql)) {
  313. self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror');
  314. }
  315. break;
  316. case ZBX_DB_MYSQL:
  317. $values['image'] = zbx_dbstr($image['image']);
  318. $sql = 'INSERT INTO images ('.implode(', ', array_keys($values)).') VALUES ('.implode(', ', $values).')';
  319. if (!DBexecute($sql)) {
  320. self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror');
  321. }
  322. break;
  323. case ZBX_DB_POSTGRESQL:
  324. $values['image'] = "'".pg_escape_bytea($image['image'])."'";
  325. $sql = 'INSERT INTO images ('.implode(', ', array_keys($values)).') VALUES ('.implode(', ', $values).')';
  326. if (!DBexecute($sql)) {
  327. self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror');
  328. }
  329. break;
  330. }
  331. $imageids[] = $imageid;
  332. }
  333. return array('imageids' => $imageids);
  334. }
  335. /**
  336. * Update images
  337. *
  338. * @param array $images
  339. * @return array (updated images)
  340. */
  341. public function update($images) {
  342. global $DB;
  343. $images = zbx_toArray($images);
  344. if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
  345. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  346. }
  347. foreach ($images as $num => $image) {
  348. if (!isset($image['imageid']))
  349. self::exception(ZBX_API_ERROR_PARAMETERS, 'Wrong fields for image.');
  350. $options = array(
  351. 'filter' => array('name' => $image['name']),
  352. 'output' => API_OUTPUT_SHORTEN,
  353. 'nopermissions' => 1
  354. );
  355. $imageExists = $this->get($options);
  356. $imageExists = reset($imageExists);
  357. if ($imageExists && (bccomp($imageExists['imageid'], $image['imageid']) != 0)) {
  358. self::exception(ZBX_API_ERROR_PARAMETERS, _('Image').' [ '.$image['name'].' ] '._('already exists'));
  359. }
  360. $values = array();
  361. if (isset($image['name'])) $values['name'] = zbx_dbstr($image['name']);
  362. if (isset($image['imagetype'])) $values['imagetype'] = $image['imagetype'];
  363. if (isset($image['image'])) {
  364. // decode BASE64
  365. $image['image'] = base64_decode($image['image']);
  366. switch ($DB['TYPE']) {
  367. case ZBX_DB_POSTGRESQL:
  368. $values['image'] = "'".pg_escape_bytea($image['image'])."'";
  369. break;
  370. case ZBX_DB_SQLITE3:
  371. $values['image'] = zbx_dbstr(bin2hex($image['image']));
  372. break;
  373. case ZBX_DB_MYSQL:
  374. $values['image'] = zbx_dbstr($image['image']);
  375. break;
  376. case ZBX_DB_ORACLE:
  377. $sql = 'SELECT image FROM images WHERE imageid = '.$image['imageid'].' FOR UPDATE';
  378. if (!$stmt = oci_parse($DB['DB'], $sql)) {
  379. $e = oci_error($DB['DB']);
  380. self::exception(ZBX_API_ERROR_PARAMETERS, 'SQL error ['.$e['message'].'] in ['.$e['sqltext'].']');
  381. }
  382. if (!oci_execute($stmt, OCI_DEFAULT)) {
  383. $e = oci_error($stmt);
  384. self::exception(ZBX_API_ERROR_PARAMETERS, 'SQL error ['.$e['message'].'] in ['.$e['sqltext'].']');
  385. }
  386. if (FALSE === ($row = oci_fetch_assoc($stmt))) {
  387. self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror');
  388. }
  389. $row['IMAGE']->truncate();
  390. $row['IMAGE']->save($image['image']);
  391. $row['IMAGE']->free();
  392. break;
  393. case ZBX_DB_DB2:
  394. $stmt = db2_prepare($DB['DB'], 'UPDATE images SET image=? WHERE imageid='.$image['imageid']);
  395. if (!$stmt) {
  396. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  397. }
  398. // not unused, db2_bind_param requires variable name as string
  399. $variable = $image['image'];
  400. if (!db2_bind_param($stmt, 1, "variable", DB2_PARAM_IN, DB2_BINARY)) {
  401. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  402. }
  403. if (!db2_execute($stmt)) {
  404. self::exception(ZBX_API_ERROR_PARAMETERS, db2_conn_errormsg($DB['DB']));
  405. }
  406. break;
  407. }
  408. }
  409. $sqlUpd = array();
  410. foreach ($values as $field => $value) {
  411. $sqlUpd[] = $field.'='.$value;
  412. }
  413. $sql = 'UPDATE images SET '.implode(', ', $sqlUpd).' WHERE imageid='.$image['imageid'];
  414. $result = DBexecute($sql);
  415. if (!$result) {
  416. self::exception(ZBX_API_ERROR_PARAMETERS, _('Could not save image!'));
  417. }
  418. }
  419. return array('imageids' => zbx_objectValues($images, 'imageid'));
  420. }
  421. /**
  422. * Delete images
  423. *
  424. * @param array $imageids
  425. * @return array
  426. */
  427. public function delete($imageids) {
  428. $imageids = zbx_toArray($imageids);
  429. if (empty($imageids)) {
  430. self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty parameters'));
  431. }
  432. if (self::$userData['type'] < USER_TYPE_ZABBIX_ADMIN) {
  433. self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
  434. }
  435. // check if icon is used in icon maps
  436. $sql = 'SELECT DISTINCT im.name '.
  437. ' FROM icon_map im, icon_mapping imp '.
  438. ' WHERE im.iconmapid=imp.iconmapid '.
  439. ' AND ('.
  440. DBCondition('im.default_iconid', $imageids).
  441. ' OR '.DBCondition('imp.iconid', $imageids).
  442. ')';
  443. $dbIconmaps = DBselect($sql);
  444. $usedInIconmaps = array();
  445. while ($iconmap = DBfetch($dbIconmaps)) {
  446. $usedInIconmaps[] = $iconmap['name'];
  447. }
  448. if (!empty($usedInIconmaps)) {
  449. self::exception(ZBX_API_ERROR_PARAMETERS,
  450. _n('The image is used in icon map %2$s.', 'The image is used in icon maps %2$s.',
  451. count($usedInIconmaps), '"'.implode('", "', $usedInIconmaps).'"')
  452. );
  453. }
  454. // check if icon is used in maps
  455. $sql = 'SELECT DISTINCT sm.sysmapid, sm.name'.
  456. ' FROM sysmaps_elements se, sysmaps sm '.
  457. ' WHERE sm.sysmapid=se.sysmapid '.
  458. ' AND ('.
  459. ' sm.iconmapid IS NULL'.
  460. ' OR se.use_iconmap='.SYSMAP_ELEMENT_USE_ICONMAP_OFF.
  461. ' )'.
  462. ' AND ('.
  463. DBCondition('se.iconid_off', $imageids).
  464. ' OR '.DBCondition('se.iconid_on', $imageids).
  465. ' OR '.DBCondition('se.iconid_disabled', $imageids).
  466. ' OR '.DBCondition('se.iconid_maintenance', $imageids).
  467. ') OR '.DBCondition('sm.backgroundid', $imageids);
  468. $dbSysmaps = DBselect($sql);
  469. $usedInMaps = array();
  470. while ($sysmap = DBfetch($dbSysmaps)) {
  471. $usedInMaps[] = $sysmap['name'];
  472. }
  473. if (!empty($usedInMaps)) {
  474. self::exception(ZBX_API_ERROR_PARAMETERS,
  475. _n('The image is used in map %2$s.', 'The image is used in maps %2$s.',
  476. count($usedInMaps), '"'.implode('", "', $usedInMaps).'"')
  477. );
  478. }
  479. DB::update('sysmaps_elements', array('values' => array('iconid_off' => 0), 'where' => array('iconid_off' => $imageids)));
  480. DB::update('sysmaps_elements', array('values' => array('iconid_on' => 0), 'where' => array('iconid_on' => $imageids)));
  481. DB::update('sysmaps_elements', array('values' => array('iconid_disabled' => 0), 'where' => array('iconid_disabled' => $imageids)));
  482. DB::update('sysmaps_elements', array('values' => array('iconid_maintenance' => 0), 'where' => array('iconid_maintenance' => $imageids)));
  483. DB::delete('images', array('imageid' => $imageids));
  484. return array('imageids' => $imageids);
  485. }
  486. }
  487. ?>