1<?php 2/* 3 +-------------------------------------------------------------------------+ 4 | Copyright (C) 2004-2021 The Cacti Group | 5 | | 6 | This program is free software; you can redistribute it and/or | 7 | modify it under the terms of the GNU General Public License | 8 | as published by the Free Software Foundation; either version 2 | 9 | of the License, or (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 | Cacti: The Complete RRDtool-based Graphing Solution | 17 +-------------------------------------------------------------------------+ 18 | This code is designed, written, and maintained by the Cacti Group. See | 19 | about.php and/or the AUTHORS file for specific developer information. | 20 +-------------------------------------------------------------------------+ 21 | http://www.cacti.net/ | 22 +-------------------------------------------------------------------------+ 23*/ 24 25function api_delete_graphs(&$local_graph_ids, $delete_type) { 26 /* check for a bad local_graph_id = 0, and remove graphs */ 27 api_graph_remove_bad_graphs($local_graph_ids); 28 29 if (!cacti_sizeof($local_graph_ids)) { 30 return; 31 } 32 33 api_graph_remove_aggregate_items($local_graph_ids); 34 35 switch ($delete_type) { 36 case '2': // delete all data sources referenced by this graph 37 $all_data_sources = array_rekey( 38 db_fetch_assoc('SELECT DISTINCT dtd.local_data_id 39 FROM data_template_data AS dtd 40 INNER JOIN data_template_rrd AS dtr 41 ON dtd.local_data_id=dtr.local_data_id 42 INNER JOIN graph_templates_item AS gti 43 ON dtr.id=gti.task_item_id 44 WHERE ' . array_to_sql_or($local_graph_ids, 'gti.local_graph_id') . ' 45 AND gti.local_graph_id NOT IN(SELECT local_graph_id FROM aggregate_graphs) 46 AND dtd.local_data_id > 0'), 47 'local_data_id', 'local_data_id' 48 ); 49 50 if (cacti_sizeof($all_data_sources)) { 51 $data_sources = array_rekey( 52 db_fetch_assoc('SELECT dtd.local_data_id, 53 COUNT(DISTINCT gti.local_graph_id) AS graphs 54 FROM data_template_data AS dtd 55 INNER JOIN data_template_rrd AS dtr 56 ON dtd.local_data_id=dtr.local_data_id 57 INNER JOIN graph_templates_item AS gti 58 ON dtr.id=gti.task_item_id 59 WHERE dtd.local_data_id > 0 60 AND gti.local_graph_id NOT IN(SELECT local_graph_id FROM aggregate_graphs) 61 GROUP BY dtd.local_data_id 62 HAVING graphs = 1 63 AND ' . array_to_sql_or($all_data_sources, 'local_data_id')), 64 'local_data_id', 'local_data_id' 65 ); 66 67 if (cacti_sizeof($data_sources)) { 68 api_data_source_remove_multi($data_sources); 69 } 70 71 api_graph_remove_multi($local_graph_ids); 72 73 /* Remove orphaned data sources */ 74 $data_sources = array_rekey( 75 db_fetch_assoc('SELECT DISTINCT dtd.local_data_id 76 FROM data_template_data AS dtd 77 INNER JOIN data_template_rrd AS dtr 78 ON dtd.local_data_id=dtr.local_data_id 79 LEFT JOIN graph_templates_item AS gti 80 ON dtr.id=gti.task_item_id 81 WHERE ' . array_to_sql_or($all_data_sources, 'dtd.local_data_id') . ' 82 AND gti.local_graph_id IS NULL 83 AND gti.local_graph_id NOT IN(SELECT local_graph_id FROM aggregate_graphs) 84 AND dtd.local_data_id > 0'), 85 'local_data_id', 'local_data_id' 86 ); 87 88 if (cacti_sizeof($data_sources)) { 89 api_data_source_remove_multi($data_sources); 90 } 91 } 92 93 break; 94 case '1': 95 api_graph_remove_multi($local_graph_ids); 96 97 break; 98 } 99} 100 101function api_graph_remove($local_graph_id) { 102 if (empty($local_graph_id)) { 103 $local_graph_ids = array($local_graph_id); 104 api_graph_remove_bad_graphs($local_graph_ids); 105 return; 106 } 107 108 api_plugin_hook_function('graphs_remove', array($local_graph_id)); 109 110 api_graph_remove_aggregate_items($local_graph_id); 111 112 db_execute_prepared('DELETE FROM graph_templates_graph WHERE local_graph_id = ?', array($local_graph_id)); 113 db_execute_prepared('DELETE FROM graph_templates_item WHERE local_graph_id = ?', array($local_graph_id)); 114 db_execute_prepared('DELETE FROM graph_tree_items WHERE local_graph_id = ?', array($local_graph_id)); 115 db_execute_prepared('DELETE FROM reports_items WHERE local_graph_id = ?', array($local_graph_id)); 116 db_execute_prepared('DELETE FROM graph_local WHERE id = ?', array($local_graph_id)); 117} 118 119function api_graph_remove_bad_graphs(&$local_graph_ids = array()) { 120 if (cacti_sizeof($local_graph_ids)) { 121 $bad_graph = array_search(0, $local_graph_ids); 122 if ($bad_graph !== false) { 123 unset($local_graph_ids[$bad_graph]); 124 125 db_execute('DELETE FROM graph_local 126 WHERE id = 0'); 127 128 db_execute('DELETE FROM graph_templates_graph 129 WHERE local_graph_id = 0 130 AND graph_template_id = 0'); 131 132 db_execute('DELETE FROM graph_templates_item 133 WHERE hash = "" 134 AND local_graph_id = 0'); 135 } 136 } 137} 138 139function api_graph_remove_aggregate_items($local_graph_ids) { 140 if (!is_array($local_graph_ids)) { 141 $local_graph_ids = explode(',', $local_graph_ids); 142 } 143 144 foreach($local_graph_ids as $lgid) { 145 $aggregate_graphs = array_rekey( 146 db_fetch_assoc_prepared('SELECT DISTINCT aggregate_graph_id 147 FROM aggregate_graphs_items 148 WHERE local_graph_id = ?', 149 array($lgid)), 150 'aggregate_graph_id', 'aggregate_graph_id' 151 ); 152 153 if (cacti_sizeof($aggregate_graphs)) { 154 foreach($aggregate_graphs as $ag) { 155 api_aggregate_disassociate($ag, $lgid); 156 } 157 } 158 } 159} 160 161function api_graph_remove_multi($local_graph_ids) { 162 /* check for a bad local_graph_id = 0, and remove graphs */ 163 api_graph_remove_bad_graphs($local_graph_ids); 164 165 if (!cacti_sizeof($local_graph_ids)) { 166 return; 167 } 168 169 /* initialize variables */ 170 $ids_to_delete = ''; 171 $i = 0; 172 173 /* build the array */ 174 if (cacti_sizeof($local_graph_ids)) { 175 api_plugin_hook_function('graphs_remove', $local_graph_ids); 176 177 foreach($local_graph_ids as $local_graph_id) { 178 if ($i == 0) { 179 $ids_to_delete .= $local_graph_id; 180 } else { 181 $ids_to_delete .= ', ' . $local_graph_id; 182 } 183 184 $i++; 185 186 if (($i % 1000) == 0) { 187 api_graph_remove_aggregate_items($ids_to_delete); 188 189 db_execute("DELETE FROM graph_templates_graph WHERE local_graph_id IN ($ids_to_delete)"); 190 db_execute("DELETE FROM graph_templates_item WHERE local_graph_id IN ($ids_to_delete)"); 191 db_execute("DELETE FROM graph_tree_items WHERE local_graph_id IN ($ids_to_delete)"); 192 db_execute("DELETE FROM reports_items WHERE local_graph_id IN ($ids_to_delete)"); 193 db_execute("DELETE FROM graph_local WHERE id IN ($ids_to_delete)"); 194 195 $i = 0; 196 $ids_to_delete = ''; 197 } 198 } 199 200 if ($i > 0) { 201 api_graph_remove_aggregate_items($ids_to_delete); 202 203 db_execute("DELETE FROM graph_templates_graph WHERE local_graph_id IN ($ids_to_delete)"); 204 db_execute("DELETE FROM graph_templates_item WHERE local_graph_id IN ($ids_to_delete)"); 205 db_execute("DELETE FROM graph_tree_items WHERE local_graph_id IN ($ids_to_delete)"); 206 db_execute("DELETE FROM reports_items WHERE local_graph_id IN ($ids_to_delete)"); 207 db_execute("DELETE FROM graph_local WHERE id IN ($ids_to_delete)"); 208 } 209 } 210} 211 212/* api_resize_graphs - resizes the selected graph, overriding the template value 213 @arg $graph_templates_graph_id - the id of the graph to resize 214 @arg $graph_width - the width of the resized graph 215 @arg $graph_height - the height of the resized graph 216 */ 217function api_resize_graphs($local_graph_id, $graph_width, $graph_height) { 218 /* get graphs template id */ 219 db_execute_prepared('UPDATE graph_templates_graph 220 SET width = ?, height = ? 221 WHERE local_graph_id = ?', 222 array($graph_width, $graph_height, $local_graph_id)); 223} 224 225/* api_reapply_suggested_graph_title - reapplies the suggested name to a graph title 226 @param int $graph_templates_graph_id - the id of the graph to reapply the name to 227*/ 228function api_reapply_suggested_graph_title($local_graph_id) { 229 global $config; 230 231 /* get graphs template id */ 232 $graph_template_id = db_fetch_cell_prepared('SELECT graph_template_id 233 FROM graph_templates_graph 234 WHERE local_graph_id = ?', 235 array($local_graph_id)); 236 237 /* if a non-template graph, simply return */ 238 if ($graph_template_id == 0) { 239 return; 240 } 241 242 /* get the host associated with this graph for data queries only 243 * there's no "reapply suggested title" for "simple" graph templates */ 244 $graph_local = db_fetch_row_prepared('SELECT * 245 FROM graph_local 246 WHERE id = ?', 247 array($local_graph_id)); 248 249 /* if this is not a data query graph, simply return */ 250 if (!isset($graph_local['host_id'])) { 251 return; 252 } 253 254 /* no snmp query graph id found */ 255 if ($graph_local['snmp_query_graph_id'] == 0) { 256 return; 257 } 258 259 /* get the suggested values from the suggested values cache */ 260 $suggested_values = db_fetch_assoc_prepared("SELECT text, field_name 261 FROM snmp_query_graph_sv 262 WHERE snmp_query_graph_id = ? 263 AND field_name = 'title' 264 ORDER BY sequence", 265 array($graph_local['snmp_query_graph_id'])); 266 267 $matches = array(); 268 269 $suggested_values_graph = array(); 270 if (cacti_sizeof($suggested_values)) { 271 foreach ($suggested_values as $suggested_value) { 272 /* once we find a match; don't try to find more */ 273 if (!isset($suggested_values_graph[$suggested_value['field_name']])) { 274 $subs_string = substitute_snmp_query_data($suggested_value['text'], $graph_local['host_id'], $graph_local['snmp_query_id'], $graph_local['snmp_index'], read_config_option('max_data_query_field_length')); 275 276 /* if there are no '|' characters, all of the substitutions were successful */ 277 if (!substr_count($subs_string, '|query')) { 278 if (in_array($suggested_value['field_name'], $matches)) { 279 continue; 280 } 281 282 $matches[] = $suggested_value['field_name']; 283 284 db_execute_prepared('UPDATE graph_templates_graph 285 SET ' . $suggested_value['field_name'] . ' = ? 286 WHERE local_graph_id = ?', 287 array($suggested_value['text'], $local_graph_id)); 288 289 /* once we find a working value for this very field, stop */ 290 $suggested_values_graph[$suggested_value['field_name']] = true; 291 } 292 } 293 } 294 295 if (cacti_sizeof($matches)) { 296 return true; 297 } 298 } 299 300 return false; 301} 302 303/* api_get_graphs_from_datasource - get's all graphs related to a data source 304 @arg $local_data_id - the id of the data source 305 @returns - array($id => $name_cache) returns the graph id's and names of the graphs 306 */ 307function api_get_graphs_from_datasource($local_data_id) { 308 return array_rekey(db_fetch_assoc_prepared('SELECT DISTINCT graph_templates_graph.local_graph_id AS id, 309 graph_templates_graph.title_cache AS name 310 FROM (graph_templates_graph 311 INNER JOIN graph_templates_item 312 ON graph_templates_graph.local_graph_id = graph_templates_item.local_graph_id) 313 INNER JOIN data_template_rrd 314 ON graph_templates_item.task_item_id = data_template_rrd.id 315 WHERE graph_templates_graph.local_graph_id > 0 316 AND data_template_rrd.local_data_id = ?', array($local_data_id)), 'id', 'name'); 317} 318 319function api_duplicate_graph($_local_graph_id, $_graph_template_id, $graph_title) { 320 global $struct_graph, $struct_graph_item; 321 322 if (!empty($_local_graph_id)) { 323 $graph_local = db_fetch_row_prepared('SELECT * 324 FROM graph_local 325 WHERE id = ?', 326 array($_local_graph_id)); 327 328 $graph_template_graph = db_fetch_row_prepared('SELECT * 329 FROM graph_templates_graph 330 WHERE local_graph_id = ?', 331 array($_local_graph_id)); 332 333 $graph_template_items = db_fetch_assoc_prepared('SELECT * 334 FROM graph_templates_item 335 WHERE local_graph_id = ?', 336 array($_local_graph_id)); 337 338 /* create new entry: graph_local */ 339 $save['id'] = 0; 340 $save['graph_template_id'] = $graph_local['graph_template_id']; 341 $save['host_id'] = $graph_local['host_id']; 342 $save['snmp_query_id'] = $graph_local['snmp_query_id']; 343 $save['snmp_index'] = $graph_local['snmp_index']; 344 345 $local_graph_id = sql_save($save, 'graph_local'); 346 347 $graph_template_graph['title'] = str_replace('<graph_title>', $graph_template_graph['title'], $graph_title); 348 } elseif (!empty($_graph_template_id)) { 349 $graph_template = db_fetch_row_prepared('SELECT * 350 FROM graph_templates 351 WHERE id = ?', 352 array($_graph_template_id)); 353 354 $graph_template_graph = db_fetch_row_prepared('SELECT * 355 FROM graph_templates_graph 356 WHERE graph_template_id = ? 357 AND local_graph_id=0', 358 array($_graph_template_id)); 359 360 $graph_template_items = db_fetch_assoc_prepared('SELECT * 361 FROM graph_templates_item 362 WHERE graph_template_id = ? 363 AND local_graph_id=0', 364 array($_graph_template_id)); 365 366 $graph_template_inputs = db_fetch_assoc_prepared('SELECT * 367 FROM graph_template_input 368 WHERE graph_template_id = ?', 369 array($_graph_template_id)); 370 371 /* create new entry: graph_templates */ 372 $save['id'] = 0; 373 $save['hash'] = get_hash_graph_template(0); 374 $save['name'] = str_replace('<template_title>', $graph_template['name'], $graph_title); 375 $save['multiple'] = $graph_template['multiple']; 376 377 $graph_template_id = sql_save($save, 'graph_templates'); 378 } 379 380 unset($save); 381 382 /* create new entry: graph_templates_graph */ 383 $save['id'] = 0; 384 $save['local_graph_id'] = (isset($local_graph_id) ? $local_graph_id : 0); 385 $save['local_graph_template_graph_id'] = (isset($graph_template_graph['local_graph_template_graph_id']) ? $graph_template_graph['local_graph_template_graph_id'] : 0); 386 $save['graph_template_id'] = (!empty($_local_graph_id) ? $graph_template_graph['graph_template_id'] : $graph_template_id); 387 $save['title_cache'] = $graph_template_graph['title_cache']; 388 389 foreach ($struct_graph as $field => $array) { 390 if ($array['method'] == 'spacer') continue; 391 $save[$field] = $graph_template_graph[$field]; 392 $save['t_' . $field] = $graph_template_graph['t_' . $field]; 393 } 394 395 $graph_templates_graph_id = sql_save($save, 'graph_templates_graph'); 396 397 /* create new entry(s): graph_templates_item */ 398 if (cacti_sizeof($graph_template_items)) { 399 foreach ($graph_template_items as $graph_template_item) { 400 unset($save); 401 402 $save['id'] = 0; 403 /* save a hash only for graph_template copy operations */ 404 $save['hash'] = (!empty($_graph_template_id) ? get_hash_graph_template(0, 'graph_template_item') : 0); 405 $save['local_graph_id'] = (isset($local_graph_id) ? $local_graph_id : 0); 406 $save['graph_template_id'] = (!empty($_local_graph_id) ? $graph_template_item['graph_template_id'] : $graph_template_id); 407 $save['local_graph_template_item_id'] = (isset($graph_template_item['local_graph_template_item_id']) ? $graph_template_item['local_graph_template_item_id'] : 0); 408 409 foreach ($struct_graph_item as $field => $array) { 410 $save[$field] = $graph_template_item[$field]; 411 } 412 413 $graph_item_mappings[$graph_template_item['id']] = sql_save($save, 'graph_templates_item'); 414 } 415 } 416 417 if (!empty($_graph_template_id)) { 418 /* create new entry(s): graph_template_input (graph template only) */ 419 if (cacti_sizeof($graph_template_inputs)) { 420 foreach ($graph_template_inputs as $graph_template_input) { 421 unset($save); 422 423 $save['id'] = 0; 424 $save['graph_template_id'] = $graph_template_id; 425 $save['name'] = $graph_template_input['name']; 426 $save['description'] = $graph_template_input['description']; 427 $save['column_name'] = $graph_template_input['column_name']; 428 $save['hash'] = get_hash_graph_template(0, 'graph_template_input'); 429 430 $graph_template_input_id = sql_save($save, 'graph_template_input'); 431 432 $graph_template_input_defs = db_fetch_assoc_prepared('SELECT * 433 FROM graph_template_input_defs 434 WHERE graph_template_input_id = ?', 435 array($graph_template_input['id'])); 436 437 /* create new entry(s): graph_template_input_defs (graph template only) */ 438 if (cacti_sizeof($graph_template_input_defs)) { 439 foreach ($graph_template_input_defs as $graph_template_input_def) { 440 db_execute_prepared('INSERT INTO graph_template_input_defs 441 (graph_template_input_id, graph_template_item_id) 442 VALUES (?, ?)', 443 array( 444 $graph_template_input_id, 445 $graph_item_mappings[$graph_template_input_def['graph_template_item_id']] 446 ) 447 ); 448 } 449 } 450 } 451 } 452 } 453 454 if (!empty($_local_graph_id)) { 455 update_graph_title_cache($local_graph_id); 456 } else { 457 // Graph Template, Check for Data Query Associated Graph Template 458 $data_query_graphs = db_fetch_assoc_prepared('SELECT * 459 FROM snmp_query_graph 460 WHERE graph_template_id = ?', 461 array($_graph_template_id)); 462 463 if (cacti_sizeof($data_query_graphs)) { 464 unset($save); 465 466 $name = db_fetch_cell_prepared('SELECT name 467 FROM graph_templates 468 WHERE id = ?', 469 array($graph_template_id)); 470 471 foreach($data_query_graphs as $dqg) { 472 /* map the snmp_query_graph */ 473 unset($save); 474 475 $save['id'] = 0; 476 $save['hash'] = get_hash_data_query('', 'data_query_graph'); 477 $save['snmp_query_id'] = $dqg['snmp_query_id']; 478 $save['name'] = $name; 479 $save['graph_template_id'] = $graph_template_id; 480 481 $snmp_query_graph_id = sql_save($save, 'snmp_query_graph'); 482 483 /* map the snmp_query_graph_rrds */ 484 if (!empty($snmp_query_graph_id)) { 485 $snmp_query_graph_rrds = db_fetch_assoc_prepared('SELECT * 486 FROM snmp_query_graph_rrd 487 WHERE snmp_query_graph_id = ?', 488 array($dqg['id'])); 489 490 if (cacti_sizeof($snmp_query_graph_rrds)) { 491 foreach($snmp_query_graph_rrds as $sqgr) { 492 db_execute_prepared('INSERT INTO snmp_query_graph_rrd 493 (snmp_query_graph_id, data_template_id, data_template_rrd_id, snmp_field_name) 494 VALUES (?, ?, ?, ?)', 495 array( 496 $snmp_query_graph_id, 497 $sqgr['data_template_id'], 498 $sqgr['data_template_rrd_id'], 499 $sqgr['snmp_field_name'] 500 ) 501 ); 502 } 503 } 504 } 505 506 /* map data source suggested values */ 507 $snames = db_fetch_assoc_prepared('SELECT * 508 FROM snmp_query_graph_rrd_sv 509 WHERE snmp_query_graph_id = ?', 510 array($dqg['id'])); 511 512 if (cacti_sizeof($snames)) { 513 foreach($snames as $sn) { 514 unset($save); 515 516 $save['id'] = 0; 517 $save['hash'] = get_hash_data_query(0, 'data_query_sv_data_source'); 518 $save['snmp_query_graph_id'] = $snmp_query_graph_id; 519 $save['data_template_id'] = $sn['data_template_id']; 520 $save['sequence'] = $sn['sequence']; 521 $save['field_name'] = $sn['field_name']; 522 $save['text'] = $sn['text']; 523 524 sql_save($save, 'snmp_query_graph_rrd_sv'); 525 } 526 } 527 528 /* map graph suggested values */ 529 $snames = db_fetch_assoc_prepared('SELECT * 530 FROM snmp_query_graph_sv 531 WHERE snmp_query_graph_id = ?', 532 array($dqg['id'])); 533 534 if (cacti_sizeof($snames)) { 535 foreach($snames as $sn) { 536 unset($save); 537 538 $save['id'] = 0; 539 $save['hash'] = get_hash_data_query(0, 'data_query_sv_graph'); 540 $save['snmp_query_graph_id'] = $snmp_query_graph_id; 541 $save['sequence'] = $sn['sequence']; 542 $save['field_name'] = $sn['field_name']; 543 $save['text'] = $sn['text']; 544 545 sql_save($save, 'snmp_query_graph_sv'); 546 } 547 } 548 } 549 } 550 } 551} 552 553function api_graph_change_device($local_graph_id, $host_id) { 554 $dqgraph = db_fetch_cell_prepared('SELECT snmp_query_id 555 FROM graph_local 556 WHERE id = ?', 557 array($local_graph_id)); 558 559 if (empty($dqgraph)) { 560 db_execute_prepared('UPDATE graph_local 561 SET host_id = ? 562 WHERE id = ?', 563 array($host_id, $local_graph_id)); 564 565 update_graph_title_cache($local_graph_id); 566 567 /* update the data sources as well */ 568 $data_ids = db_fetch_assoc_prepared('SELECT DISTINCT dtr.local_data_id 569 FROM graph_templates_item AS gti 570 INNER JOIN data_template_rrd AS dtr 571 ON gti.task_item_id=dtr.id 572 WHERE gti.local_graph_id = ?', 573 array($local_graph_id)); 574 575 if (cacti_sizeof($data_ids)) { 576 foreach($data_ids as $data_id) { 577 db_execute_prepared('UPDATE data_local 578 SET host_id = ? 579 WHERE id = ?', 580 array($host_id, $data_id['local_data_id'])); 581 582 db_execute_prepared('UPDATE poller_item 583 SET host_id = ? 584 WHERE local_data_id = ?', 585 array($host_id, $data_id['local_data_id'])); 586 } 587 } 588 589 return true; 590 } 591 592 return false; 593} 594 595