Scope the tree Graph Templates filter to the drilled Device Template (#8370)

* Scope the tree Graph Templates filter to the drilled Device Template

When drilling a Site Branch into a Device Template (host_id=-1, host_template_id set), create_tree_filter() fell through to listing every Graph Template. Scope the dropdown to the Graph Templates present on that Device Template's devices (within the drilled Site when set), matching the graphs the branch actually shows.

* docs(CHANGELOG): add issue#8370 entry

* test: cover the tree Device Template graph-template scope; fix CHANGELOG ordering

Add an isolated source-slice probe that drives create_tree_filter()'s new host_template_id branch so the changed lines meet the >=80% changed-line coverage gate, wired into run_request_coverage.sh. Move the issue#8370 CHANGELOG entry into the issue block so it no longer precedes the security entries.

* docs(CHANGELOG): append issue#8370 at the end of the issue block
This commit is contained in:
TheWitness authored and GitHub committed 2026-10-14 20:56:12 -04:00
1 parent 75f92c2d86
commit ffd7a81109
4 files changed
+93

No files matched your search

+1
View File
@@ -233,6 +233,7 @@ Cacti CHANGELOG
-issue#8040: Regenerate the vendored DOMPurify asset to match the pinned 3.4.15 release and keep node_modules during CI
-issue#8041: Detect a real TTY instead of a dead github_actions check before calling stty size
-issue#8043: Regenerate the vendored DOMPurify asset to match the pinned 3.4.15 release and keep node_modules during CI
-issue#8370: When drilling a Site Branch into a Device Template, the Tree view Graph Templates filter now lists only the Graph Templates present on that Device Template's devices
-feature#8166: Add a cross-process shared SNMP authentication cache (disabled by default) that pre-hardens SNMPv3 credential arguments once per credential change and seals them with the per-installation AES-256-GCM key, so poller, cmd and script server processes reuse them instead of rebuilding them on every request
-feature#8166: Route SNMPv3 get/getnext through the in-process php-snmp extension when the running PHP version supports the configured auth/privacy protocols and no context/engine id is set, bypassing a per-request Net-SNMP binary spawn
-feature#8166: Add an "Enable MD5 and DES for SNMPv3" setting (off by default) that removes the legacy MD5/DES algorithms from the Device and Automation SNMP Option pickers when disabled, and default new Devices to SHA/AES
+10
View File
@@ -970,6 +970,16 @@ function create_tree_filter() : array {
$templates = get_allowed_graph_templates_normalized('gl.host_id=0', 'name', '', $total_rows);
} elseif (gfrv('host_id') > 0) {
$templates = get_allowed_graph_templates_normalized('gl.host_id=' . gfrv('host_id'), 'name', '', $total_rows);
} elseif (gfrv('host_template_id') > 0) {
// Site Branch drilled into by Device Template: limit the Graph Templates to
// those present on that Device Template's devices (within the Site when set)
$device_where = 'host_template_id=' . gfrv('host_template_id');
if (gfrv('site_id') > 0) {
$device_where .= ' AND site_id=' . gfrv('site_id');
}
$templates = get_allowed_graph_templates_normalized('gl.host_id IN (SELECT id FROM host WHERE ' . $device_where . ')', 'name', '', $total_rows);
} else {
$templates = get_allowed_graph_templates_normalized('', 'name', '', $total_rows);
}
@@ -0,0 +1,80 @@
<?php
// Copyright (C) 2026 The Cacti Group. Licensed under GPL-2.0-or-later.
namespace CactiTreeFilterDeviceTemplateFixture;
use RuntimeException;
/*
* Request-coverage probe for the Tree view Graph Templates filter scoping by the
* drilled Device Template.
*
* create_tree_filter() (lib/html_tree.php) reaches its host_template_id branch
* only when a Site Branch is drilled into by Device Template (host_id == -1 with
* host_template_id set), a path the page-level e2e suites do not drive. The
* function is loaded in isolation with its I/O boundaries stubbed so the
* production statements run and RequestCoverage maps the hits back to source.
*/
require dirname(__DIR__, 2) . '/Helpers/RequestCoverage.php';
require dirname(__DIR__, 2) . '/Helpers/SourceSlice.php';
$root = dirname(__DIR__, 3);
require $root . '/include/global_constants.php';
$GLOBALS['item_rows'] = ['-1' => 'All', '15' => '15', '30' => '30'];
$GLOBALS['_SESSION'] = ['sess_user_id' => 1];
$GLOBALS['_REQUEST'] = ['host_id' => '-1', 'host_template_id' => '7', 'site_id' => '3', 'graph_template_id' => '-1'];
$GLOBALS['captured_graph_template_where'] = null;
function __($text, ...$args) {
return $args !== [] ? @vsprintf($text, $args) : $text;
}
function cacti_sizeof($value) {
return is_countable($value) ? count($value) : 0;
}
function read_user_setting($name, $default = '') {
return $default;
}
function html_graph_order_filter_array() {
return [];
}
function is_view_allowed($view) {
return true;
}
function isrv($name) {
return isset($GLOBALS['_REQUEST'][$name]);
}
function gnrv($name, $default = '') {
return $GLOBALS['_REQUEST'][$name] ?? $default;
}
function grv($name, $default = '') {
return $GLOBALS['_REQUEST'][$name] ?? $default;
}
function gfrv($name, $filter = FILTER_VALIDATE_INT, $options = []) {
return (int) ($GLOBALS['_REQUEST'][$name] ?? 0);
}
function srv($name, $value) {
$GLOBALS['_REQUEST'][$name] = $value;
}
function get_allowed_graph_templates_normalized($sql_where = '', $order = 'name', $limit = '', &$total_rows = 0) {
$GLOBALS['captured_graph_template_where'] = $sql_where;
$total_rows = 0;
return [];
}
cacti_fixture_source_function($root . '/lib/html_tree.php', 'create_tree_filter', __NAMESPACE__);
$filters = create_tree_filter();
$where = $GLOBALS['captured_graph_template_where'];
if ($where !== 'gl.host_id IN (SELECT id FROM host WHERE host_template_id=7 AND site_id=3)') {
throw new RuntimeException('Device Template tree filter did not scope the Graph Templates query: ' . var_export($where, true));
}
if (!isset($filters['rows'][1]['graph_template_id'])) {
throw new RuntimeException('create_tree_filter did not build the Graph Template dropdown');
}
print json_encode(['device_template_scope' => true], JSON_THROW_ON_ERROR) . "\n";
+2
View File
@@ -40,4 +40,6 @@ run_php_probe tests/fixtures/UserAdministrationAuditCoverage.php '^(user_admin\.
run_php_probe tests/fixtures/Core/GraphViewCrossFilterCoverage.php '^(lib/html\.php|lib/html_graph\.php|tests/fixtures/Core/GraphViewCrossFilterCoverage\.php)'
run_php_probe tests/fixtures/Core/TreeFilterDeviceTemplateCoverage.php '^(lib/html_tree\.php|tests/fixtures/Core/TreeFilterDeviceTemplateCoverage\.php)'
run_probe tests/e2e/installer-coverage.sh '^(lib/installer\.php|cli/(install_cacti|upgrade_database)\.php|install/(functions|preflight|report|background|install)\.php|tests/e2e/installer)' 18277