PHPStan Level 8 - Phase 1 Conversion (#8135)

* PHPStan Level 8 - Phase 1 Conversion

Reduces the real (no-baseline) PHPStan level 8 error count from ~2,724 to 425
and regenerates phpstan-baseline.neon accordingly (8,941 -> 1,921 lines).

Core type-safety changes
- lib/database.php: narrow db_fetch_row()/db_fetch_row_prepared() to return
  array (was bool|array) and db_fetch_assoc()/db_fetch_assoc_prepared() to
  return array (was mixed); the _prepared workers coerce the connection-failure
  path to an empty array so the declared type is honest. empty()/cacti_sizeof()
  checks are unaffected.
- lib/database.php: narrow $db_conn guards from is_object() to instanceof PDO in
  the transaction/quote/insert-id helpers so the PDO calls resolve.
- lib/mib_cache.php: the fluent MibCache methods mib()/object()/table()/row()
  now return self instead of a bare object so chained calls type-check.

Type-safety casts and guards (mechanical, behaviour-preserving)
- Cast string|false/|null builtin results feeding string parameters
  (json_decode, base64_encode, trim, htmle, preg_replace, explode, etc.).
- Cast int|string / int|false values feeding int id/pid parameters.
- Guard resource|false fopen()/popen() handles before fwrite/fclose/fread, and
  wrap foreach over array|false/list|false results with `?: []`.

Genuine bugs found and fixed
- cli/add_tree.php / lib/api_tree.php: site tree nodes could not be created via
  the CLI - the --site-id option was never parsed, $nodeTypes had no 'site'
  entry (passing null to api_tree_item_save(int $type) -> TypeError), and
  api_tree_item_save() never persisted site_id. All three fixed.
- tree.php: leaves_exist() is typed : int but returned db_fetch_assoc_prepared()
  (an array of rows) for a SELECT COUNT(*); now uses db_fetch_cell_prepared()
  and returns the scalar count.
- lib/mib_cache.php: $entries_per_object was a float (division / ceil) used as
  an array key (PHP 8.1 implicit float-to-int key deprecation); now cast to int.

Config
- .phpstan.neon: add notIdentical.alwaysTrue and booleanAnd.alwaysFalse to the
  existing always-true/false ignore family (same "PHPStan gets confused"
  dynamic-constant cause already covered by identical.alwaysTrue,
  notEqual.alwaysTrue, booleanAnd.leftAlwaysTrue, etc.).
- phpstan-baseline.neon: regenerated; the remaining 425 entries are the
  untouched long tail for Phase 2.

* Remove redundant @phpstan-ignore comments

Follow-up cleanup for the level 8 Phase 1 work. Removes 14 inline
@phpstan-ignore comments that no longer suppress any reported error:

- cli/repair_database.php: `@phpstan-ignore booleanAnd.alwaysFalse` is now
  covered by the global booleanAnd.alwaysFalse ignore added to .phpstan.neon.
- 13 others (host.php, include/global.php, include/session.php,
  lib/api_automation.php x2, lib/functions.php x2, lib/html_utility.php x2,
  lib/installer.php, lib/package.php, lib/reports.php, lib/rrd.php) no longer
  match any reported error after the type-safety fixes (e.g. the
  db_fetch_row_prepared() return-type narrowing removed the offset-assign
  errors the api_automation ignores were suppressing).

Verified with reportUnmatchedIgnoredErrors enabled: 0 unmatched ignores
remain and the full level 8 run still reports 0 errors.

* ci: satisfy validator ratchet and refresh security sink baselines

- lib/api_tree.php: give the new tree-item site_id a real numeric
  constraint ('^[-0-9]+$', matching html_reports.php) instead of an
  empty regex, so the validator constraint ratchet passes without
  bumping its baseline.
- tests/security/baselines: refresh the three sink/hotspot signatures
  whose code text changed from the (string) casts added in this branch
  (lib/poller.php setsid, cli/rrdresize.php json_encode, lib/import.php
  simplexml_load_string).

* ci(js): allow DOMPurify 3.4.16 and update sync_js pin test

The dependabot bump (#8134) moved package.json/package-lock.json to
DOMPurify 3.4.16 on develop but left tests/js/sync_js.test.mjs pinned to
3.4.15, so the PR merge commit fails the 'DOMPurify is pinned' contract.
Bring package.json/package-lock.json to 3.4.16 (matching develop) and
update the pin test to expect 3.4.16.

* test: update sql.php null-handling assertion for the (string) cast

This branch changed scripts/sql.php from trim(\ ?? '') to
trim((string) \) (the phpstan-safe form that coerces both null and
false from shell_exec()). Update SqlScriptsTest's null-return assertion
to match the new cast instead of the removed '?? ''.

* fix: address Copilot review - ownership IDs, fopen guards, mib_cache bound

- chown()/chgrp(): pass integer UID/GID from fileowner()/filegroup()
  (guarding the false lookup) instead of string-casting them, which made
  them resolve account/group names like '1001' and fail. Covers
  lib/api_device.php, lib/boost.php and poller_maintenance.php (x2).
- fopen() failure now short-circuits instead of reporting success:
  lib/package.php returns false, lib/clog_webapi.php and utilities.php
  render an error, and snmpagent_mibcachechild.php skips the cache write
  and sentinel unlink so a concurrent writer's lock is preserved.
- lib/mib_cache.php: keep the float quotient as the loop bound and cast
  only the array offset, so a non-even entries/columns split no longer
  truncates the loop and drops a cached row.

* revert: keep db_fetch_* returning false on error; baseline Level 8 instead

Per review, restoring the intentional fail-safe: db_fetch_row[_prepared]()
return bool|array and db_fetch_assoc[_prepared]() return mixed again, so a
genuine SQL error (not just a missing connection) is signalled as false and
the === false checks in cdef_is_in_use(), boost_process_* and aggregate.php
work as before. Dropped the is_array() ? : [] coercion.

Level 8 stays green by regenerating phpstan-baseline.neon to capture the
re-introduced bool|array/mixed call-site errors (the ~1,850 the narrowing
had eliminated). Tightening those callers to drop them from the baseline is
Phase 2 work.

---------

Co-authored-by: TheWitness <copilot@users.noreply.github.com>
This commit is contained in:
TheWitnessandTheWitness authored and GitHub committed 2026-10-02 10:08:56 -04:00
1 parent 72eb913f5d
commit 3ab4c69fb7
98 files changed
+418 -1844

No files matched your search

+2
View File
@@ -38,6 +38,7 @@ parameters:
- identifier: if.alwaysFalse - identifier: if.alwaysFalse
- identifier: notEqual.alwaysFalse - identifier: notEqual.alwaysFalse
- identifier: notEqual.alwaysTrue - identifier: notEqual.alwaysTrue
- identifier: notIdentical.alwaysTrue
- identifier: equal.alwaysTrue - identifier: equal.alwaysTrue
- identifier: if.alwaysTrue - identifier: if.alwaysTrue
- identifier: while.alwaysTrue - identifier: while.alwaysTrue
@@ -46,6 +47,7 @@ parameters:
- identifier: identical.alwaysFalse - identifier: identical.alwaysFalse
- identifier: booleanAnd.leftAlwaysTrue - identifier: booleanAnd.leftAlwaysTrue
- identifier: booleanAnd.leftAlwaysFalse - identifier: booleanAnd.leftAlwaysFalse
- identifier: booleanAnd.alwaysFalse
- identifier: function.alreadyNarrowedType - identifier: function.alreadyNarrowedType
# L9 - '/^Parameter #1 \$value of function strval expects bool\|float\|int\|resource\|string\|null, mixed given.$/' # L9 - '/^Parameter #1 \$value of function strval expects bool\|float\|int\|resource\|string\|null, mixed given.$/'
# L9 - '/^Parameter #1 \$value of function intval expects array\|bool\|float\|int\|resource\|string\|null, mixed given.$/' # L9 - '/^Parameter #1 \$value of function intval expects array\|bool\|float\|int\|resource\|string\|null, mixed given.$/'
+18 -18
View File
@@ -74,14 +74,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$verror = validate_parameters($params, $allowed_hosts_filter); $verror = validate_parameters($params, $allowed_hosts_filter);
if ($verror) { if ($verror) {
$response->getBody()->write(json_encode($verror)); $response->getBody()->write((string) json_encode($verror));
cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API');
return $response->withStatus(400)->withHeader('Content-Type', 'application/json'); return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
} }
$json = json_encode(get_hosts($params)); $json = (string) json_encode(get_hosts($params));
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -95,14 +95,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$verror = validate_parameters($params, $allowed_host_templates_filter); $verror = validate_parameters($params, $allowed_host_templates_filter);
if ($verror) { if ($verror) {
$response->getBody()->write(json_encode($verror)); $response->getBody()->write((string) json_encode($verror));
cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API');
return $response->withStatus(400)->withHeader('Content-Type', 'application/json'); return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
} }
$json = json_encode(get_host_templates($params['template_id'] ?? 0)); $json = (string) json_encode(get_host_templates($params['template_id'] ?? 0));
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -112,7 +112,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$infoGroup->get('/graph_list', function (Request $request, Response $response) { $infoGroup->get('/graph_list', function (Request $request, Response $response) {
$params = $request->getQueryParams(); $params = $request->getQueryParams();
$host_id = $params['host_id'] ?? 0; $host_id = $params['host_id'] ?? 0;
$json = json_encode(get_graph_list($host_id)); $json = (string) json_encode(get_graph_list($host_id));
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -126,14 +126,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$verror = validate_parameters($params, $allowed_automation_networks_filter); $verror = validate_parameters($params, $allowed_automation_networks_filter);
if ($verror) { if ($verror) {
$response->getBody()->write(json_encode($verror)); $response->getBody()->write((string) json_encode($verror));
cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API');
return $response->withStatus(400)->withHeader('Content-Type', 'application/json'); return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
} }
$json = json_encode(get_automation_networks($params)); $json = (string) json_encode(get_automation_networks($params));
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -148,13 +148,13 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$poller_id = $params['poller_id'] ?? 0; $poller_id = $params['poller_id'] ?? 0;
$hosts = get_poller_status($poller_id); $hosts = get_poller_status($poller_id);
$response->getBody()->write(json_encode($hosts)); $response->getBody()->write((string) json_encode($hosts));
return $response->withHeader('Content-Type', 'application/json'); return $response->withHeader('Content-Type', 'application/json');
}); });
$statusGroup->get('/cacti_status', function (Request $request, Response $response) { $statusGroup->get('/cacti_status', function (Request $request, Response $response) {
$json = json_encode(get_cacti_status()); $json = (string) json_encode(get_cacti_status());
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -162,7 +162,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
}); });
$statusGroup->get('/cacti_db_status', function (Request $request, Response $response) { $statusGroup->get('/cacti_db_status', function (Request $request, Response $response) {
$json = json_encode(get_cacti_db_status()); $json = (string) json_encode(get_cacti_db_status());
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -170,7 +170,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
}); });
$statusGroup->get('/boost_status', function (Request $request, Response $response) { $statusGroup->get('/boost_status', function (Request $request, Response $response) {
$json = json_encode(get_boost_status()); $json = (string) json_encode(get_boost_status());
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -178,7 +178,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
}); });
$statusGroup->get('/dsstats', function (Request $request, Response $response) { $statusGroup->get('/dsstats', function (Request $request, Response $response) {
$json = json_encode(get_dsstats_status()); $json = (string) json_encode(get_dsstats_status());
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -189,19 +189,19 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$ping_result = db_fetch_row('SELECT 1 from version'); $ping_result = db_fetch_row('SELECT 1 from version');
if (!$ping_result) { if (!$ping_result) {
$response->getBody()->write(json_encode(['error' => 'Database connection failed'])); $response->getBody()->write((string) json_encode(['error' => 'Database connection failed']));
return $response->withStatus(500)->withHeader('Content-Type', 'application/json'); return $response->withStatus(500)->withHeader('Content-Type', 'application/json');
} }
$response->getBody()->write(json_encode(['status' => 'Database connection test successful'])); $response->getBody()->write((string) json_encode(['status' => 'Database connection test successful']));
return $response->withHeader('Content-Type', 'application/json'); return $response->withHeader('Content-Type', 'application/json');
}); });
// automation status endpoint // automation status endpoint
$statusGroup->get('/automation', function (Request $request, Response $response) { $statusGroup->get('/automation', function (Request $request, Response $response) {
$json = json_encode(get_automation_status()); $json = (string) json_encode(get_automation_status());
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -219,14 +219,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
$verror = validate_parameters($params, $allowed_thold_filter); $verror = validate_parameters($params, $allowed_thold_filter);
if ($verror) { if ($verror) {
$response->getBody()->write(json_encode($verror)); $response->getBody()->write((string) json_encode($verror));
cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API');
return $response->withStatus(400)->withHeader('Content-Type', 'application/json'); return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
} }
$json = json_encode(get_thresholds($params)); $json = (string) json_encode(get_thresholds($params));
$response->getBody()->write($json); $response->getBody()->write($json);
@@ -234,7 +234,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) {
}); });
$tholdGroup->get('/status', function (Request $request, Response $response) { $tholdGroup->get('/status', function (Request $request, Response $response) {
$json = json_encode(get_threshold_status()); $json = (string) json_encode(get_threshold_status());
$response->getBody()->write($json); $response->getBody()->write($json);
+1 -1
View File
@@ -318,7 +318,7 @@ if (isrv('ref')) {
} }
if (!$valid && cacti_sizeof($server_info)) { if (!$valid && cacti_sizeof($server_info)) {
foreach ($server_info as $record) { foreach (($server_info ?: []) as $record) {
if (isset($record['host']) && $record['host'] == $server_ref) { if (isset($record['host']) && $record['host'] == $server_ref) {
$valid = true; $valid = true;
+1 -1
View File
@@ -544,7 +544,7 @@ if (cacti_sizeof($parms)) {
print "Adding $description ($ip) as \"" . $host_templates[$template_id] . "\" using SNMP v$snmp_ver with username \"$snmp_username\"" . PHP_EOL; print "Adding $description ($ip) as \"" . $host_templates[$template_id] . "\" using SNMP v$snmp_ver with username \"$snmp_username\"" . PHP_EOL;
} }
$host_id = api_device_save(0, $template_id, $description, $ip, $host_id = api_device_save(0, (int) $template_id, $description, $ip,
$community, $snmp_ver, $snmp_username, $snmp_password, $community, $snmp_ver, $snmp_username, $snmp_password,
$snmp_port, $snmp_timeout, $disable, $avail, $ping_method, $snmp_port, $snmp_timeout, $disable, $avail, $ping_method,
$ping_port, $ping_timeout, $ping_retries, $notes, $ping_port, $ping_timeout, $ping_retries, $notes,
+2 -2
View File
@@ -429,7 +429,7 @@ if (cacti_sizeof($parms)) {
// process the snmp fields // process the snmp fields
if ($graph_type == 'dq' || $graph_type == 'ds' || $listSNMPFields || $listSNMPValues) { if ($graph_type == 'dq' || $graph_type == 'ds' || $listSNMPFields || $listSNMPValues) {
$snmpFields = getSNMPFields($host_id, $dsGraph['snmpQueryId']); $snmpFields = getSNMPFields($host_id, (int) $dsGraph['snmpQueryId']);
if ($listSNMPFields) { if ($listSNMPFields) {
displaySNMPFields($snmpFields, $host_id, $quietMode); displaySNMPFields($snmpFields, $host_id, $quietMode);
@@ -489,7 +489,7 @@ if (cacti_sizeof($parms)) {
} }
} }
$snmpValues = getSNMPValues($host_id, $snmpField, $dsGraph['snmpQueryId']); $snmpValues = getSNMPValues($host_id, $snmpField, (int) $dsGraph['snmpQueryId']);
$snmpValue = ''; $snmpValue = '';
$snmpValueRegex = ''; $snmpValueRegex = '';
+1 -1
View File
@@ -549,7 +549,7 @@ function fetchCurl(string $url) : string|false {
$buffer = curl_exec($curl); $buffer = curl_exec($curl);
if ($buffer === false) { if (!is_string($buffer)) {
$error = curl_error($curl); $error = curl_error($curl);
echoQuiet('Error: cURL request failed: ' . $error . PHP_EOL); echoQuiet('Error: cURL request failed: ' . $error . PHP_EOL);
+6 -1
View File
@@ -48,7 +48,8 @@ if (cacti_sizeof($parms)) {
$siteId = 0; // The ID of the site to add $siteId = 0; // The ID of the site to add
$sortMethods = ['manual' => 1, 'alpha' => 2, 'natural' => 4, 'numeric' => 3]; $sortMethods = ['manual' => 1, 'alpha' => 2, 'natural' => 4, 'numeric' => 3];
$nodeTypes = ['header' => 1, 'graph' => 2, 'host' => 3]; // 'site' reuses the host type id; api_tree_item_save() only uses the type to gate the title requirement
$nodeTypes = ['header' => 1, 'graph' => 2, 'host' => 3, 'site' => 3];
$hostId = 0; $hostId = 0;
$hostGroupStyle = 1; // 1 = Graph Template, 2 = Data Query Index $hostGroupStyle = 1; // 1 = Graph Template, 2 = Data Query Index
@@ -104,6 +105,10 @@ if (cacti_sizeof($parms)) {
case '--host-id': case '--host-id':
$hostId = intval($value); $hostId = intval($value);
break;
case '--site-id':
$siteId = intval($value);
break; break;
case '--quiet': case '--quiet':
$quietMode = true; $quietMode = true;
+1 -1
View File
@@ -259,7 +259,7 @@ function upgrade_database() : void {
$preorder[] = CACTI_PATH_PLUGINS . '/thold'; $preorder[] = CACTI_PATH_PLUGINS . '/thold';
$preorder[] = CACTI_PATH_PLUGINS . '/syslog'; $preorder[] = CACTI_PATH_PLUGINS . '/syslog';
foreach ($plugins as $p) { foreach (($plugins ?: []) as $p) {
if (str_contains($p, 'thold')) { if (str_contains($p, 'thold')) {
// Skip, upgrading this first // Skip, upgrading this first
} elseif (str_contains($p, 'syslog')) { } elseif (str_contains($p, 'syslog')) {
+5 -1
View File
@@ -260,10 +260,14 @@ if (cacti_sizeof($parms)) {
if (!$quiet) { if (!$quiet) {
$fin = fopen('php://stdin', 'r'); $fin = fopen('php://stdin', 'r');
if ($fin === false) {
exit(1);
}
while (true) { while (true) {
printf(PHP_EOL . 'Precheck completed with no Errors. Do you want to continue [Y|N]? '); printf(PHP_EOL . 'Precheck completed with no Errors. Do you want to continue [Y|N]? ');
$line = cacti_strtolower(trim(fgets($fin))); $line = cacti_strtolower(trim((string) fgets($fin)));
if ($line == 'y') { if ($line == 'y') {
fclose($fin); fclose($fin);
+14 -12
View File
@@ -105,7 +105,7 @@ if (cacti_sizeof($parms)) {
break; break;
case '--child': case '--child':
$thread_id = $value; $thread_id = (int) $value;
break; break;
case '--host-id': case '--host-id':
@@ -197,7 +197,7 @@ if (!is_numeric($end_time)) {
// validate the start and end times are sane // validate the start and end times are sane
if ($start_time >= $end_time) { if ($start_time >= $end_time) {
printf('ERROR: The Start Time \'%s\' is equal or grater to the End Time \'%s\' is not a valid date/time' . PHP_EOL, date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time)); printf('ERROR: The Start Time \'%s\' is equal or grater to the End Time \'%s\' is not a valid date/time' . PHP_EOL, date('Y-m-d H:i:s', (int) $start_time), date('Y-m-d H:i:s', $end_time));
exit(1); exit(1);
} }
@@ -359,6 +359,8 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
$fp = fopen($tmp_file, 'w'); $fp = fopen($tmp_file, 'w');
$lf = false;
if ($seebug) { if ($seebug) {
$lf = fopen(sys_get_temp_dir() . '/cacti_float_rrdfiles.log', 'a'); $lf = fopen(sys_get_temp_dir() . '/cacti_float_rrdfiles.log', 'a');
} }
@@ -378,7 +380,7 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
* <pdp_per_row>24</pdp_per_row> <!-- 7200 seconds --> * <pdp_per_row>24</pdp_per_row> <!-- 7200 seconds -->
* split the database record into pieces * split the database record into pieces
*/ */
$parts = preg_split('/[\s]+/', trim($line)); $parts = preg_split('/[\s]+/', trim($line)) ?: [];
/** /**
* We use this just in case we need to update * We use this just in case we need to update
@@ -397,7 +399,7 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
$line .= PHP_EOL; $line .= PHP_EOL;
} elseif ($in_database) { } elseif ($in_database) {
// split the database record into pieces // split the database record into pieces
$parts = preg_split('/[\s]+/', trim($line)); $parts = preg_split('/[\s]+/', trim($line)) ?: [];
$timestamp = intval($parts[5]); $timestamp = intval($parts[5]);
@@ -413,9 +415,9 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
} elseif ($prev_data != '') { } elseif ($prev_data != '') {
if ($seebug) { if ($seebug) {
if ($step !== false) { if ($step !== false) {
fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s, Step:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time, $step)); is_resource($lf) && fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s, Step:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time, $step));
} else { } else {
fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time)); is_resource($lf) && fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
} }
} }
@@ -427,15 +429,15 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
$nline = $db_prefix . implode(' ', $parts) . ' ' . $prev_data . PHP_EOL; $nline = $db_prefix . implode(' ', $parts) . ' ' . $prev_data . PHP_EOL;
if ($seebug) { if ($seebug) {
fwrite($lf, sprintf('Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time)); is_resource($lf) && fwrite($lf, sprintf('Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n", trim($prev_line), trim($line), trim($nline))); is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n", trim($prev_line), trim($line), trim($nline)));
} }
$line = $nline; $line = $nline;
} else { } else {
if ($seebug) { if ($seebug) {
fwrite($lf, sprintf('Not Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time)); is_resource($lf) && fwrite($lf, sprintf('Not Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line))); is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line)));
} }
$in_range = false; $in_range = false;
@@ -468,7 +470,7 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
} }
if ($seebug) { if ($seebug) {
fclose($lf); is_resource($lf) && fclose($lf);
} }
if ($return == 0) { if ($return == 0) {
@@ -693,7 +695,7 @@ function sig_handler(int $signo) : void {
float_kill_running_processes(); float_kill_running_processes();
} }
unregister_process('rfloat', 'rmaster', $thread_id, getmypid()); unregister_process('rfloat', 'rmaster', $thread_id, (int) getmypid());
exit(1); exit(1);
default: default:
+1 -1
View File
@@ -133,7 +133,7 @@ if (cacti_sizeof($directory)) {
pkg_debug('Processing files'); pkg_debug('Processing files');
if (cacti_sizeof($files)) { if (cacti_sizeof($files)) {
foreach ($files as $file) { foreach (($files ?: []) as $file) {
pkg_debug("Processing file: $file"); pkg_debug("Processing file: $file");
if (is_readable($file)) { if (is_readable($file)) {
+2 -2
View File
@@ -171,9 +171,9 @@ if (cacti_sizeof($parms)) {
$fp = fopen($filename, 'r'); $fp = fopen($filename, 'r');
$data = fread($fp, filesize($filename)); $data = fread($fp, filesize($filename));
fclose($fp); is_resource($fp) && fclose($fp);
print 'Read ' . strlen($data) . ' bytes of Package data' . PHP_EOL; print 'Read ' . strlen((string) $data) . ' bytes of Package data' . PHP_EOL;
$result = import_package($filename, $profile_id, $remove_orphans, $replace_svalues, $preview_only); $result = import_package($filename, $profile_id, $remove_orphans, $replace_svalues, $preview_only);
+2 -2
View File
@@ -125,9 +125,9 @@ if (cacti_sizeof($parms)) {
if (file_exists($filename) && is_readable($filename)) { if (file_exists($filename) && is_readable($filename)) {
$fp = fopen($filename,'r'); $fp = fopen($filename,'r');
$xml_data = fread($fp,filesize($filename)); $xml_data = fread($fp,filesize($filename));
fclose($fp); is_resource($fp) && fclose($fp);
print 'Read ' . strlen($xml_data) . ' bytes of XML data' . PHP_EOL; print 'Read ' . strlen((string) $xml_data) . ' bytes of XML data' . PHP_EOL;
$debug_data = import_xml_data($xml_data, false, $id, $remove_orphans, $replace_svalues); $debug_data = import_xml_data($xml_data, false, $id, $remove_orphans, $replace_svalues);
+2 -2
View File
@@ -103,7 +103,7 @@ if ($audit) {
exit(1); exit(1);
} }
$input = json_decode(file_get_contents($config['input_whitelist']), true); $input = json_decode((string) file_get_contents($config['input_whitelist']), true);
$totals = 0; $totals = 0;
$items = cacti_sizeof($input); $items = cacti_sizeof($input);
@@ -148,7 +148,7 @@ if ($audit) {
WHERE input_string != ""'); WHERE input_string != ""');
if (file_exists($config['input_whitelist'])) { if (file_exists($config['input_whitelist'])) {
$input_ws = json_decode(file_get_contents($config['input_whitelist']), true); $input_ws = json_decode((string) file_get_contents($config['input_whitelist']), true);
} else { } else {
$input_ws = []; $input_ws = [];
} }
+1 -1
View File
@@ -166,7 +166,7 @@ if (!$quiet && $debug) {
} }
try { try {
$file_array = $file_finder->findHashes($base_dir, $ignore_regex, $excluded_directories, $debug_callback); $file_array = $file_finder->findHashes((string) $base_dir, $ignore_regex, $excluded_directories, $debug_callback);
} catch (DirectoryNotFoundException | InvalidArgumentException $e) { } catch (DirectoryNotFoundException | InvalidArgumentException $e) {
printf('ERROR: %s' . PHP_EOL, $e->getMessage()); printf('ERROR: %s' . PHP_EOL, $e->getMessage());
exit(6); exit(6);
+2 -2
View File
@@ -336,7 +336,7 @@ function migrate_all_devices(int $source_poller, int $dest_poller, bool $quietMo
print PHP_EOL; print PHP_EOL;
print 'Are you sure you want to continue? (y/N): '; print 'Are you sure you want to continue? (y/N): ';
$confirmation = trim(fgets(STDIN)); $confirmation = trim((string) fgets(STDIN));
if (cacti_strtolower($confirmation) !== 'y') { if (cacti_strtolower($confirmation) !== 'y') {
print 'Migration cancelled by user' . PHP_EOL; print 'Migration cancelled by user' . PHP_EOL;
@@ -431,7 +431,7 @@ function migrate_from_host_ids(string $host_ids_string, int $source_poller, int
print PHP_EOL; print PHP_EOL;
print 'Are you sure you want to continue? (y/N): '; print 'Are you sure you want to continue? (y/N): ';
$confirmation = trim(fgets(STDIN)); $confirmation = trim((string) fgets(STDIN));
if (cacti_strtolower($confirmation) !== 'y') { if (cacti_strtolower($confirmation) !== 'y') {
print 'Migration cancelled by user' . PHP_EOL; print 'Migration cancelled by user' . PHP_EOL;
+2 -2
View File
@@ -132,7 +132,7 @@ foreach ($parms as $parameter) {
break; break;
case '--child': case '--child':
$thread_id = $value; $thread_id = (int) $value;
break; break;
case '--force': case '--force':
@@ -440,7 +440,7 @@ function sig_handler(int $signo) : void {
reindex_kill_running_processes(); reindex_kill_running_processes();
} }
unregister_process('reindex', 'rmaster', $thread_id, getmypid()); unregister_process('reindex', 'rmaster', $thread_id, (int) getmypid());
exit(1); exit(1);
default: default:
+2 -2
View File
@@ -124,7 +124,7 @@ foreach ($parms as $parameter) {
break; break;
case '--child': case '--child':
$thread_id = $value; $thread_id = (int) $value;
break; break;
case '--force': case '--force':
@@ -398,7 +398,7 @@ function sig_handler(int $signo) : void {
pushout_kill_running_processes(); pushout_kill_running_processes();
} }
unregister_process('pushout' . $rp_type, 'rmaster', $thread_id, getmypid()); unregister_process('pushout' . $rp_type, 'rmaster', $thread_id, (int) getmypid());
exit(1); exit(1);
default: default:
+1 -1
View File
@@ -45,7 +45,7 @@ $columns = 80;
if (CACTI_SERVER_OS == 'unix' && stream_isatty(STDIN)) { if (CACTI_SERVER_OS == 'unix' && stream_isatty(STDIN)) {
$stty = shell_exec('stty size'); $stty = shell_exec('stty size');
$sizes = explode(' ', $stty); $sizes = explode(' ', (string) $stty);
if (!empty($sizes[1])) { if (!empty($sizes[1])) {
$columns = $sizes[1]; $columns = $sizes[1];
+1 -1
View File
@@ -112,7 +112,7 @@ detailed_checks();
snmp_repairs(); snmp_repairs();
snmp_index_repairs(); snmp_index_repairs();
if (cacti_sizeof($repaired_hosts) && $total_repairs > 0) { // @phpstan-ignore booleanAnd.alwaysFalse if (cacti_sizeof($repaired_hosts) && $total_repairs > 0) {
print_separator(true); print_separator(true);
printf('NOTE: Pushing out %s Devices after repairs!' . PHP_EOL . PHP_EOL, cacti_sizeof($repaired_hosts)); printf('NOTE: Pushing out %s Devices after repairs!' . PHP_EOL . PHP_EOL, cacti_sizeof($repaired_hosts));
+4 -4
View File
@@ -237,7 +237,7 @@ $known_ds_types = [1 => 'GAUGE', 2 => 'COUNTER', 3 => 'DERIVE', 4 => 'ABSOLUTE']
if ($scanned_directory['folders']) { if ($scanned_directory['folders']) {
// create backup folder // create backup folder
if (!mkdir($tmp_backup_folder)) { if (!mkdir((string) $tmp_backup_folder)) {
print 'ERROR: Unable to create a backup folder!' . PHP_EOL; print 'ERROR: Unable to create a backup folder!' . PHP_EOL;
exit(1); exit(1);
@@ -556,7 +556,7 @@ if ($scanned_directory['folders']) {
// ## log_missing // ## log_missing
continue; continue;
} else { } else {
$rrd_data = json_decode(json_encode(simplexml_load_string($file_dump)), true); $rrd_data = json_decode((string) json_encode(simplexml_load_string($file_dump)), true);
if ($rrd_data === false) { if ($rrd_data === false) {
f_notify(false, "\033[0;31m[FAILED]\033[0m"); f_notify(false, "\033[0;31m[FAILED]\033[0m");
@@ -939,7 +939,7 @@ function rrdtool_parse_info(string $lines) : array {
$key_count = count($keys); $key_count = count($keys);
$pointer = &$store; $pointer = &$store;
foreach ($keys as $key_num => $key) { foreach (($keys ?: []) as $key_num => $key) {
$pointer = &$pointer[$key]; $pointer = &$pointer[$key];
if ($key_num + 1 === $key_count) { if ($key_num + 1 === $key_count) {
@@ -978,7 +978,7 @@ function rrdtool_pipe_execute(string $command, mixed $pipes) : string {
$line = fgets($pipes[1], 8092); $line = fgets($pipes[1], 8092);
// return the complete output cause the logic behind a proxy should be as simple as possible // return the complete output cause the logic behind a proxy should be as simple as possible
if (substr_count($line, 'OK u')) { if (substr_count((string) $line, 'OK u')) {
break; break;
} }
$stdout .= $line; $stdout .= $line;
+1 -1
View File
@@ -84,7 +84,7 @@ $perms = db_get_permissions(true);
$count = 0; $count = 0;
if ($output_json) { if ($output_json) {
print cacti_strtolower(json_encode($perms, JSON_PRETTY_PRINT)); print cacti_strtolower((string) json_encode($perms, JSON_PRETTY_PRINT));
} else { } else {
if ($output_grants) { if ($output_grants) {
$pad = str_repeat('-', 20); $pad = str_repeat('-', 20);
+3 -3
View File
@@ -272,8 +272,8 @@ if (!file_exists($rrdtool)) {
$response = shell_exec(cacti_escapeshellcmd($rrdtool)); $response = shell_exec(cacti_escapeshellcmd($rrdtool));
if (strlen($response)) { if (strlen((string) $response)) {
$response_array = explode(' ', $response); $response_array = explode(' ', (string) $response);
print 'NOTE: Using ' . $response_array[0] . ' Version ' . $response_array[1] . PHP_EOL; print 'NOTE: Using ' . $response_array[0] . ' Version ' . $response_array[1] . PHP_EOL;
} else { } else {
print 'FATAL: RRDTool not found in configuration or path.' . PHP_EOL . 'Please insure RRDTool can be found using one of these methods!' . PHP_EOL; print 'FATAL: RRDTool not found in configuration or path.' . PHP_EOL . 'Please insure RRDTool can be found using one of these methods!' . PHP_EOL;
@@ -815,7 +815,7 @@ function processXML(array &$output) : array {
if (cacti_sizeof($output)) { if (cacti_sizeof($output)) {
foreach ($output as $line) { foreach ($output as $line) {
if (substr_count($line, '<row>')) { if (substr_count($line, '<row>')) {
$line = trim(str_replace('<row>', '', str_replace('</row>', '', $line))); $line = trim(str_replace('<row>', '', str_replace('</row>', '', (string) $line)));
$larray = explode('<v>', $line); $larray = explode('<v>', $line);
$time = trim(str_replace('<date>', '', str_replace('</date>', '', $larray[0]))); $time = trim(str_replace('<date>', '', str_replace('</date>', '', $larray[0])));
+1 -1
View File
@@ -351,7 +351,7 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
} else { } else {
$output = fgets($pipes[1], 1024); $output = fgets($pipes[1], 1024);
if (substr_count($output, 'Started') != 0) { if (substr_count((string) $output, 'Started') != 0) {
cacti_log('PHP Script Server Started Properly', $print_data_to_stdout, 'POLLER', POLLER_VERBOSITY_HIGH); cacti_log('PHP Script Server Started Properly', $print_data_to_stdout, 'POLLER', POLLER_VERBOSITY_HIGH);
} }
+1 -1
View File
@@ -473,7 +473,7 @@ function profile_validate_upload() : bool {
return false; return false;
} }
return json_decode(file_get_contents($_FILES['import_file']['tmp_name']), true); return json_decode((string) file_get_contents($_FILES['import_file']['tmp_name']), true);
} }
raise_message('nfu2', __('No file uploaded.'), MESSAGE_LEVEL_ERROR); raise_message('nfu2', __('No file uploaded.'), MESSAGE_LEVEL_ERROR);
+2 -2
View File
@@ -206,9 +206,9 @@ if ($output !== false && $output != '') {
} }
if (isset($graph_data_array['graph_width']) && isset($graph_data_array['graph_height'])) { if (isset($graph_data_array['graph_width']) && isset($graph_data_array['graph_height'])) {
$image = rrdtool_create_error_image($error, $graph_data_array['graph_width'], $graph_data_array['graph_height']); $image = rrdtool_create_error_image((string) $error, $graph_data_array['graph_width'], $graph_data_array['graph_height']);
} else { } else {
$image = rrdtool_create_error_image($error); $image = rrdtool_create_error_image((string) $error);
} }
ob_end_clean(); ob_end_clean();
+7 -7
View File
@@ -202,11 +202,11 @@ if ($output !== false && $output != '') {
} }
// Check for additional data points from graphv output // Check for additional data points from graphv output
$graph_start_pos = strpos($output, 'graph_start =', $image_begin_pos); $graph_start_pos = strpos($output, 'graph_start =', (int) $image_begin_pos);
if (!$graph_start_pos) { if (!$graph_start_pos) {
// Find the end of the line of the image definition row, after this the raw image data will come // Find the end of the line of the image definition row, after this the raw image data will come
$image_data_line_end = strpos($output, "\n", $image_begin_pos); $image_data_line_end = strpos($output, "\n", (int) $image_begin_pos);
if ($image_data_line_end !== false) { if ($image_data_line_end !== false) {
$image_data_pos = $image_data_line_end + 1; $image_data_pos = $image_data_line_end + 1;
@@ -216,7 +216,7 @@ if ($output !== false && $output != '') {
} }
} else { } else {
// Find the end of the line of the image definition row, after this the raw image data will come // Find the end of the line of the image definition row, after this the raw image data will come
$image_data_line_end = strpos($output, "\n", $image_begin_pos); $image_data_line_end = strpos($output, "\n", (int) $image_begin_pos);
if ($image_data_line_end !== false) { if ($image_data_line_end !== false) {
$image_data_pos = $image_data_line_end + 1; $image_data_pos = $image_data_line_end + 1;
@@ -314,9 +314,9 @@ if ($output !== false && $output != '') {
} }
if (isset($graph_data_array['graph_width']) && isset($graph_data_array['graph_height'])) { if (isset($graph_data_array['graph_width']) && isset($graph_data_array['graph_height'])) {
$image = rrdtool_create_error_image($error, $graph_data_array['graph_width'], $graph_data_array['graph_height']); $image = rrdtool_create_error_image((string) $error, $graph_data_array['graph_width'], $graph_data_array['graph_height']);
} else { } else {
$image = rrdtool_create_error_image($error); $image = rrdtool_create_error_image((string) $error);
} }
if (isset($graph_data_array['graph_width'])) { if (isset($graph_data_array['graph_width'])) {
@@ -342,12 +342,12 @@ if ($output !== false && $output != '') {
if ($image != false) { if ($image != false) {
$oarray['image'] = base64_encode($image); $oarray['image'] = base64_encode($image);
} else { } else {
$oarray['image'] = base64_encode(file_get_contents(__DIR__ . '/images/cacti_error_image.png')); $oarray['image'] = base64_encode((string) file_get_contents(__DIR__ . '/images/cacti_error_image.png'));
} }
} }
header('Content-Type: application/json'); header('Content-Type: application/json');
header('Cache-Control: max-age=15'); header('Cache-Control: max-age=15');
$json = json_encode($oarray); $json = json_encode($oarray);
header('Content-Length: ' . strlen($json)); header('Content-Length: ' . strlen((string) $json));
print $json; print $json;
+1 -1
View File
@@ -321,7 +321,7 @@ switch (grv('action')) {
$graph_rrd = read_config_option('realtime_cache_path') . '/user_' . hash('sha256',session_id()) . '_lgi_' . grv('local_graph_id') . '.png'; $graph_rrd = read_config_option('realtime_cache_path') . '/user_' . hash('sha256',session_id()) . '_lgi_' . grv('local_graph_id') . '.png';
if (file_exists($graph_rrd)) { if (file_exists($graph_rrd)) {
print base64_encode(file_get_contents($graph_rrd)); print base64_encode((string) file_get_contents($graph_rrd));
} }
exit; exit;
+4 -4
View File
@@ -625,7 +625,7 @@ function host_export() : void {
if (cacti_sizeof($hosts)) { if (cacti_sizeof($hosts)) {
$columns = array_keys($hosts[0]); $columns = array_keys($hosts[0]);
fputcsv($stdout, $columns); is_resource($stdout) && fputcsv($stdout, $columns);
foreach ($hosts as $h) { foreach ($hosts as $h) {
// Flatten embedded newlines as the previous export format did, then // Flatten embedded newlines as the previous export format did, then
@@ -641,11 +641,11 @@ function host_export() : void {
$h[$hc] = $v; $h[$hc] = $v;
} }
fputcsv($stdout, $h); is_resource($stdout) && fputcsv($stdout, $h);
} }
} }
fclose($stdout); is_resource($stdout) && fclose($stdout);
} }
function host_add_query() : void { function host_add_query() : void {
@@ -1533,7 +1533,7 @@ function get_device_records(int &$total_rows, int $rows) : mixed {
"(host.status = ? OR (status != 2 "(host.status = ? OR (status != 2
AND thold_failure_count > 0 AND thold_failure_count > 0
AND status_event_count >= thold_failure_count) AND status_event_count >= thold_failure_count)
AND NOT $host_where_disabled)"; // @phpstan-ignore-line AND NOT $host_where_disabled)";
$sql_params[] = $status; $sql_params[] = $status;
} else { } else {
+1 -1
View File
@@ -726,7 +726,7 @@ define('CACTI_VERSION_BRIEF', get_cacti_version_text(false, CACTI_VERSION));
define('CACTI_VERSION_BRIEF_FULL', get_cacti_version_text(false, CACTI_VERSION_FULL)); define('CACTI_VERSION_BRIEF_FULL', get_cacti_version_text(false, CACTI_VERSION_FULL));
define('CACTI_VERSION_TEXT', get_cacti_version_text(true, CACTI_VERSION)); define('CACTI_VERSION_TEXT', get_cacti_version_text(true, CACTI_VERSION));
define('CACTI_VERSION_TEXT_FULL', get_cacti_version_text(true, CACTI_VERSION_FULL)); define('CACTI_VERSION_TEXT_FULL', get_cacti_version_text(true, CACTI_VERSION_FULL));
define('CACTI_VERSION_TEXT_CLI', get_cacti_cli_version(true, CACTI_VERSION_FULL)); // @phpstan-ignore-line define('CACTI_VERSION_TEXT_CLI', get_cacti_cli_version(true, CACTI_VERSION_FULL));
require_once(CACTI_PATH_LIBRARY . '/auth.php'); require_once(CACTI_PATH_LIBRARY . '/auth.php');
require_once(CACTI_PATH_LIBRARY . '/plugins.php'); require_once(CACTI_PATH_LIBRARY . '/plugins.php');
+1 -1
View File
@@ -1087,7 +1087,7 @@ function number_format_i18n(mixed $number, mixed $decimals = null, mixed $baseu
cacti_log('DEBUG: Number format \'' . $fmt_key . '\' was unavailable, using older methods', false, 'i18n', POLLER_VERBOSITY_HIGH); cacti_log('DEBUG: Number format \'' . $fmt_key . '\' was unavailable, using older methods', false, 'i18n', POLLER_VERBOSITY_HIGH);
} }
$origlocales = explode(';', setlocale(LC_ALL, null)); $origlocales = explode(';', (string) setlocale(LC_ALL, null));
setlocale(LC_ALL, $cacti_locale); setlocale(LC_ALL, $cacti_locale);
$locale = localeconv(); $locale = localeconv();
+9 -6
View File
@@ -56,15 +56,18 @@ global $weekly_timespans, $yearly_timespans;
// Workaround End // Workaround End
while (false !== ($entry = $dir->read())) { if ($dir !== false) {
if ($entry != '.' && $entry != '..') { while (false !== ($entry = $dir->read())) {
if (is_dir(CACTI_PATH_INCLUDE . '/themes/' . $entry)) { if ($entry != '.' && $entry != '..') {
$themes[$entry] = __(ucwords($entry)); if (is_dir(CACTI_PATH_INCLUDE . '/themes/' . $entry)) {
$themes[$entry] = __(ucwords($entry));
}
} }
} }
asort($themes);
$dir->close();
} }
asort($themes);
$dir->close();
// tab information // tab information
$tabs = [ $tabs = [
+1 -1
View File
@@ -128,7 +128,7 @@ function cacti_db_session_destroy(string $id) : bool {
return true; return true;
} }
function cacti_db_session_clean(mixed $max) : bool { // @phpstan-ignore argument.type function cacti_db_session_clean(mixed $max) : bool {
if (!is_numeric($max)) { if (!is_numeric($max)) {
$old = time() - 14400; $old = time() - 14400;
} else { } else {
+1 -1
View File
@@ -68,7 +68,7 @@ if (CACTI_SERVER_OS == 'unix') {
} elseif (file_exists('/etc/os-release')) { } elseif (file_exists('/etc/os-release')) {
$contents = file_get_contents('/etc/os-release'); $contents = file_get_contents('/etc/os-release');
if (stripos($contents, 'debian') !== false || stripos($contents, 'ubuntu')) { if (stripos((string) $contents, 'debian') !== false || stripos((string) $contents, 'ubuntu')) {
$help = 'Installing-Under-Ubuntu-Debian.html'; $help = 'Installing-Under-Ubuntu-Debian.html';
} }
} }
+2 -2
View File
@@ -79,7 +79,7 @@ if (isset($initialData['step']) && $initialData['step'] == Installer::STEP_TEST_
} }
} }
$response = json_decode($json, true); $response = json_decode((string) $json, true);
if (is_array($response)) { if (is_array($response)) {
$response['csrfMagicToken'] = csrf_get_tokens(); $response['csrfMagicToken'] = csrf_get_tokens();
@@ -94,5 +94,5 @@ log_install_high('json',' End: ' . clean_up_lines($json_debug) . PHP_EOL);
header('Content-Type: application/json'); header('Content-Type: application/json');
header('Cache-Control: no-store'); header('Cache-Control: no-store');
header('X-Content-Type-Options: nosniff'); header('X-Content-Type-Options: nosniff');
header('Content-Length: ' . strlen($json)); header('Content-Length: ' . strlen((string) $json));
print $json; print $json;
+1 -1
View File
@@ -1025,7 +1025,7 @@ function auto_title(int $_local_graph_id) : string {
// remove all '- |host_*|' occurrences // remove all '- |host_*|' occurrences
$pattern = '/-?\s+\|host_\w+\|/'; $pattern = '/-?\s+\|host_\w+\|/';
$graph_title = preg_replace($pattern, '', $graph_title); $graph_title = preg_replace($pattern, '', (string) $graph_title);
cacti_log('title:' . $graph_title, true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG); cacti_log('title:' . $graph_title, true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
+10 -10
View File
@@ -1815,7 +1815,7 @@ function build_graph_object_sql_having(array $rule, string $filter) : string {
$i = 0; $i = 0;
foreach ($field_names as $column) { foreach (($field_names ?: []) as $column) {
/* The name becomes an identifier in the generated SQL, and it /* The name becomes an identifier in the generated SQL, and it
* arrives from snmp_query_field, which a data query XML import * arrives from snmp_query_field, which a data query XML import
* populates. A backtick in it would close the quoting the * populates. A backtick in it would close the quoting the
@@ -1881,7 +1881,7 @@ function build_data_query_sql(array $rule) : string {
$sql_query = "\n\tSELECT h.hostname AS automation_host, host_id, \n\th.disabled, $sdisabled \n\th.status, snmp_query_id, snmp_index "; $sql_query = "\n\tSELECT h.hostname AS automation_host, host_id, \n\th.disabled, $sdisabled \n\th.status, snmp_query_id, snmp_index ";
if (cacti_sizeof($field_names) > 0) { if (cacti_sizeof($field_names) > 0) {
foreach ($field_names as $column) { foreach (($field_names ?: []) as $column) {
$field_name = $column['field_name']; $field_name = $column['field_name'];
$sql_query .= ",\n\tMAX(CASE WHEN field_name='$field_name' THEN field_value ELSE NULL END) AS '$field_name'"; $sql_query .= ",\n\tMAX(CASE WHEN field_name='$field_name' THEN field_value ELSE NULL END) AS '$field_name'";
} }
@@ -2089,9 +2089,9 @@ function build_sort_order(string $index_order, string $default_order = '') : str
* @param int $rule_type The type of rule to apply. * @param int $rule_type The type of rule to apply.
* @param string $sql_where Optional SQL WHERE clause to filter the results. * @param string $sql_where Optional SQL WHERE clause to filter the results.
* *
* @return array|bool - The list of matching hosts. * @return array The list of matching hosts.
*/ */
function get_matching_hosts(array $rule, int $rule_type, string $sql_where = '') : array|bool { function get_matching_hosts(array $rule, int $rule_type, string $sql_where = '') : array {
$function = automation_function_with_pid(__FUNCTION__); $function = automation_function_with_pid(__FUNCTION__);
cacti_log($function . ' called: ' . json_encode($rule) . ' type: ' . $rule_type, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); cacti_log($function . ' called: ' . json_encode($rule) . ' type: ' . $rule_type, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH);
@@ -2144,9 +2144,9 @@ function get_matching_hosts(array $rule, int $rule_type, string $sql_where = '')
* @param int $rule_type The type of rule to apply. * @param int $rule_type The type of rule to apply.
* @param string $sql_where Optional SQL WHERE clause to further filter the results. * @param string $sql_where Optional SQL WHERE clause to further filter the results.
* *
* @return array|bool The list of matching graphs. * @return array The list of matching graphs.
*/ */
function get_matching_graphs(array $rule, int $rule_type, string $sql_where = '') : array|bool { function get_matching_graphs(array $rule, int $rule_type, string $sql_where = '') : array {
$function = automation_function_with_pid(__FUNCTION__); $function = automation_function_with_pid(__FUNCTION__);
cacti_log($function . ' called: ' . json_encode($rule) . ' type: ' . $rule_type, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); cacti_log($function . ' called: ' . json_encode($rule) . ' type: ' . $rule_type, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH);
@@ -2360,9 +2360,9 @@ function get_query_fields(string $table, array $excluded_fields) : array {
* *
* @param string $snmp_query_id The ID of the SNMP query for which to retrieve field names. * @param string $snmp_query_id The ID of the SNMP query for which to retrieve field names.
* *
* @return array|bool An array of field names associated with the specified SNMP query ID. * @return array An array of field names associated with the specified SNMP query ID.
*/ */
function get_field_names(string $snmp_query_id) : array|bool { function get_field_names(string $snmp_query_id) : array {
$function = automation_function_with_pid(__FUNCTION__); $function = automation_function_with_pid(__FUNCTION__);
cacti_log($function . " called: $snmp_query_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); cacti_log($function . " called: $snmp_query_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH);
@@ -5363,8 +5363,8 @@ function automation_tree_rule_export(mixed $tree_rule_ids) : array {
unset($tree_rule['id']); unset($tree_rule['id']);
// pick up the tree and branch name as they may not be on the foreign system // pick up the tree and branch name as they may not be on the foreign system
$tree_rule['tree_data'] = db_fetch_row_prepared('SELECT name, sort_type FROM graph_tree WHERE id = ?', [$tree_rule['tree_id']]); // @phpstan-ignore-line $tree_rule['tree_data'] = db_fetch_row_prepared('SELECT name, sort_type FROM graph_tree WHERE id = ?', [$tree_rule['tree_id']]);
$tree_rule['tree_branch_data'] = automation_device_rule_export_branches($tree_rule['tree_id'], $tree_rule['tree_item_id']); // @phpstan-ignore-line $tree_rule['tree_branch_data'] = automation_device_rule_export_branches($tree_rule['tree_id'], $tree_rule['tree_item_id']);
// collapse the graph rule items // collapse the graph rule items
$tree_rule['tree_rule_items'] = $tree_rule_items; $tree_rule['tree_rule_items'] = $tree_rule_items;
+5 -5
View File
@@ -1282,8 +1282,8 @@ function api_device_save(int $id, int $device_template_id, string $description,
$owner_id = fileowner(CACTI_PATH_RRA); $owner_id = fileowner(CACTI_PATH_RRA);
$group_id = filegroup(CACTI_PATH_RRA); $group_id = filegroup(CACTI_PATH_RRA);
if ((chown($host_dir, $owner_id)) && if ($owner_id !== false && $group_id !== false &&
(chgrp($host_dir, $group_id))) { chown($host_dir, $owner_id) && chgrp($host_dir, $group_id)) {
// permissions set ok // permissions set ok
} else { } else {
cacti_log("ERROR: Unable to set directory permissions for '" . $host_dir . "'", false); cacti_log("ERROR: Unable to set directory permissions for '" . $host_dir . "'", false);
@@ -3373,7 +3373,7 @@ function api_device_template_archive_for_export(int $id) : mixed {
if (cacti_sizeof($files)) { if (cacti_sizeof($files)) {
foreach ($files as $file) { foreach ($files as $file) {
if (str_contains($file['file'], '.xml')) { if (str_contains($file['file'], '.xml')) {
$files = array_merge($files, find_dependent_files(file_get_contents($file['file']))); $files = array_merge($files, find_dependent_files((string) file_get_contents($file['file'])));
} }
} }
} }
@@ -3456,7 +3456,7 @@ function api_device_template_archive(int $id, string $archive_note) : bool {
if (cacti_sizeof($files)) { if (cacti_sizeof($files)) {
foreach ($files as $file) { foreach ($files as $file) {
if (str_contains($file['file'], '.xml')) { if (str_contains($file['file'], '.xml')) {
$files = array_merge($files, find_dependent_files(file_get_contents($file['file']))); $files = array_merge($files, find_dependent_files((string) file_get_contents($file['file'])));
} }
} }
} }
@@ -3470,7 +3470,7 @@ function api_device_template_archive(int $id, string $archive_note) : bool {
} }
if ($package_file != '' && file_exists($package_file)) { if ($package_file != '' && file_exists($package_file)) {
$archive = base64_encode(file_get_contents($package_file)); $archive = base64_encode((string) file_get_contents($package_file));
$md5sum = md5($archive); $md5sum = md5($archive);
db_execute_prepared('INSERT INTO host_template_archive db_execute_prepared('INSERT INTO host_template_archive
+1 -1
View File
@@ -402,7 +402,7 @@ function api_scheduler_augment_save(array $save, array $post) : array {
$timestamp += 86400; $timestamp += 86400;
} }
$save['next_start'] = date('Y-m-d H:i:s', $timestamp); $save['next_start'] = date('Y-m-d H:i:s', (int) $timestamp);
} else { } else {
// the time is in the future, we are safe to store it // the time is in the future, we are safe to store it
$save['next_start'] = date('Y-m-d H:i:s', $start_at); $save['next_start'] = date('Y-m-d H:i:s', $start_at);
+1
View File
@@ -882,6 +882,7 @@ int $host_id, int $site_id, int $host_grouping_type, int $sort_children_type, bo
$save['parent'] = $parent_tree_item_id; $save['parent'] = $parent_tree_item_id;
$save['local_graph_id'] = form_input_validate($local_graph_id, 'local_graph_id', '', true, 3); $save['local_graph_id'] = form_input_validate($local_graph_id, 'local_graph_id', '', true, 3);
$save['host_id'] = form_input_validate($host_id, 'host_id', '', true, 3); $save['host_id'] = form_input_validate($host_id, 'host_id', '', true, 3);
$save['site_id'] = form_input_validate($site_id, 'site_id', '^[-0-9]+$', true, 3);
$save['host_grouping_type'] = form_input_validate($host_grouping_type, 'host_grouping_type', '', true, 3); $save['host_grouping_type'] = form_input_validate($host_grouping_type, 'host_grouping_type', '', true, 3);
$save['sort_children_type'] = form_input_validate($sort_children_type, 'sort_children_type', '', true, 3); $save['sort_children_type'] = form_input_validate($sort_children_type, 'sort_children_type', '', true, 3);
+2 -2
View File
@@ -420,7 +420,7 @@ function get_basic_auth_username() : string|false {
$found = false; $found = false;
if (cacti_sizeof($records)) { if (cacti_sizeof($records)) {
foreach ($records as $r) { foreach (($records ?: []) as $r) {
if (trim($r) === '') { if (trim($r) === '') {
continue; continue;
} }
@@ -5201,7 +5201,7 @@ function remote_agent_validate_effective_user(mixed $value, ?callable $lookup =
return false; return false;
} }
$lookup ??= static fn (int $id) : array|false => db_fetch_row_prepared( $lookup ??= static fn (int $id) : array => db_fetch_row_prepared(
'SELECT id, enabled 'SELECT id, enabled
FROM user_auth FROM user_auth
WHERE id = ?', WHERE id = ?',
+3 -3
View File
@@ -1777,7 +1777,7 @@ function boost_process_poller_output(int $local_data_id, mixed $rrdtool_pipe = [
$multi_ok = false; $multi_ok = false;
if (cacti_sizeof($values)) { if (cacti_sizeof($values)) {
foreach ($values as $value) { foreach (($values ?: []) as $value) {
$matches = explode(':', $value); $matches = explode(':', $value);
if (isset($rrd_field_names[$matches[0]])) { if (isset($rrd_field_names[$matches[0]])) {
@@ -2330,11 +2330,11 @@ function boost_rrdtool_function_create(int $local_data_id, bool $show_source, mi
$pgroup_id = fileowner(CACTI_PATH_RRA . $spath); $pgroup_id = fileowner(CACTI_PATH_RRA . $spath);
if ($powner_id != $owner_id) { if ($powner_id != $owner_id) {
$success = chown(CACTI_PATH_RRA . $spath, $owner_id); $success = $owner_id !== false && chown(CACTI_PATH_RRA . $spath, $owner_id);
} }
if ($pgroup_id != $group_id && $success) { if ($pgroup_id != $group_id && $success) {
$success = chgrp(CACTI_PATH_RRA . $spath, $group_id); $success = $group_id !== false && chgrp(CACTI_PATH_RRA . $spath, $group_id);
} }
if (!$success) { if (!$success) {
+7 -3
View File
@@ -181,11 +181,15 @@ function clog_purge_logfile(string $action = 'purge') : void {
$log_fh = fopen($logfile, 'w'); $log_fh = fopen($logfile, 'w');
fclose($log_fh); if (is_resource($log_fh)) {
fclose($log_fh);
raise_message('clog_removed', $imessage, MESSAGE_LEVEL_INFO); raise_message('clog_removed', $imessage, MESSAGE_LEVEL_INFO);
cacti_log($message, false, 'WEBUI'); cacti_log($message, false, 'WEBUI');
} else {
raise_message('clog_removed', __('Unable to open log file \'%s\' for writing.', basename($logfile)), MESSAGE_LEVEL_ERROR);
}
} }
} else { } else {
raise_message('clog_permissions'); raise_message('clog_permissions');
+2 -2
View File
@@ -62,8 +62,8 @@ function csp_report_sanitize_field($v): string {
// Strip CR/LF and other C0 controls; truncate to 256 chars for log sanity. // Strip CR/LF and other C0 controls; truncate to 256 chars for log sanity.
$v = preg_replace('/[\x00-\x1f\x7f]/', ' ', $v); $v = preg_replace('/[\x00-\x1f\x7f]/', ' ', $v);
if (strlen($v) > 256) { if (strlen((string) $v) > 256) {
$v = substr($v, 0, 253) . '...'; $v = substr((string) $v, 0, 253) . '...';
} }
return $v; return $v;
+8 -8
View File
@@ -1330,7 +1330,7 @@ function query_snmp_host(int $host_id, int $snmp_query_id) : bool {
} elseif (str_starts_with($field_array['source'], 'OID2HEX/REGEXP:')) { } elseif (str_starts_with($field_array['source'], 'OID2HEX/REGEXP:')) {
$value = preg_replace('/' . str_replace('OID2HEX/REGEXP:', '', $field_array['source']) . '/', '\\1', $oid); $value = preg_replace('/' . str_replace('OID2HEX/REGEXP:', '', $field_array['source']) . '/', '\\1', $oid);
$parts = explode('.', $value); $parts = explode('.', (string) $value);
$ip_value = ''; $ip_value = '';
foreach ($parts as $idx => $part) { foreach ($parts as $idx => $part) {
@@ -1350,7 +1350,7 @@ function query_snmp_host(int $host_id, int $snmp_query_id) : bool {
// Check for ip address and shorten // Check for ip address and shorten
if (is_ipaddress($ip_value)) { if (is_ipaddress($ip_value)) {
$value = inet_ntop(inet_pton($ip_value)); $value = inet_ntop((string) inet_pton($ip_value));
} }
} }
@@ -1412,7 +1412,7 @@ function query_snmp_host(int $host_id, int $snmp_query_id) : bool {
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
if (str_starts_with($field_array['source'], 'VALUE/REGEXP:')) { if (str_starts_with($field_array['source'], 'VALUE/REGEXP:')) {
$values[$key]['value'] = preg_replace('/' . str_replace('VALUE/REGEXP:', '', $field_array['source']) . '/', '\\1', $values[$key]['value']); $values[$key]['value'] = preg_replace('/' . str_replace('VALUE/REGEXP:', '', $field_array['source']) . '/', '\\1', (string) $values[$key]['value']);
} }
} }
} }
@@ -1662,7 +1662,7 @@ function query_snmp_host(int $host_id, int $snmp_query_id) : bool {
// Check for ip address and shorten // Check for ip address and shorten
if (is_ipaddress($ip_value)) { if (is_ipaddress($ip_value)) {
$parse_value = inet_ntop(inet_pton($ip_value)); $parse_value = inet_ntop((string) inet_pton($ip_value));
} }
debug_log_insert('data_query', __esc('Found item [%s=\'%s\'] index: %s [from regexp oid parse]', $field_name, $parse_value, $snmp_index)); debug_log_insert('data_query', __esc('Found item [%s=\'%s\'] index: %s [from regexp oid parse]', $field_name, $parse_value, $snmp_index));
@@ -1747,8 +1747,8 @@ function data_query_format_record(int $host_id, int $snmp_query_id, string $fiel
$data_query_rewrite_indexes_cache[$hash][$snmp_index] = $value; $data_query_rewrite_indexes_cache[$hash][$snmp_index] = $value;
if (mb_detect_encoding($value, mb_detect_order(), true) === false) { if (mb_detect_encoding((string) $value, mb_detect_order(), true) === false) {
$value = bin2hex($value); $value = bin2hex((string) $value);
} }
return "($host_id, $snmp_query_id, " . db_qstr($field_name) . ', ' . db_qstr($value) . ', ' . db_qstr($snmp_index) . ', ' . db_qstr($oid) . ', 1)'; return "($host_id, $snmp_query_id, " . db_qstr($field_name) . ', ' . db_qstr($value) . ', ' . db_qstr($snmp_index) . ', ' . db_qstr($oid) . ', 1)';
@@ -2023,7 +2023,7 @@ function rewrite_snmp_enum_value(string|null $field_name, string|null $value = n
foreach ($mapcache[$field_name] as $src => $dst) { foreach ($mapcache[$field_name] as $src => $dst) {
if (preg_match($src, $value)) { if (preg_match($src, $value)) {
$nvalue = preg_replace($src, $dst, $value); $nvalue = preg_replace($src, $dst, (string) $value);
debug_log_insert('data_query', __esc("rewrite_value: '%s' => '%s'", $value, $nvalue)); debug_log_insert('data_query', __esc("rewrite_value: '%s' => '%s'", $value, $nvalue));
$value = $nvalue; $value = $nvalue;
@@ -2799,7 +2799,7 @@ function get_script_query_path(string $args, string $script_path, int $host_id)
$extra_arguments = ''; $extra_arguments = '';
foreach ($parts as $index => $part) { foreach (($parts ?: []) as $index => $part) {
/* only the hostname/IP placeholders are stripped of '%'; SNMP /* only the hostname/IP placeholders are stripped of '%'; SNMP
* community and credential substitutions may legitimately * community and credential substitutions may legitimately
* contain one, so they keep their value unmodified. */ * contain one, so they keep their value unmodified. */
+10 -10
View File
@@ -1001,7 +1001,7 @@ function db_fetch_insert_id(mixed $db_conn = false) : mixed {
} }
} }
if (is_object($db_conn)) { if ($db_conn instanceof PDO) {
return $db_conn->lastInsertId(); return $db_conn->lastInsertId();
} }
@@ -1442,7 +1442,7 @@ function db_cacti_initialized(bool $is_web = true) : bool {
$db_conn = false; $db_conn = false;
} }
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
return false; return false;
} }
@@ -2123,12 +2123,12 @@ function db_begin_transaction(mixed $db_conn = false) : bool {
global $database_sessions, $database_default, $database_hostname, $database_port; global $database_sessions, $database_default, $database_hostname, $database_port;
// check for a connection being passed, if not use legacy behavior // check for a connection being passed, if not use legacy behavior
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) { if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
} }
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
return false; return false;
} }
} }
@@ -2147,12 +2147,12 @@ function db_commit_transaction(mixed $db_conn = false) : bool {
global $database_sessions, $database_default, $database_hostname, $database_port; global $database_sessions, $database_default, $database_hostname, $database_port;
// check for a connection being passed, if not use legacy behavior // check for a connection being passed, if not use legacy behavior
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) { if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
} }
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
return false; return false;
} }
} }
@@ -2179,12 +2179,12 @@ function db_rollback_transaction(mixed $db_conn = false) : bool {
global $database_sessions, $database_default, $database_hostname, $database_port; global $database_sessions, $database_default, $database_hostname, $database_port;
// check for a connection being passed, if not use legacy behavior // check for a connection being passed, if not use legacy behavior
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) { if (isset($database_sessions["$database_hostname:$database_port:$database_default"])) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
} }
if (!is_object($db_conn)) { if (!($db_conn instanceof PDO)) {
return false; return false;
} }
} }
@@ -2465,7 +2465,7 @@ function db_qstr(mixed $s, mixed $db_conn = false) : string {
return 'NULL'; return 'NULL';
} }
if (is_object($db_conn)) { if ($db_conn instanceof PDO) {
return $db_conn->quote($s); return $db_conn->quote($s);
} }
@@ -2865,7 +2865,7 @@ function db_get_permissions(bool $include_unknown = false, bool $log = false, mi
$db_grant_perms = preg_split('/,[ ]*/', $db_grant_match[1]); $db_grant_perms = preg_split('/,[ ]*/', $db_grant_match[1]);
if (cacti_sizeof($db_grant_perms)) { if (cacti_sizeof($db_grant_perms)) {
foreach ($db_grant_perms as $db_grant_perm) { foreach (($db_grant_perms ?: []) as $db_grant_perm) {
$db_grant_perm = cacti_strtoupper($db_grant_perm); $db_grant_perm = cacti_strtoupper($db_grant_perm);
if ($db_grant_perm == 'ALL' || if ($db_grant_perm == 'ALL' ||
+5 -5
View File
@@ -557,7 +557,7 @@ function read_user_setting(string $config_name, mixed $default = false, bool $fo
[$config_name, $effective_uid]); [$config_name, $effective_uid]);
} }
if (cacti_sizeof($db_setting)) { if (is_array($db_setting) && cacti_sizeof($db_setting)) {
$user_config_array[$config_name] = $db_setting['value']; $user_config_array[$config_name] = $db_setting['value'];
} elseif ($default !== false) { } elseif ($default !== false) {
$user_config_array[$config_name] = $default; $user_config_array[$config_name] = $default;
@@ -6583,7 +6583,7 @@ function mailer(array|string $from, array|string $to, null|array|string $cc = nu
// process custom headers // process custom headers
if (cacti_sizeof($headers)) { if (cacti_sizeof($headers)) {
foreach ($headers as $name => $value) { foreach (($headers ?: []) as $name => $value) {
$emailMessage->getHeaders()->addTextHeader($name, $value); $emailMessage->getHeaders()->addTextHeader($name, $value);
} }
} }
@@ -9445,7 +9445,7 @@ function get_cacti_base_tables() : array {
} }
if (cacti_sizeof($schema)) { if (cacti_sizeof($schema)) {
foreach ($schema as $line) { foreach (($schema ?: []) as $line) {
if (str_contains($line, 'CREATE TABLE')) { if (str_contains($line, 'CREATE TABLE')) {
$table = str_replace(['CREATE TABLE', '`', '(', ' '], '', $line); $table = str_replace(['CREATE TABLE', '`', '(', ' '], '', $line);
$base_tables[] = trim($table); $base_tables[] = trim($table);
@@ -10076,9 +10076,9 @@ function substring_index(string $subject, string $delim, int $count) : string {
} }
if ($count < 0) { if ($count < 0) {
return implode($delim, array_slice(explode($delim, $subject), $count)); // @phpstan-ignore argument.type (guard above ensures $delim is non-empty) return implode($delim, array_slice(explode($delim, $subject), $count));
} else { } else {
return implode($delim, array_slice(explode($delim, $subject), 0, $count)); // @phpstan-ignore argument.type (guard above ensures $delim is non-empty) return implode($delim, array_slice(explode($delim, $subject), 0, $count));
} }
} }
+6 -6
View File
@@ -83,7 +83,7 @@ function rrdtool_function_stats(mixed $local_data_ids, int $start_seconds, int $
include_once(CACTI_PATH_LIBRARY . '/rrd.php'); include_once(CACTI_PATH_LIBRARY . '/rrd.php');
if (!is_array($local_data_ids)) { if (!is_array($local_data_ids)) {
return json_encode([]); return (string) json_encode([]);
} }
// initialize some variables // initialize some variables
@@ -202,7 +202,7 @@ function rrdtool_function_stats(mixed $local_data_ids, int $start_seconds, int $
* good data. Else prepare a new array with summary data. * good data. Else prepare a new array with summary data.
*/ */
if (!$good_data) { if (!$good_data) {
return json_encode([]); return (string) json_encode([]);
} }
$stats = []; $stats = [];
@@ -217,7 +217,7 @@ function rrdtool_function_stats(mixed $local_data_ids, int $start_seconds, int $
$stats['peak'] = []; $stats['peak'] = [];
} }
return json_encode($stats); return (string) json_encode($stats);
} }
function nth_percentile_fetch_statistics(int $percentile, array &$local_data_ids, array &$fetch_array, string $cf) : array { function nth_percentile_fetch_statistics(int $percentile, array &$local_data_ids, array &$fetch_array, string $cf) : array {
@@ -716,7 +716,7 @@ function variable_bandwidth_summation(array &$regexp_match_array, array &$graph,
switch($regexp_match_array[2]) { switch($regexp_match_array[2]) {
case 'current': case 'current':
$summation_cache[$graph_item['local_data_id']] = bandwidth_summation($graph_item['local_data_id'], $summation_timespan_start, $graph_end, $rra_step, $ds_step); $summation_cache[$graph_item['local_data_id']] = bandwidth_summation($graph_item['local_data_id'], (int) $summation_timespan_start, $graph_end, $rra_step, $ds_step);
break; break;
case 'total': case 'total':
@@ -724,13 +724,13 @@ function variable_bandwidth_summation(array &$regexp_match_array, array &$graph,
if (!empty($graph_element['data_template_rrd_id']) && if (!empty($graph_element['data_template_rrd_id']) &&
!empty($graph_element['local_data_id']) && !empty($graph_element['local_data_id']) &&
is_graphable_item($graph_item_types[$graph_element['graph_type_id']])) { is_graphable_item($graph_item_types[$graph_element['graph_type_id']])) {
$summation_cache[$graph_element['local_data_id']] = bandwidth_summation($graph_element['local_data_id'], $summation_timespan_start, $graph_end, $rra_step, $ds_step); $summation_cache[$graph_element['local_data_id']] = bandwidth_summation($graph_element['local_data_id'], (int) $summation_timespan_start, $graph_end, $rra_step, $ds_step);
} }
} }
break; break;
case 'atomic': case 'atomic':
$summation_cache[$graph_item['local_data_id']] = bandwidth_summation($graph_item['local_data_id'], $summation_timespan_start, $graph_end, $rra_step, 1); $summation_cache[$graph_item['local_data_id']] = bandwidth_summation($graph_item['local_data_id'], (int) $summation_timespan_start, $graph_end, $rra_step, 1);
break; break;
} }
+5 -5
View File
@@ -766,7 +766,7 @@ function html_header_sort(array $header_items, string $sort_column, string $sort
'columns' => $header_items 'columns' => $header_items
]; ];
print "<thead><tr class='tableHeader' data-columns='" . base64_encode(json_encode($table_visibility)) . "'>"; print "<thead><tr class='tableHeader' data-columns='" . base64_encode((string) json_encode($table_visibility)) . "'>";
$i = 1; $i = 1;
@@ -964,7 +964,7 @@ function html_header_sort_checkbox(array $header_items, string $sort_column, str
'columns' => $header_items 'columns' => $header_items
]; ];
print "<thead><tr class='tableHeader' data-columns='" . base64_encode(json_encode($table_visibility)) . "'>"; print "<thead><tr class='tableHeader' data-columns='" . base64_encode((string) json_encode($table_visibility)) . "'>";
foreach ($header_items as $db_column => $display_array) { foreach ($header_items as $db_column => $display_array) {
// if the column is not visible, don't display it // if the column is not visible, don't display it
@@ -1113,7 +1113,7 @@ function html_header(array $header_items, int $last_item_colspan = 1, bool $resi
'columns' => $header_items 'columns' => $header_items
]; ];
print "<thead><tr class='tableHeader " . ($last_item_colspan > 1 || !$resizable ? 'tableFixed' : '') . "' data-columns='" . base64_encode(json_encode($table_visibility)) . "'>"; print "<thead><tr class='tableHeader " . ($last_item_colspan > 1 || !$resizable ? 'tableFixed' : '') . "' data-columns='" . base64_encode((string) json_encode($table_visibility)) . "'>";
$i = 0; $i = 0;
@@ -1205,7 +1205,7 @@ function html_header_checkbox(array $header_items, bool $include_form = true, st
'columns' => $header_items 'columns' => $header_items
]; ];
print "<thead><tr class='tableHeader " . (!$resizable ? 'tableFixed' : '') . "' data-columns='" . base64_encode(json_encode($table_visibility)) . "'>"; print "<thead><tr class='tableHeader " . (!$resizable ? 'tableFixed' : '') . "' data-columns='" . base64_encode((string) json_encode($table_visibility)) . "'>";
foreach ($header_items as $item) { foreach ($header_items as $item) {
if (is_array($item)) { if (is_array($item)) {
@@ -2327,7 +2327,7 @@ function html_show_tabs_left() : void {
ob_start(); ob_start();
api_plugin_hook('top_graph_header_tabs'); api_plugin_hook('top_graph_header_tabs');
$tab_text = trim(ob_get_clean()); $tab_text = trim((string) ob_get_clean());
$tab_text = str_replace('<a', '', $tab_text); $tab_text = str_replace('<a', '', $tab_text);
$tab_text = str_replace('</a>', '|', $tab_text); $tab_text = str_replace('</a>', '|', $tab_text);
$tab_text = str_replace('<img', '', $tab_text); $tab_text = str_replace('<img', '', $tab_text);
+1 -1
View File
@@ -394,7 +394,7 @@ function reports_form_save() : void {
if ($regex_valid !== true) { if ($regex_valid !== true) {
$_SESSION[SESS_ERROR_FIELDS]['graph_name_regexp'] = 3; $_SESSION[SESS_ERROR_FIELDS]['graph_name_regexp'] = 3;
raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle($save['graph_name_regexp']), htmle($regex_valid)), MESSAGE_LEVEL_ERROR); raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle((string) $save['graph_name_regexp']), htmle((string) $regex_valid)), MESSAGE_LEVEL_ERROR);
} }
} }
$save['site_id'] = (isrv('site_id') ? form_input_validate(gnrv('site_id'), 'site_id', '^[-0-9]+$', true, 3) : 0); $save['site_id'] = (isrv('site_id') ? form_input_validate(gnrv('site_id'), 'site_id', '^[-0-9]+$', true, 3) : 0);
+7 -7
View File
@@ -71,7 +71,7 @@ function inject_form_variables(array &$form_array, mixed $arg1 = [], mixed $arg2
// an empty field name in the variable means don't treat this as an array // an empty field name in the variable means don't treat this as an array
if ($matches2 == '') { if ($matches2 == '') {
if (is_array(${$matches1})) { // @phpstan-ignore-line if (is_array(${$matches1})) {
// the existing value is already an array, leave it alone // the existing value is already an array, leave it alone
$form_array[$field_name][$field_to_check] = ${$matches1}; $form_array[$field_name][$field_to_check] = ${$matches1};
} else { } else {
@@ -82,7 +82,7 @@ function inject_form_variables(array &$form_array, mixed $arg1 = [], mixed $arg2
/* copy the value down from the array/key specified in the variable /* copy the value down from the array/key specified in the variable
* replace up to three times for arg1:arg2:arg3 variables * replace up to three times for arg1:arg2:arg3 variables
*/ */
if (is_array(${$matches1})) { // @phpstan-ignore-line if (is_array(${$matches1})) {
$array = ${$matches1}; $array = ${$matches1};
if (isset($array[$matches2]) && $array[$matches2] != '') { if (isset($array[$matches2]) && $array[$matches2] != '') {
@@ -930,7 +930,7 @@ function get_filter_request_var(string $name, int $filter = FILTER_VALIDATE_INT,
$valid = true; $valid = true;
$values = preg_split('/,/', $_REQUEST[$name], -1, PREG_SPLIT_NO_EMPTY); $values = preg_split('/,/', $_REQUEST[$name], -1, PREG_SPLIT_NO_EMPTY);
foreach ($values as $number) { foreach (($values ?: []) as $number) {
if (!is_numeric($number)) { if (!is_numeric($number)) {
$valid = false; $valid = false;
@@ -956,7 +956,7 @@ function get_filter_request_var(string $name, int $filter = FILTER_VALIDATE_INT,
if ($value === false) { if ($value === false) {
if ($filter == FILTER_VALIDATE_IS_REGEX) { if ($filter == FILTER_VALIDATE_IS_REGEX) {
raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle(get_nfilter_request_var($name)), htmle($custom_error)), MESSAGE_LEVEL_ERROR); raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle((string) get_nfilter_request_var($name)), htmle((string) $custom_error)), MESSAGE_LEVEL_ERROR);
set_request_var($name, ''); set_request_var($name, '');
} else { } else {
die_html_input_error($name, get_nfilter_request_var($name)); die_html_input_error($name, get_nfilter_request_var($name));
@@ -1189,7 +1189,7 @@ function validate_store_request_vars(array $filters, string $sess_prefix = '') :
$valid = true; $valid = true;
$values = preg_split('/,/', $_REQUEST[$variable], -1, PREG_SPLIT_NO_EMPTY); $values = preg_split('/,/', $_REQUEST[$variable], -1, PREG_SPLIT_NO_EMPTY);
foreach ($values as $number) { foreach (($values ?: []) as $number) {
if (!is_numeric($number)) { if (!is_numeric($number)) {
$valid = false; $valid = false;
@@ -1226,10 +1226,10 @@ function validate_store_request_vars(array $filters, string $sess_prefix = '') :
if ($value === false) { if ($value === false) {
if ($options['filter'] == FILTER_VALIDATE_IS_REGEX) { if ($options['filter'] == FILTER_VALIDATE_IS_REGEX) {
raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', raise_message('custom', __('The regular expression "%s" is not valid. Error is %s',
htmle(get_nfilter_request_var($variable)), htmle($custom_error)), MESSAGE_LEVEL_ERROR); htmle((string) get_nfilter_request_var($variable)), htmle((string) $custom_error)), MESSAGE_LEVEL_ERROR);
set_request_var($variable, ''); set_request_var($variable, '');
} else { } else {
die_html_input_error($variable, get_nfilter_request_var($variable), htmle($custom_error)); die_html_input_error($variable, get_nfilter_request_var($variable), htmle((string) $custom_error));
} }
} else { } else {
set_request_var($variable, $value); set_request_var($variable, $value);
+10 -10
View File
@@ -397,7 +397,7 @@ function import_package_get_details(string $xmlfile) : array {
$return = []; $return = [];
$data = file_get_contents($filename); $data = file_get_contents($filename);
$xmlget = simplexml_load_string($data); $xmlget = simplexml_load_string((string) $data);
$pkgarr = xml_to_array($xmlget); $pkgarr = xml_to_array($xmlget);
$return = $pkgarr['info']; $return = $pkgarr['info'];
@@ -548,14 +548,14 @@ function import_read_package_data(string $xmlfile, string &$public_key, bool $pr
while (!feof($f)) { while (!feof($f)) {
$x = fgets($f); $x = fgets($f);
if (strlen($x) == 0) { if (strlen((string) $x) == 0) {
cacti_log('FATAL: Unable to read Cacti Package ' . $filename, true, 'IMPORT', POLLER_VERBOSITY_LOW); cacti_log('FATAL: Unable to read Cacti Package ' . $filename, true, 'IMPORT', POLLER_VERBOSITY_LOW);
fclose($f); fclose($f);
return false; return false;
} }
if (str_contains($x, '<signature>')) { if (str_contains((string) $x, '<signature>')) {
$binary_signature = base64_decode(trim(str_replace(['<signature>', '</signature>'], ['', ''], $x)), true); $binary_signature = base64_decode(trim(str_replace(['<signature>', '</signature>'], ['', ''], $x)), true);
$x = " <signature></signature>\n"; $x = " <signature></signature>\n";
@@ -573,7 +573,7 @@ function import_read_package_data(string $xmlfile, string &$public_key, bool $pr
} }
// Package signatures use SHA-256 regardless of key representation. // Package signatures use SHA-256 regardless of key representation.
$ok = openssl_verify($xml, $binary_signature, $public_key, OPENSSL_ALGO_SHA256); $ok = openssl_verify($xml, (string) $binary_signature, $public_key, OPENSSL_ALGO_SHA256);
if ($ok == 1) { if ($ok == 1) {
cacti_log('NOTE: File is Signed Correctly', false, 'IMPORT', POLLER_VERBOSITY_MEDIUM); cacti_log('NOTE: File is Signed Correctly', false, 'IMPORT', POLLER_VERBOSITY_MEDIUM);
@@ -661,7 +661,7 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha
$binary_signature = base64_decode($f['filesignature'], true); $binary_signature = base64_decode($f['filesignature'], true);
$fdata = base64_decode($f['data'], true); $fdata = base64_decode($f['data'], true);
$ok = openssl_verify($fdata, $binary_signature, $public_key, OPENSSL_ALGO_SHA256); $ok = openssl_verify((string) $fdata, (string) $binary_signature, $public_key, OPENSSL_ALGO_SHA256);
if ($ok == 1) { if ($ok == 1) {
cacti_log('NOTE: File OK: ' . $f['name'], false, 'IMPORT', POLLER_VERBOSITY_MEDIUM); cacti_log('NOTE: File OK: ' . $f['name'], false, 'IMPORT', POLLER_VERBOSITY_MEDIUM);
@@ -751,11 +751,11 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha
$file = fopen($filename, 'wb'); $file = fopen($filename, 'wb');
if (is_resource($file)) { if (is_resource($file)) {
$bytesWritten = fwrite($file, $fdata, strlen($fdata)); $bytesWritten = fwrite($file, $fdata, strlen((string) $fdata));
fclose($file); fclose($file);
clearstatcache(); clearstatcache();
if ($bytesWritten === strlen($fdata)) { if ($bytesWritten === strlen((string) $fdata)) {
$filestatus[$filename] = __('written'); $filestatus[$filename] = __('written');
} else { } else {
$filestatus[$filename] = __('incomplete write'); $filestatus[$filename] = __('incomplete write');
@@ -784,7 +784,7 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha
} else { } else {
cacti_log('Previewing file: ' . $filename, false, 'IMPORT', POLLER_VERBOSITY_MEDIUM); cacti_log('Previewing file: ' . $filename, false, 'IMPORT', POLLER_VERBOSITY_MEDIUM);
$new = md5($fdata); $new = md5((string) $fdata);
if (file_exists($filename)) { if (file_exists($filename)) {
$existing = md5_file($filename); $existing = md5_file($filename);
@@ -843,7 +843,7 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha
$name = $f['name']; $name = $f['name'];
if (isset($f['type']) && $f['type'] == 'template') { if (isset($f['type']) && $f['type'] == 'template') {
$template_data = xml2array($fdata); $template_data = xml2array((string) $fdata);
if (cacti_sizeof($template_data)) { if (cacti_sizeof($template_data)) {
foreach ($template_data as $hash => $tdata) { foreach ($template_data as $hash => $tdata) {
@@ -3169,7 +3169,7 @@ function import_display_results(array $import_debug_info, array $filestatus, boo
print ob_get_clean(); print ob_get_clean();
} else { } else {
$output = ob_get_clean(); $output = ob_get_clean();
$output = explode("\n", $output); $output = explode("\n", (string) $output);
if (cacti_sizeof($output)) { if (cacti_sizeof($output)) {
foreach ($output as $line) { foreach ($output as $line) {
+16 -16
View File
@@ -976,7 +976,7 @@ class Installer implements JsonSerializable {
// cacti_escapeshellcmd() replaces backslashes on Windows; normalize first // cacti_escapeshellcmd() replaces backslashes on Windows; normalize first
$output = shell_exec(cacti_escapeshellcmd(str_replace('\\', '/', $path)) . ' --version 2>&1'); $output = shell_exec(cacti_escapeshellcmd(str_replace('\\', '/', $path)) . ' --version 2>&1');
if ($output === null || !str_contains($output, 'Composer')) { if ($output === null || !str_contains((string) $output, 'Composer')) {
$this->addError(Installer::STEP_BINARY_LOCATIONS, 'Paths', $name, __('Composer did not return expected result')); $this->addError(Installer::STEP_BINARY_LOCATIONS, 'Paths', $name, __('Composer did not return expected result'));
$should_set = false; $should_set = false;
} }
@@ -1430,7 +1430,7 @@ class Installer implements JsonSerializable {
* *
* @return array<string, bool> * @return array<string, bool>
*/ */
private function getTemplates() : array { // @phpstan-ignore-line private function getTemplates() : array {
$known_templates = install_setup_get_templates(); $known_templates = install_setup_get_templates();
$db_templates = array_rekey( $db_templates = array_rekey(
@@ -1645,7 +1645,7 @@ class Installer implements JsonSerializable {
$selected = []; $selected = [];
$select_count = 0; $select_count = 0;
foreach ($known_tables as $known) { foreach (($known_tables ?: []) as $known) {
$table = $known['Name']; $table = $known['Name'];
$key = $known['Name']; $key = $known['Name'];
$option = ''; $option = '';
@@ -2226,7 +2226,7 @@ class Installer implements JsonSerializable {
$themes = glob($themePath . '*', GLOB_ONLYDIR); $themes = glob($themePath . '*', GLOB_ONLYDIR);
$themeOutput = '<select id=\'theme\' name=\'theme\'>'; $themeOutput = '<select id=\'theme\' name=\'theme\'>';
foreach ($themes as $themeFolder) { foreach (($themes ?: []) as $themeFolder) {
$theme = substr($themeFolder, strlen($themePath)); $theme = substr($themeFolder, strlen($themePath));
if (file_exists($themePath . $theme . '/main.css')) { if (file_exists($themePath . $theme . '/main.css')) {
@@ -2383,7 +2383,7 @@ class Installer implements JsonSerializable {
html_end_box(false); html_end_box(false);
$output .= Installer::sectionNormal(ob_get_contents()); $output .= Installer::sectionNormal((string) ob_get_contents());
ob_clean(); ob_clean();
$output .= Installer::sectionSubTitleEnd(); $output .= Installer::sectionSubTitleEnd();
@@ -2417,7 +2417,7 @@ class Installer implements JsonSerializable {
html_end_box(false); html_end_box(false);
$output .= Installer::sectionNormal(ob_get_contents()); $output .= Installer::sectionNormal((string) ob_get_contents());
ob_clean(); ob_clean();
$output .= Installer::sectionSubTitleEnd(); $output .= Installer::sectionSubTitleEnd();
@@ -2445,7 +2445,7 @@ class Installer implements JsonSerializable {
html_end_box(); html_end_box();
$output .= Installer::sectionNormal(ob_get_contents()); $output .= Installer::sectionNormal((string) ob_get_contents());
ob_clean(); ob_clean();
$output .= Installer::sectionSubTitleEnd(); $output .= Installer::sectionSubTitleEnd();
@@ -2748,7 +2748,7 @@ class Installer implements JsonSerializable {
$html = ob_get_contents(); $html = ob_get_contents();
$output .= Installer::sectionNormal($html); $output .= Installer::sectionNormal((string) $html);
ob_end_clean(); ob_end_clean();
@@ -2953,7 +2953,7 @@ class Installer implements JsonSerializable {
$html = ob_get_contents(); $html = ob_get_contents();
ob_end_clean(); ob_end_clean();
$output .= Installer::sectionNormal($html); $output .= Installer::sectionNormal((string) $html);
$output .= Installer::sectionTitle(__('Default Profile')); $output .= Installer::sectionTitle(__('Default Profile'));
$output .= Installer::sectionNormal(__('Please select the default Data Source Profile to be used for polling sources. This is the maximum amount of time between scanning devices for information so the lower the polling interval, the more work is placed on the Cacti Server host. Long retention profiles store more data, so they take up more disk capacity. Their advantage is that older data is not as consolidated and is therefore more accurate than using shorter retention.')); $output .= Installer::sectionNormal(__('Please select the default Data Source Profile to be used for polling sources. This is the maximum amount of time between scanning devices for information so the lower the polling interval, the more work is placed on the Cacti Server host. Long retention profiles store more data, so they take up more disk capacity. Their advantage is that older data is not as consolidated and is therefore more accurate than using shorter retention.'));
@@ -2987,7 +2987,7 @@ class Installer implements JsonSerializable {
$html = ob_get_contents(); $html = ob_get_contents();
ob_end_clean(); ob_end_clean();
$output .= Installer::sectionNormal($html); $output .= Installer::sectionNormal((string) $html);
$output .= Installer::sectionTitle(__('Default Automation Network')); $output .= Installer::sectionTitle(__('Default Automation Network'));
$output .= Installer::sectionNormal(__('Cacti can automatically scan the network once installation has completed. This will utilise the network range below to work out the range of IPs that can be scanned. A predefined set of options are defined for scanning which include using both \'public\' and \'private\' communities.')); $output .= Installer::sectionNormal(__('Cacti can automatically scan the network once installation has completed. This will utilise the network range below to work out the range of IPs that can be scanned. A predefined set of options are defined for scanning which include using both \'public\' and \'private\' communities.'));
@@ -3031,7 +3031,7 @@ class Installer implements JsonSerializable {
); );
$html = ob_get_contents(); $html = ob_get_contents();
$output .= Installer::sectionNormal($html); $output .= Installer::sectionNormal((string) $html);
$output .= Installer::sectionSubTitle(__('Additional SNMP Options'), 'automation_snmp_options'); $output .= Installer::sectionSubTitle(__('Additional SNMP Options'), 'automation_snmp_options');
ob_clean(); ob_clean();
@@ -3042,7 +3042,7 @@ class Installer implements JsonSerializable {
] ]
); );
$html = ob_get_contents(); $html = ob_get_contents();
$output .= Installer::sectionNormal($html); $output .= Installer::sectionNormal((string) $html);
ob_end_clean(); ob_end_clean();
} else { } else {
$output = Installer::sectionTitleError(__('Error Locating Profiles')); $output = Installer::sectionTitleError(__('Error Locating Profiles'));
@@ -3092,7 +3092,7 @@ class Installer implements JsonSerializable {
form_end_row(); form_end_row();
} }
html_end_box(false); html_end_box(false);
$output .= Installer::sectionNormal(ob_get_contents()); $output .= Installer::sectionNormal((string) ob_get_contents());
ob_end_clean(); ob_end_clean();
$output .= Installer::sectionNormal(__('Device Templates allow you to monitor and graph a vast assortment of data within Cacti. After you select the desired Device Templates, press \'Next\' and the installation will complete. Please be patient on this step, as the importation of the Device Templates can take a few minutes.')); $output .= Installer::sectionNormal(__('Device Templates allow you to monitor and graph a vast assortment of data within Cacti. After you select the desired Device Templates, press \'Next\' and the installation will complete. Please be patient on this step, as the importation of the Device Templates can take a few minutes.'));
@@ -3160,7 +3160,7 @@ class Installer implements JsonSerializable {
html_start_box(__('Tables'), '100%', false, 3, 'center', '', false); html_start_box(__('Tables'), '100%', false, 3, 'center', '', false);
html_header_checkbox([__('Name'), __('Collation'), __('Row Format'), __('Engine'), __('Rows')]); html_header_checkbox([__('Name'), __('Collation'), __('Row Format'), __('Engine'), __('Rows')]);
foreach ($tables as $id => $p) { foreach (($tables ?: []) as $id => $p) {
$enabled = self::isTableSelectable($p); $enabled = self::isTableSelectable($p);
$style = ($enabled ? '' : 'text-decoration: line-through;'); $style = ($enabled ? '' : 'text-decoration: line-through;');
@@ -3196,7 +3196,7 @@ class Installer implements JsonSerializable {
} }
$output .= Installer::sectionNormal(__('The following tables should be converted to UTF8 and InnoDB with a Dynamic row format. Please select the tables that you wish to convert during the installation process.')); $output .= Installer::sectionNormal(__('The following tables should be converted to UTF8 and InnoDB with a Dynamic row format. Please select the tables that you wish to convert during the installation process.'));
$output .= Installer::sectionNormal(ob_get_contents()); $output .= Installer::sectionNormal((string) ob_get_contents());
ob_end_clean(); ob_end_clean();
} }
@@ -3676,7 +3676,7 @@ class Installer implements JsonSerializable {
return; return;
} }
if (str_contains($check, 'Nothing to install, update or remove')) { if (str_contains((string) $check, 'Nothing to install, update or remove')) {
log_install_always('', __('Composer dependencies are current, no vendor refresh needed.')); log_install_always('', __('Composer dependencies are current, no vendor refresh needed.'));
return; return;
+2 -2
View File
@@ -133,7 +133,7 @@ function cacti_ldap_auth(string $username, string $password = '', string $dn = '
$response = []; $response = [];
foreach ($ldap_servers as $ldap_server) { foreach (($ldap_servers ?: []) as $ldap_server) {
$ldap->host = $ldap_server; $ldap->host = $ldap_server;
$response = $ldap->Authenticate(); $response = $ldap->Authenticate();
@@ -257,7 +257,7 @@ function cacti_ldap_search_dn(string $username, string $dn = '', string $host =
$response = []; $response = [];
foreach ($ldap_servers as $ldap_server) { foreach (($ldap_servers ?: []) as $ldap_server) {
$ldap->host = $ldap_server; $ldap->host = $ldap_server;
$response = $ldap->Search(); $response = $ldap->Search();
+8 -7
View File
@@ -108,7 +108,7 @@ class MibCache {
} }
} }
public function mib(string $mib) : object { public function mib(string $mib) : self {
$this->active_mib = $mib; $this->active_mib = $mib;
$this->active_object = ''; $this->active_object = '';
$this->active_table = ''; $this->active_table = '';
@@ -117,13 +117,13 @@ class MibCache {
return $this; return $this;
} }
public function object(string $object) : object { public function object(string $object) : self {
$this->active_object = $object; $this->active_object = $object;
return $this; return $this;
} }
public function table(string $table) : object { public function table(string $table) : self {
if ($this->active_table != $table) { if ($this->active_table != $table) {
if (!isset($this->cache__tables[$this->active_mib][$table])) { if (!isset($this->cache__tables[$this->active_mib][$table])) {
$oid_table = db_fetch_cell_prepared('SELECT oid $oid_table = db_fetch_cell_prepared('SELECT oid
@@ -161,7 +161,7 @@ class MibCache {
} }
} }
public function row(mixed $index) : object { public function row(mixed $index) : self {
// limited to one single $index so far // limited to one single $index so far
$this->active_table_entry = $index; $this->active_table_entry = $index;
@@ -316,7 +316,8 @@ class MibCache {
$result[$i] = []; $result[$i] = [];
for ($j = 0; $j < $num_columns; $j++) { for ($j = 0; $j < $num_columns; $j++) {
$result[$i][$entries[$i + $j * $entries_per_object]['name']] = $entries[$i + $j * $entries_per_object]['value']; $index = (int) ($i + $j * $entries_per_object);
$result[$i][$entries[$index]['name']] = $entries[$index]['value'];
} }
} }
@@ -361,13 +362,13 @@ class MibCache {
if (cacti_sizeof($entries)) { if (cacti_sizeof($entries)) {
$num_objects = cacti_sizeof($column); $num_objects = cacti_sizeof($column);
$num_entries = cacti_sizeof($entries); $num_entries = cacti_sizeof($entries);
$entries_per_object = ceil($num_entries / $num_objects); $entries_per_object = (int) ceil($num_entries / $num_objects);
for ($i = 0; $i < $entries_per_object; $i++) { for ($i = 0; $i < $entries_per_object; $i++) {
$result[$i] = []; $result[$i] = [];
for ($j = 0; $j < $num_objects; $j++) { for ($j = 0; $j < $num_objects; $j++) {
$index = (int) $i + ($j * $entries_per_object); $index = (int) ($i + ($j * $entries_per_object));
$result[$i][$entries[$index]['name']] = $entries[$index]['value']; $result[$i][$entries[$index]['name']] = $entries[$index]['value'];
} }
} }
+13 -6
View File
@@ -272,7 +272,7 @@ function get_package_contents(string $export_type, int $export_item_id, bool $in
if (cacti_sizeof($files)) { if (cacti_sizeof($files)) {
foreach ($files as $file) { foreach ($files as $file) {
if (str_contains($file['file'], '.xml')) { if (str_contains($file['file'], '.xml')) {
$files = array_merge($files, find_dependent_files(file_get_contents($file['file']), true)); $files = array_merge($files, find_dependent_files((string) file_get_contents($file['file']), true));
} }
} }
} }
@@ -284,7 +284,7 @@ function get_package_contents(string $export_type, int $export_item_id, bool $in
* When exporting Graph Templates, you have to check for data queries * When exporting Graph Templates, you have to check for data queries
* and process their XML files for additional scripts * and process their XML files for additional scripts
*/ */
if ($export_type == 'graph_template' && cacti_sizeof($queries)) { // @phpstan-ignore-line - This values is set as a global in get_item_xml if ($export_type == 'graph_template' && cacti_sizeof($queries)) {
foreach ($queries as $dq) { foreach ($queries as $dq) {
$xml_data = get_item_xml('data_query', $dq['id'], $include_deps); $xml_data = get_item_xml('data_query', $dq['id'], $include_deps);
@@ -294,7 +294,7 @@ function get_package_contents(string $export_type, int $export_item_id, bool $in
if (cacti_sizeof($nfiles)) { if (cacti_sizeof($nfiles)) {
foreach ($nfiles as $file) { foreach ($nfiles as $file) {
if (str_contains($file['file'], '.xml')) { if (str_contains($file['file'], '.xml')) {
$files = array_merge($files, find_dependent_files(file_get_contents($file['file']), true)); $files = array_merge($files, find_dependent_files((string) file_get_contents($file['file']), true));
} }
} }
} }
@@ -423,7 +423,7 @@ function find_dependent_files(string $xml_data, bool $raise_message = false) : a
$line = str_replace('<input_string>', '', $line); $line = str_replace('<input_string>', '', $line);
$line = str_replace('</input_string>', '', $line); $line = str_replace('</input_string>', '', $line);
$line = base64_decode($line, true); $line = base64_decode($line, true);
$line = xml_character_decode($line); $line = xml_character_decode((string) $line);
$line = str_replace('><', '> <', $line); $line = str_replace('><', '> <', $line);
$line = str_replace('>""<', '>" "<', $line); $line = str_replace('>""<', '>" "<', $line);
$line = str_replace('>\'\'<', '>\' \'<', $line); $line = str_replace('>\'\'<', '>\' \'<', $line);
@@ -500,7 +500,7 @@ function find_paths(string $input, string $type = 'cacti_xml') : array {
$input = htmlspecialchars_decode($input); $input = htmlspecialchars_decode($input);
$parts = preg_split('/\s+/', $input); $parts = preg_split('/\s+/', $input);
foreach ($parts as $part) { foreach (($parts ?: []) as $part) {
$opath = htmlspecialchars($part); $opath = htmlspecialchars($part);
$part = str_replace('<path_cacti>', CACTI_PATH_BASE, $part); $part = str_replace('<path_cacti>', CACTI_PATH_BASE, $part);
$part = str_replace('|path_cacti|', CACTI_PATH_BASE, $part); $part = str_replace('|path_cacti|', CACTI_PATH_BASE, $part);
@@ -701,7 +701,7 @@ function package_template(string &$template, array &$info, array &$files, string
$data = 'Not Found'; $data = 'Not Found';
} }
openssl_sign($data, $binary_signature, $private_key, OPENSSL_ALGO_SHA256); openssl_sign((string) $data, $binary_signature, $private_key, OPENSSL_ALGO_SHA256);
if ($data) { if ($data) {
$data = base64_encode($data); $data = base64_encode($data);
@@ -749,6 +749,13 @@ function package_template(string &$template, array &$info, array &$files, string
$debug .= 'NOTE: Creating compressed template xml "' . clean_up_name($name) . ".xml.gz\"\n"; $debug .= 'NOTE: Creating compressed template xml "' . clean_up_name($name) . ".xml.gz\"\n";
$f = fopen("compress.zlib://$tmpdir/" . clean_up_name($name) . '.xml.gz','wb'); $f = fopen("compress.zlib://$tmpdir/" . clean_up_name($name) . '.xml.gz','wb');
if (!is_resource($f)) {
$debug .= "ERROR: Could not open package file for writing\n";
return false;
}
fwrite($f, $xml, strlen($xml)); fwrite($f, $xml, strlen($xml));
fclose($f); fclose($f);
+6 -6
View File
@@ -223,10 +223,10 @@ class Net_Ping {
* www.google.com : xmt/rcv/%loss = 1/1/0%, min/avg/max = 25.6/25.6/25.6 * www.google.com : xmt/rcv/%loss = 1/1/0%, min/avg/max = 25.6/25.6/25.6
* 172.24.254.2 : xmt/rcv/%loss = 1/1/0%, min/avg/max = 7.01/7.01/7.01 * 172.24.254.2 : xmt/rcv/%loss = 1/1/0%, min/avg/max = 7.01/7.01/7.01
*/ */
$position = strpos($result, 'min/avg/max ='); $position = strpos((string) $result, 'min/avg/max =');
if ($position > 0) { if ($position > 0) {
$output = substr($result, $position); $output = substr((string) $result, $position);
$results = explode('/', $output); $results = explode('/', $output);
$this->ping_status = $results[3]; // avg $this->ping_status = $results[3]; // avg
$this->ping_response = __('ICMP Ping Success (fping.exe) (%s ms)', $results[1]); $this->ping_response = __('ICMP Ping Success (fping.exe) (%s ms)', $results[1]);
@@ -255,10 +255,10 @@ class Net_Ping {
* Approximate round trip times in milli-seconds: * Approximate round trip times in milli-seconds:
* Minimum = 22ms, Maximum = 30ms, Average = 25ms * Minimum = 22ms, Maximum = 30ms, Average = 25ms
*/ */
$position = strpos($result, 'Minimum'); $position = strpos((string) $result, 'Minimum');
if ($position > 0) { if ($position > 0) {
$output = trim(substr($result, $position)); $output = trim(substr((string) $result, $position));
$pieces = explode(',', $output); $pieces = explode(',', $output);
$results = explode('=', $pieces[2]); // Average $results = explode('=', $pieces[2]); // Average
@@ -273,10 +273,10 @@ class Net_Ping {
return false; return false;
} }
} else { } else {
$position = strpos($result, 'min/avg/max'); $position = strpos((string) $result, 'min/avg/max');
if ($position > 0) { if ($position > 0) {
$output = trim(str_replace(' ms', '', substr($result, $position))); $output = trim(str_replace(' ms', '', substr((string) $result, $position)));
$pieces = explode('=', $output); $pieces = explode('=', $output);
$results = explode('/', $pieces[1]); $results = explode('/', $pieces[1]);
+10 -10
View File
@@ -1619,7 +1619,7 @@ function api_plugin_archive_restore(string $plugin, string $id, string $type = '
foreach ($archive_files as $basefile => $pharpath) { foreach ($archive_files as $basefile => $pharpath) {
$output = file_get_contents("phar://my.tgz{$pharpath}"); $output = file_get_contents("phar://my.tgz{$pharpath}");
if (strlen($output)) { if (strlen((string) $output)) {
$rfile = ltrim($basefile, '/'); $rfile = ltrim($basefile, '/');
/** /**
@@ -1757,7 +1757,7 @@ function api_plugin_archive(string $plugin, string $note = '') : void {
$md5sum, $md5sum,
date('Y-m-d H:i:s'), date('Y-m-d H:i:s'),
$note, $note,
base64_encode(file_get_contents($tmpafile)) base64_encode((string) file_get_contents($tmpafile))
] ]
); );
@@ -2195,9 +2195,9 @@ function plugin_fetch_latest_plugins() : mixed {
$requires, $requires,
date('Y-m-d H:i:s', strtotime($json_data[0]['published_at'])), date('Y-m-d H:i:s', strtotime($json_data[0]['published_at'])),
base64_encode($json_data[0]['body']), base64_encode($json_data[0]['body']),
base64_encode($ofiles['info']), base64_encode((string) $ofiles['info']),
base64_encode($ofiles['readme']), base64_encode((string) $ofiles['readme']),
base64_encode($ofiles['changelog']), base64_encode((string) $ofiles['changelog']),
base64_encode($ofiles['archive']) base64_encode($ofiles['archive'])
] ]
); );
@@ -2340,9 +2340,9 @@ function plugin_fetch_latest_plugins() : mixed {
$requires, $requires,
$published_at, $published_at,
'', '',
base64_encode($ofiles['info']), base64_encode((string) $ofiles['info']),
base64_encode($ofiles['readme']), base64_encode((string) $ofiles['readme']),
base64_encode($ofiles['changelog']), base64_encode((string) $ofiles['changelog']),
base64_encode($ofiles['archive']) base64_encode($ofiles['archive'])
] ]
); );
@@ -2418,7 +2418,7 @@ function plugin_make_github_request(string $url, string $type = 'json') : mixed
$error = curl_error($ch); $error = curl_error($ch);
if ($info['http_code'] == 403 || $info['http_code'] == 429) { if ($info['http_code'] == 403 || $info['http_code'] == 429) {
$json_data = json_decode($data, true); $json_data = json_decode((string) $data, true);
if (isset($json_data['message'])) { if (isset($json_data['message'])) {
raise_message('rate_limited', $json_data['message'], MESSAGE_LEVEL_ERROR); raise_message('rate_limited', $json_data['message'], MESSAGE_LEVEL_ERROR);
@@ -2431,7 +2431,7 @@ function plugin_make_github_request(string $url, string $type = 'json') : mixed
if ($errno == 0) { if ($errno == 0) {
if ($type == 'json') { if ($type == 'json') {
return json_decode($data, true); return json_decode((string) $data, true);
} }
if ($type == 'raw') { if ($type == 'raw') {
+17 -9
View File
@@ -77,7 +77,7 @@ function exec_poll_php(string $command, bool $using_proc_function, array $pipes,
$output = fgets($pipes[1], 8192); $output = fgets($pipes[1], 8192);
if (substr_count($output, 'ERROR') > 0) { if (substr_count((string) $output, 'ERROR') > 0) {
$output = 'U'; $output = 'U';
} }
} }
@@ -293,7 +293,7 @@ function exec_with_timeout(string $cmd, array &$output, int &$return_code, int $
$setsid = ''; $setsid = '';
if (CACTI_SERVER_OS != 'win32') { if (CACTI_SERVER_OS != 'win32') {
$setsid_path = trim(shell_exec('which setsid 2>/dev/null') ?? ''); $setsid_path = trim((string) shell_exec('which setsid 2>/dev/null'));
if ($setsid_path !== '') { if ($setsid_path !== '') {
$setsid = 'setsid -- '; $setsid = 'setsid -- ';
@@ -825,7 +825,7 @@ function process_poller_output(mixed &$rrdtool_pipe, int $remainder = 0) : int {
// need a per-instance lookup (rare exception), cached per data source // need a per-instance lookup (rare exception), cached per data source
$nt_rrd_field_names = $data_template_id == 0 ? poller_get_nt_rrd_field_names($local_data_id, $nt_cache) : []; $nt_rrd_field_names = $data_template_id == 0 ? poller_get_nt_rrd_field_names($local_data_id, $nt_cache) : [];
foreach ($values as $value) { foreach (($values ?: []) as $value) {
$matches = explode(':', $value); $matches = explode(':', $value);
if (cacti_sizeof($matches) == 2) { if (cacti_sizeof($matches) == 2) {
@@ -1307,6 +1307,10 @@ function update_db_from_path(string $path, string $type, bool $recursive = true)
if (is_dir($path)) { if (is_dir($path)) {
$pobject = dir($path); $pobject = dir($path);
if ($pobject === false) {
return;
}
while (($entry = $pobject->read()) !== false) { while (($entry = $pobject->read()) !== false) {
if (!should_ignore_from_replication($entry)) { if (!should_ignore_from_replication($entry)) {
$spath = ltrim(trim(str_replace(CACTI_PATH_BASE, '', $path), '/ \\') . '/' . $entry, '/ \\'); $spath = ltrim(trim(str_replace(CACTI_PATH_BASE, '', $path), '/ \\') . '/' . $entry, '/ \\');
@@ -1349,7 +1353,7 @@ function update_db_from_path(string $path, string $type, bool $recursive = true)
$save['md5sum'] = md5_file($entry_path); $save['md5sum'] = md5_file($entry_path);
$save['update_time'] = date('Y-m-d H:i:s'); $save['update_time'] = date('Y-m-d H:i:s');
$save['attributes'] = $attributes; $save['attributes'] = $attributes;
$save['contents'] = base64_encode(file_get_contents($entry_path)); $save['contents'] = base64_encode((string) file_get_contents($entry_path));
sql_save($save, 'poller_resource_cache'); sql_save($save, 'poller_resource_cache');
} }
@@ -1386,7 +1390,7 @@ function update_db_from_path(string $path, string $type, bool $recursive = true)
$save['md5sum'] = md5_file($path); $save['md5sum'] = md5_file($path);
$save['update_time'] = date('Y-m-d H:i:s'); $save['update_time'] = date('Y-m-d H:i:s');
$save['attributes'] = $attributes; $save['attributes'] = $attributes;
$save['contents'] = base64_encode(file_get_contents($path)); $save['contents'] = base64_encode((string) file_get_contents($path));
sql_save($save, 'poller_resource_cache'); sql_save($save, 'poller_resource_cache');
} }
@@ -1442,7 +1446,7 @@ function resource_cache_out(string $type, array $path) : void {
// If for some reason, the attributes are empty, assume 0644 // If for some reason, the attributes are empty, assume 0644
$attributes = empty($e['attributes']) ? 33188 : $e['attributes']; $attributes = empty($e['attributes']) ? 33188 : $e['attributes'];
$extension = substr(strrchr($e['path'], '.'), 1); $extension = substr((string) strrchr($e['path'], '.'), 1);
$exit = -1; $exit = -1;
$contents = base64_decode(db_fetch_cell_prepared('SELECT contents $contents = base64_decode(db_fetch_cell_prepared('SELECT contents
FROM poller_resource_cache FROM poller_resource_cache
@@ -1539,6 +1543,10 @@ function md5sum_path(string $path, bool $recursive = true) : mixed {
$filemd5s = []; $filemd5s = [];
$pobject = dir($path); $pobject = dir($path);
if ($pobject === false) {
return false;
}
$excluded_extensions = ['tar', 'gz', 'zip', 'tgz', 'ttf', 'z', 'exe', 'pack', 'swp', 'swo']; $excluded_extensions = ['tar', 'gz', 'zip', 'tgz', 'ttf', 'z', 'exe', 'pack', 'swp', 'swo'];
while (($entry = $pobject->read()) !== false) { while (($entry = $pobject->read()) !== false) {
@@ -3030,7 +3038,7 @@ function register_process_start_locked(string $tasktype, string $taskname, int $
if (!cacti_sizeof($r)) { if (!cacti_sizeof($r)) {
cacti_log(sprintf('NOTE: Registering process! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $pid), false, 'POLLER', POLLER_VERBOSITY_MEDIUM); cacti_log(sprintf('NOTE: Registering process! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $pid), false, 'POLLER', POLLER_VERBOSITY_MEDIUM);
register_process($tasktype, $taskname, $taskid, $pid, $timeout); register_process($tasktype, $taskname, $taskid, (int) $pid, $timeout);
} elseif ($r['timeout_exceeded']) { } elseif ($r['timeout_exceeded']) {
if ($r['pid'] > 0) { if ($r['pid'] > 0) {
if (cacti_process_still_running((int) $r['pid'])) { if (cacti_process_still_running((int) $r['pid'])) {
@@ -3040,7 +3048,7 @@ function register_process_start_locked(string $tasktype, string $taskname, int $
} }
unregister_process($tasktype, $taskname, $taskid); unregister_process($tasktype, $taskname, $taskid);
register_process($tasktype, $taskname, $taskid, $pid, $timeout); register_process($tasktype, $taskname, $taskid, (int) $pid, $timeout);
} else { } else {
// Should never be reached // Should never be reached
cacti_log(sprintf('ERROR: Failed registering process. Invalid pid found. Unable to kill! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $r['pid']), false, 'POLLER'); cacti_log(sprintf('ERROR: Failed registering process. Invalid pid found. Unable to kill! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $r['pid']), false, 'POLLER');
@@ -3055,7 +3063,7 @@ function register_process_start_locked(string $tasktype, string $taskname, int $
cacti_log(sprintf('WARNING: Detected process that is exited and did not unregister first! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $pid), false, 'POLLER'); cacti_log(sprintf('WARNING: Detected process that is exited and did not unregister first! (%s, %s, %s, %s)', $tasktype, $taskname, $taskid, $pid), false, 'POLLER');
unregister_process($tasktype, $taskname, $taskid); unregister_process($tasktype, $taskname, $taskid);
register_process($tasktype, $taskname, $taskid, $pid, $timeout); register_process($tasktype, $taskname, $taskid, (int) $pid, $timeout);
} }
return true; return true;
+7 -7
View File
@@ -358,11 +358,11 @@ function reports_interval_start(int $interval, int $count, int $offset, int $tim
$nth_weekday = ceil($day_of_month / 7); $nth_weekday = ceil($day_of_month / 7);
$date_str = '+' . $count . ' months'; $date_str = '+' . $count . ' months';
$month_base = strtotime($date_str, $timestamp); $month_base = (int) strtotime($date_str, $timestamp);
$new_month = mktime((int) date('H', $month_base), (int) date('i', $month_base), (int) date('s', $month_base), (int) date('m', $month_base), 1, (int) date('Y', $month_base)); $new_month = mktime((int) date('H', $month_base), (int) date('i', $month_base), (int) date('s', $month_base), (int) date('m', $month_base), 1, (int) date('Y', $month_base));
$date_str = '+' . ($nth_weekday - 1) . ' week ' . $weekday; $date_str = '+' . ($nth_weekday - 1) . ' week ' . $weekday;
$base = strtotime($date_str, $new_month); $base = (int) strtotime($date_str, $new_month);
$ts = mktime((int) date('H', $month_base), (int) date('i', $month_base), (int) date('s', $month_base), (int) date('m', $base), (int) date('d', $base), (int) date('Y', $base)); $ts = mktime((int) date('H', $month_base), (int) date('i', $month_base), (int) date('s', $month_base), (int) date('m', $base), (int) date('d', $base), (int) date('Y', $base));
break; break;
@@ -711,7 +711,7 @@ function reports_load_format_file(string $format_file, mixed &$output, bool &$re
$output = ''; $output = '';
if (cacti_sizeof($contents)) { if (cacti_sizeof($contents)) {
foreach ($contents as $line) { foreach (($contents ?: []) as $line) {
$line = trim($line); $line = trim($line);
if (substr_count($line, '<REPORT>')) { if (substr_count($line, '<REPORT>')) {
@@ -856,7 +856,7 @@ function reports_generate_history_html(int $history_id, int $output = REPORTS_OU
$report = str_replace('<table>', '<table class="cactiTable">', $report); $report = str_replace('<table>', '<table class="cactiTable">', $report);
} }
$graph_data = json_decode(base64_decode($data['report_attachments'], true), true); $graph_data = json_decode((string) base64_decode($data['report_attachments'], true), true);
foreach ($graph_data as $graph) { foreach ($graph_data as $graph) {
$report = str_replace('<GRAPH:' . $graph['local_graph_id'] . ':' . $graph['timespan'] . '>', $report = str_replace('<GRAPH:' . $graph['local_graph_id'] . ':' . $graph['timespan'] . '>',
@@ -1594,7 +1594,7 @@ function reports_expand_tree(array &$report, array $item, int $parent, int $outp
if (cacti_sizeof($outgraphs)) { if (cacti_sizeof($outgraphs)) {
// let's sort the graphs naturally // let's sort the graphs naturally
usort($outgraphs, 'necturally_sort_graphs'); // @phpstan-ignore-line usort($outgraphs, 'necturally_sort_graphs');
// start graph display // start graph display
if ($title != '') { if ($title != '') {
@@ -1974,7 +1974,7 @@ function reports_get_format_files() : array {
$contents = file($dir . '/' . $file); $contents = file($dir . '/' . $file);
if (cacti_sizeof($contents)) { if (cacti_sizeof($contents)) {
foreach ($contents as $line) { foreach (($contents ?: []) as $line) {
$line = trim($line); $line = trim($line);
if (substr_count($line, 'Description:') && str_starts_with($line, '#')) { if (substr_count($line, 'Description:') && str_starts_with($line, '#')) {
@@ -2335,7 +2335,7 @@ function reports_log_and_notify(int $id, int $start_time, string $report_type, s
$save['report_raw_output'] = $oput_raw; $save['report_raw_output'] = $oput_raw;
$save['report_html_output'] = $oput_html; $save['report_html_output'] = $oput_html;
$save['report_txt_output'] = $oput_text; $save['report_txt_output'] = $oput_text;
$save['report_attachments'] = base64_encode(json_encode($attachments)); $save['report_attachments'] = base64_encode((string) json_encode($attachments));
$save['send_type'] = $report['request_type']; $save['send_type'] = $report['request_type'];
$save['send_time'] = date('Y-m-d H:i:s'); $save['send_time'] = date('Y-m-d H:i:s');
$save['run_time'] = $end_time - $start_time; $save['run_time'] = $end_time - $start_time;
+2 -2
View File
@@ -3983,7 +3983,7 @@ function rrdtool_function_theme_font_options(array &$graph_data_array) : string
} }
} }
if (isset(${$themeborder}) && cacti_version_compare($rrdversion, '1.4', '>=')) { // @phpstan-ignore-line if (isset(${$themeborder}) && cacti_version_compare($rrdversion, '1.4', '>=')) {
$graph_opts .= '--border ' . ${$themeborder} . RRD_NL; // @phpstan-ignore-line $graph_opts .= '--border ' . ${$themeborder} . RRD_NL; // @phpstan-ignore-line
} }
@@ -5006,7 +5006,7 @@ function rrd_datasource_add(array $file_array, array $ds_array, bool $debug) : m
* version 0003 => RRDtool 1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x * version 0003 => RRDtool 1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x
*/ */
$version_node = $dom->getElementsByTagName('version')->item(0); $version_node = $dom->getElementsByTagName('version')->item(0);
$version = $version_node !== null ? trim($version_node->nodeValue) : RRD_FILE_VERSION3; $version = $version_node !== null ? trim((string) $version_node->nodeValue) : RRD_FILE_VERSION3;
// now start XML processing // now start XML processing
foreach ($ds_array as $ds) { foreach ($ds_array as $ds) {
+2 -2
View File
@@ -403,9 +403,9 @@ function do_rrdcheck(int $thread_id = 1) : void {
if ($first) { if ($first) {
// get the data source names // get the data source names
$data_source_names = preg_split('/\s+/', $line); $data_source_names = preg_split('/\s+/', $line) ?: [];
foreach ($data_source_names as $index => $name) { foreach (($data_source_names ?: []) as $index => $name) {
$nan_24[$index] = 0; $nan_24[$index] = 0;
$nan_1[$index] = 0; $nan_1[$index] = 0;
} }
+5 -5
View File
@@ -997,12 +997,12 @@ function format_snmp_string(string $string, bool $snmp_oid_included, int $value_
if ($snmp_oid_included) { if ($snmp_oid_included) {
// strip off all leading junk (the oid and stuff) // strip off all leading junk (the oid and stuff)
$string_array = explode('=', $string, 2); $string_array = explode('=', (string) $string, 2);
if (cacti_sizeof($string_array) == 1) { if (cacti_sizeof($string_array) == 1) {
// trim excess first // trim excess first
$string = trim($string); $string = trim((string) $string);
} elseif ((str_starts_with($string, '.')) || (str_contains($string, '::'))) { } elseif ((str_starts_with((string) $string, '.')) || (str_contains((string) $string, '::'))) {
// drop the OID from the array // drop the OID from the array
array_shift($string_array); array_shift($string_array);
$string = trim(implode('=', $string_array)); $string = trim(implode('=', $string_array));
@@ -1010,7 +1010,7 @@ function format_snmp_string(string $string, bool $snmp_oid_included, int $value_
$string = trim(implode('=', $string_array)); $string = trim(implode('=', $string_array));
} }
} else { } else {
$string = trim($string); $string = trim((string) $string);
} }
// remove quotes and extraneous data // remove quotes and extraneous data
@@ -1087,7 +1087,7 @@ function format_snmp_string(string $string, bool $snmp_oid_included, int $value_
} }
// Trim the string of trailing and leading spaces // Trim the string of trailing and leading spaces
$string = trim($string); $string = trim((string) $string);
// convert hex strings to numeric values // convert hex strings to numeric values
if (is_hex_string($string)) { if (is_hex_string($string)) {
+2 -2
View File
@@ -2585,7 +2585,7 @@ function verify_data_input_whitelist(string $hash, string $input_string) : mixed
return true; return true;
} }
$whitelist = json_decode(file_get_contents(CACTI_WHITELIST), true); $whitelist = json_decode((string) file_get_contents(CACTI_WHITELIST), true);
if (isset($whitelist[$hash])) { if (isset($whitelist[$hash])) {
if ($input_string == $whitelist[$hash]) { if ($input_string == $whitelist[$hash]) {
@@ -2614,7 +2614,7 @@ function graph_template_whitelist_check(int $graph_template_id) : bool {
// load whitelist, but only once within process execution // load whitelist, but only once within process execution
if ($data_input_whitelist == null) { if ($data_input_whitelist == null) {
$data_input_whitelist = json_decode(file_get_contents(CACTI_WHITELIST), true); $data_input_whitelist = json_decode((string) file_get_contents(CACTI_WHITELIST), true);
if ($data_input_whitelist === null) { if ($data_input_whitelist === null) {
cacti_log('ERROR: Failed to parse input whitelist file: ' . CACTI_WHITELIST); cacti_log('ERROR: Failed to parse input whitelist file: ' . CACTI_WHITELIST);
+2 -2
View File
@@ -150,12 +150,12 @@ function process_user_input(array &$timespan, int $timeshift) : void {
$errors = 0; $errors = 0;
if ($date1 < $early_date) { if ($date1 < $early_date) {
raise_message('start_too_early', __('Your Start Date \'%s\' is before January 1993. Please pick a more recent Start Date.', date('Y-m-d H:i:s', $date1)), MESSAGE_LEVEL_WARN); raise_message('start_too_early', __('Your Start Date \'%s\' is before January 1993. Please pick a more recent Start Date.', date('Y-m-d H:i:s', (int) $date1)), MESSAGE_LEVEL_WARN);
$errors++; $errors++;
} }
if ($date2 < $early_date) { if ($date2 < $early_date) {
raise_message('start_too_early', __('Your End Date \'%s\' is before January 1993. Please pick a more recent End Date.', date('Y-m-d H:i:s', $date2)), MESSAGE_LEVEL_WARN); raise_message('start_too_early', __('Your End Date \'%s\' is before January 1993. Please pick a more recent End Date.', date('Y-m-d H:i:s', (int) $date2)), MESSAGE_LEVEL_WARN);
$errors++; $errors++;
} }
+8 -8
View File
@@ -1048,7 +1048,7 @@ function data_input_whitelist_check(int $data_input_id) : bool {
'hash', ['id', 'name', 'input_string'] 'hash', ['id', 'name', 'input_string']
); );
$data_input_whitelist = json_decode(file_get_contents(CACTI_WHITELIST), true); $data_input_whitelist = json_decode((string) file_get_contents(CACTI_WHITELIST), true);
if ($data_input_whitelist === null) { if ($data_input_whitelist === null) {
cacti_log('ERROR: Failed to parse input whitelist file: ' . CACTI_WHITELIST); cacti_log('ERROR: Failed to parse input whitelist file: ' . CACTI_WHITELIST);
@@ -1717,11 +1717,11 @@ function utilities_php_modules() : string {
// Remove nasty style sheets, links and other junk // Remove nasty style sheets, links and other junk
$php_info = str_replace("\n", '', $php_info); $php_info = str_replace("\n", '', $php_info);
$php_info = preg_replace('/^.*\<body\>/', '', $php_info); $php_info = preg_replace('/^.*\<body\>/', '', $php_info);
$php_info = preg_replace('/\<\/body\>.*$/', '', $php_info); $php_info = preg_replace('/\<\/body\>.*$/', '', (string) $php_info);
$php_info = preg_replace('/(\<a name.*\>)([^<>]*)(\<\/a\>)/U', '$2', $php_info); $php_info = preg_replace('/(\<a name.*\>)([^<>]*)(\<\/a\>)/U', '$2', (string) $php_info);
$php_info = preg_replace('/\<img.*\>/U', '', $php_info); $php_info = preg_replace('/\<img.*\>/U', '', (string) $php_info);
$php_info = preg_replace('/\<div[^<>]*\>\<\/div\>/U', '', $php_info); $php_info = preg_replace('/\<div[^<>]*\>\<\/div\>/U', '', (string) $php_info);
$php_info = preg_replace('/\<\/?address\>/', '', $php_info); $php_info = preg_replace('/\<\/?address\>/', '', (string) $php_info);
return $php_info; return $php_info;
} }
@@ -1790,7 +1790,7 @@ function utilities_get_system_memory() : array {
} }
if ($file != '') { if ($file != '') {
$data = explode("\n", file_get_contents($file)); $data = explode("\n", (string) file_get_contents($file));
foreach ($data as $l) { foreach ($data as $l) {
if (trim($l) != '') { if (trim($l) != '') {
@@ -1912,7 +1912,7 @@ function utility_php_recommends() : array {
$php_file = cacti_escapeshellarg(CACTI_PATH_INSTALL . '/cli_check.php') . ' recommends'; $php_file = cacti_escapeshellarg(CACTI_PATH_INSTALL . '/cli_check.php') . ' recommends';
$json = shell_exec($php . ' -q ' . $php_file); $json = shell_exec($php . ' -q ' . $php_file);
$ext = ['web' => '', 'cli' => '']; $ext = ['web' => '', 'cli' => ''];
$ext['cli'] = @json_decode($json, true); $ext['cli'] = @json_decode((string) $json, true);
utility_php_verify_recommends($ext['web'], 'web'); utility_php_verify_recommends($ext['web'], 'web');
utility_php_set_recommends_text($ext); utility_php_set_recommends_text($ext);
+1 -1
View File
@@ -653,7 +653,7 @@ function manager_logs(int $id, string $header_label) : void {
$description = ''; $description = '';
$lines = preg_split('/\r\n|\r|\n/', $item['description']); $lines = preg_split('/\r\n|\r|\n/', $item['description']);
foreach ($lines as $line) { foreach (($lines ?: []) as $line) {
$description .= htmle(trim($line)) . '<br>'; $description .= htmle(trim($line)) . '<br>';
} }
+1 -1
View File
@@ -87,7 +87,7 @@ if (isempty_request_var('state') || empty($_SESSION['oauth2state']) ||
// Use this to interact with an API on the users behalf // Use this to interact with an API on the users behalf
// Use this to get a new access token if the old one expires // Use this to get a new access token if the old one expires
print __('Refresh Token: ') . htmle($token->getRefreshToken()); print __('Refresh Token: ') . htmle((string) $token->getRefreshToken());
print '<br/>' . __('Store this token in Settings -> Mail/Reporting/DNS -> Oauth2 refresh token. '); print '<br/>' . __('Store this token in Settings -> Mail/Reporting/DNS -> Oauth2 refresh token. ');
print '<br/>' . __('If the token is empty, it means it stays the same. The Oatuh2 provider will not resend it in that case. '); print '<br/>' . __('If the token is empty, it means it stays the same. The Oatuh2 provider will not resend it in that case. ');
} }
+1 -1
View File
@@ -102,7 +102,7 @@ function form_save() : void {
if (cacti_sizeof($files)) { if (cacti_sizeof($files)) {
foreach ($files as $file) { foreach ($files as $file) {
if (str_contains($file['file'], '.xml')) { if (str_contains($file['file'], '.xml')) {
$files = array_merge($files, find_dependent_files(file_get_contents($file['file']))); $files = array_merge($files, find_dependent_files((string) file_get_contents($file['file'])));
} }
} }
} }
+6 -6
View File
@@ -266,7 +266,7 @@ function form_actions() : void {
foreach ($_POST as $var => $val) { foreach ($_POST as $var => $val) {
if (str_contains($var, 'chk_file_')) { if (str_contains($var, 'chk_file_')) {
$id = base64_decode(str_replace('chk_file_', '', $var), true); $id = base64_decode(str_replace('chk_file_', '', $var), true);
$id = json_decode($id, true); $id = json_decode((string) $id, true);
// Get rid of the basename // Get rid of the basename
$id['pfile'] = str_replace(CACTI_PATH_BASE . '/', '', $id['pfile']); $id['pfile'] = str_replace(CACTI_PATH_BASE . '/', '', $id['pfile']);
@@ -283,7 +283,7 @@ function form_actions() : void {
if (str_contains($var, 'chk_import_')) { if (str_contains($var, 'chk_import_')) {
$id = base64_decode(str_replace('chk_import_', '', $var), true); $id = base64_decode(str_replace('chk_import_', '', $var), true);
$id = json_decode($id, true); $id = json_decode((string) $id, true);
$packages = explode('<br>', $id['package']); $packages = explode('<br>', $id['package']);
$package = ''; $package = '';
@@ -540,7 +540,7 @@ function form_save() : void {
foreach ($_POST as $var => $val) { foreach ($_POST as $var => $val) {
if (str_contains($var, 'chk_file_')) { if (str_contains($var, 'chk_file_')) {
$id = base64_decode(str_replace('chk_file_', '', $var), true); $id = base64_decode(str_replace('chk_file_', '', $var), true);
$id = json_decode($id, true); $id = json_decode((string) $id, true);
if (str_contains($id['pfile'], '/')) { if (str_contains($id['pfile'], '/')) {
$parts = explode('/', $id['pfile']); $parts = explode('/', $id['pfile']);
@@ -569,7 +569,7 @@ function form_save() : void {
if (str_contains($var, 'chk_import_')) { if (str_contains($var, 'chk_import_')) {
$id = base64_decode(str_replace('chk_import_', '', $var), true); $id = base64_decode(str_replace('chk_import_', '', $var), true);
$id = json_decode($id, true); $id = json_decode((string) $id, true);
$hashes[] = $id['hash']; $hashes[] = $id['hash'];
} }
@@ -656,7 +656,7 @@ function package_file_get_contents(string $package_location, string $package_fil
$fdata = base64_decode($file['data'], true); $fdata = base64_decode($file['data'], true);
$ok = openssl_verify($fdata, $binary_signature, $public_key, OPENSSL_ALGO_SHA256); $ok = openssl_verify((string) $fdata, (string) $binary_signature, $public_key, OPENSSL_ALGO_SHA256);
if ($ok != 1) { if ($ok != 1) {
$fdata = false; $fdata = false;
@@ -699,7 +699,7 @@ function package_file_get_contents(string $package_location, string $package_fil
$fdata = base64_decode($file['data'], true); $fdata = base64_decode($file['data'], true);
$ok = openssl_verify($fdata, $binary_signature, $public_key, OPENSSL_ALGO_SHA256); $ok = openssl_verify((string) $fdata, (string) $binary_signature, $public_key, OPENSSL_ALGO_SHA256);
if ($ok != 1) { if ($ok != 1) {
$fdata = false; $fdata = false;
+27 -1509
View File
File diff suppressed because it is too large. Load diff
+12 -12
View File
@@ -74,7 +74,7 @@ function sig_handler($signo) : void {
case SIGTERM: case SIGTERM:
case SIGINT: case SIGINT:
if ($thread > 0) { if ($thread > 0) {
clearTask($network_id, getmypid()); clearTask($network_id, (int) getmypid());
exit(0); exit(0);
} }
@@ -92,7 +92,7 @@ function sig_handler($signo) : void {
} }
} }
clearTask($network_id, getmypid()); clearTask($network_id, (int) getmypid());
sleep(5); sleep(5);
@@ -113,7 +113,7 @@ function sig_handler($signo) : void {
} }
} }
clearTask($network_id, getmypid()); clearTask($network_id, (int) getmypid());
} }
exit(0); exit(0);
@@ -541,7 +541,7 @@ function discoverDevices(int $network_id, int $thread) : bool {
[$dnsname, $device['ip_address']]); [$dnsname, $device['ip_address']]);
$device['dnsname'] = $dnsname; $device['dnsname'] = $dnsname;
$device['dnsname_short'] = explode('.', cacti_strtolower($dnsname))[0]; $device['dnsname_short'] = explode('.', cacti_strtolower((string) $dnsname))[0];
} elseif ($network['enable_netbios'] == 'on') { } elseif ($network['enable_netbios'] == 'on') {
automation_debug('Device: ' . $device['ip_address'] . ', Checking DNS: Not found, Checking NetBIOS:'); automation_debug('Device: ' . $device['ip_address'] . ', Checking DNS: Not found, Checking NetBIOS:');
@@ -645,7 +645,7 @@ function discoverDevices(int $network_id, int $thread) : bool {
automation_debug(' Responded'); automation_debug(' Responded');
$stats['ping']++; $stats['ping']++;
addUpDevice($network_id, getmypid()); addUpDevice($network_id, (int) getmypid());
} }
} }
@@ -679,10 +679,10 @@ function discoverDevices(int $network_id, int $thread) : bool {
if (cacti_sizeof($exists)) { if (cacti_sizeof($exists)) {
if ($exists['deleted'] != 'on') { if ($exists['deleted'] != 'on') {
if ($exists['status'] == 3 || $exists['status'] == 2) { if ($exists['status'] == 3 || $exists['status'] == 2) {
addUpDevice($network_id, getmypid()); addUpDevice($network_id, (int) getmypid());
if ($exists['snmp_version'] > 0) { if ($exists['snmp_version'] > 0) {
addSNMPDevice($network_id, getmypid()); addSNMPDevice($network_id, (int) getmypid());
} }
// Rerun data queries if specified // Rerun data queries if specified
@@ -702,8 +702,8 @@ function discoverDevices(int $network_id, int $thread) : bool {
$hostname = gethostbyaddr($device['ip_address']); $hostname = gethostbyaddr($device['ip_address']);
if ($hostname != $device['ip_address']) { if ($hostname != $device['ip_address']) {
if (str_contains($hostname, '.')) { if (str_contains((string) $hostname, '.')) {
$hostname = substr($hostname, 0, strpos($hostname, '.') - 1); $hostname = substr((string) $hostname, 0, strpos((string) $hostname, '.') - 1);
} }
} }
@@ -745,7 +745,7 @@ function discoverDevices(int $network_id, int $thread) : bool {
$stats['snmp']++; $stats['snmp']++;
addSNMPDevice($network_id, getmypid()); addSNMPDevice($network_id, (int) getmypid());
automation_debug(' Responded'); automation_debug(' Responded');
@@ -924,10 +924,10 @@ function discoverDevices(int $network_id, int $thread) : bool {
} else { } else {
if ($exists['deleted'] != 'on') { if ($exists['deleted'] != 'on') {
if ($exists['status'] == 3 || $exists['status'] == 2) { if ($exists['status'] == 3 || $exists['status'] == 2) {
addUpDevice($network_id, getmypid()); addUpDevice($network_id, (int) getmypid());
if ($exists['snmp_version'] > 0) { if ($exists['snmp_version'] > 0) {
addSNMPDevice($network_id, getmypid()); addSNMPDevice($network_id, (int) getmypid());
} }
// Rerun data queries if specified // Rerun data queries if specified
+4 -4
View File
@@ -345,7 +345,7 @@ if ($child == false) {
cacti_log('INFO: Boost unregistering master process', true, 'BOOST'); cacti_log('INFO: Boost unregistering master process', true, 'BOOST');
unregister_process('boost', 'master', POLLER_ID, getmypid()); unregister_process('boost', 'master', POLLER_ID, (int) getmypid());
// log the end time of the process // log the end time of the process
set_config_option('boost_last_end_time', time()); set_config_option('boost_last_end_time', time());
@@ -426,9 +426,9 @@ function sig_handler(int $signo) : void {
} }
if ($child) { if ($child) {
unregister_process('boost', 'child', $child, getmypid()); unregister_process('boost', 'child', $child, (int) getmypid());
} else { } else {
unregister_process('boost', 'master', POLLER_ID, getmypid()); unregister_process('boost', 'master', POLLER_ID, (int) getmypid());
} }
exit; exit;
@@ -1239,7 +1239,7 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
$unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'], $unused_cache) : []; $unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'], $unused_cache) : [];
} }
foreach ($values as $value) { foreach (($values ?: []) as $value) {
$matches = explode(':', $value); $matches = explode(':', $value);
if (cacti_sizeof($matches) == 2) { if (cacti_sizeof($matches) == 2) {
+2 -2
View File
@@ -393,9 +393,9 @@ function sig_handler(int $signo) : void {
} }
if ($type == 'master') { if ($type == 'master') {
unregister_process('commands', $type, $poller_id, getmypid()); unregister_process('commands', $type, $poller_id, (int) getmypid());
} else { } else {
unregister_process('commands', $type, $host_id + 1000, getmypid()); unregister_process('commands', $type, $host_id + 1000, (int) getmypid());
} }
exit(1); exit(1);
+2 -2
View File
@@ -90,7 +90,7 @@ if (cacti_sizeof($parms)) {
break; break;
case '--child': case '--child':
$thread_id = $value; $thread_id = (int) $value;
break; break;
case '--version': case '--version':
@@ -482,7 +482,7 @@ function sig_handler($signo) : void {
dsstats_kill_running_processes(); dsstats_kill_running_processes();
} }
unregister_process('dsstats', $type, $thread_id, getmypid()); unregister_process('dsstats', $type, $thread_id, (int) getmypid());
exit(1); exit(1);
default: default:
+12 -3
View File
@@ -619,7 +619,11 @@ function logrotate_file_rotate(string $name, string $log, object $date) : int {
if (rename($log, $log . '-' . $ext)) { if (rename($log, $log . '-' . $ext)) {
touch($log); touch($log);
chown($log, $owner); chown($log, $owner);
chgrp($log, $group);
if ($group !== false) {
chgrp($log, $group);
}
chmod($log, $perms); chmod($log, $perms);
cacti_log('Cacti Log Rotation - Created ' . $name . ' Log : ' . basename($log) . '-' . $ext, true, 'MAINT'); cacti_log('Cacti Log Rotation - Created ' . $name . ' Log : ' . basename($log) . '-' . $ext, true, 'MAINT');
@@ -911,8 +915,13 @@ function rrdclean_create_path(string $path) : bool {
// NOTE: chown/chgrp fails for non-root users, checking their // NOTE: chown/chgrp fails for non-root users, checking their
// result is therefore irrelevant // result is therefore irrelevant
@chown($path, $owner_id); if ($owner_id !== false) {
@chgrp($path, $group_id); @chown($path, $owner_id);
}
if ($group_id !== false) {
@chgrp($path, $group_id);
}
} }
} else { } else {
cacti_log("ERROR: RRDfile Maintenance unable to create directory '" . $path . "'", false, 'MAINT'); cacti_log("ERROR: RRDfile Maintenance unable to create directory '" . $path . "'", false, 'MAINT');
+1 -1
View File
@@ -293,7 +293,7 @@ function process_poller_output_rt(mixed $rrdtool_pipe, string $poller_id, int $i
); );
if (cacti_sizeof($values)) { if (cacti_sizeof($values)) {
foreach ($values as $value) { foreach (($values ?: []) as $value) {
$matches = explode(':', $value); $matches = explode(':', $value);
if (isset($rrd_field_names[$matches[0]])) { if (isset($rrd_field_names[$matches[0]])) {
+2 -2
View File
@@ -179,7 +179,7 @@ rrdcheck_debug('Polling Ending');
set_config_option('rrdcheck_last_run_time', time()); set_config_option('rrdcheck_last_run_time', time());
if (!$forcerun) { if (!$forcerun) {
unregister_process('rrdcheck', $type, $thread_id); unregister_process('rrdcheck', $type, (int) $thread_id);
} }
exit(0); exit(0);
@@ -287,7 +287,7 @@ function sig_handler(int $signo) : void {
rrdcheck_kill_running_processes(); rrdcheck_kill_running_processes();
} }
unregister_process('rrdcheck', $type, $thread_id, getmypid()); unregister_process('rrdcheck', $type, $thread_id, (int) getmypid());
exit(1); exit(1);
default: default:
+1 -1
View File
@@ -266,7 +266,7 @@ function kill_spikes(array $templates, int &$found) : int {
$response = exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' . $response = exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' .
cacti_escapeshellarg(CACTI_PATH_CLI . '/removespikes.php') . ' --rrdfile=' . cacti_escapeshellarg($f) . ($debug ? ' --debug' : '')); cacti_escapeshellarg(CACTI_PATH_CLI . '/removespikes.php') . ' --rrdfile=' . cacti_escapeshellarg($f) . ($debug ? ' --debug' : ''));
if (substr_count($response, 'Spikes Found and Remediated')) { if (substr_count((string) $response, 'Spikes Found and Remediated')) {
$found++; $found++;
} }
+1 -1
View File
@@ -401,7 +401,7 @@ function poller_check_duplicate_poller_id(int $poller_id, string $hostname, stri
$ip_hostnames[$hostname] = $hostname; $ip_hostnames[$hostname] = $hostname;
if (cacti_sizeof($addresses)) { if (cacti_sizeof($addresses)) {
foreach ($addresses as $address) { foreach (($addresses ?: []) as $address) {
if (isset($address['target'])) { if (isset($address['target'])) {
$ip_hostnames[$address['host']] = $address['host']; $ip_hostnames[$address['host']] = $address['host'];
} }
+4 -4
View File
@@ -147,10 +147,10 @@ $start = microtime(true);
$include_file = ''; $include_file = '';
if (CACTI_SERVER_OS == 'win32') { if (CACTI_SERVER_OS == 'win32') {
cacti_log('DEBUG: GETCWD: ' . cacti_strtolower(strtr(getcwd(),'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG); cacti_log('DEBUG: GETCWD: ' . cacti_strtolower(strtr((string) getcwd(),'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
cacti_log('DEBUG: DIRNAM: ' . cacti_strtolower(strtr(__DIR__,'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG); cacti_log('DEBUG: DIRNAM: ' . cacti_strtolower(strtr(__DIR__,'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
} else { } else {
cacti_log('DEBUG: GETCWD: ' . strtr(getcwd(),'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG); cacti_log('DEBUG: GETCWD: ' . strtr((string) getcwd(),'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
cacti_log('DEBUG: DIRNAM: ' . strtr(__DIR__,'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG); cacti_log('DEBUG: DIRNAM: ' . strtr(__DIR__,'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
} }
@@ -237,13 +237,13 @@ while (1) {
case 0: case 0:
// cut off include file as first part of input string and keep rest for further parsing // cut off include file as first part of input string and keep rest for further parsing
$include_file = trim(substr($input_string,0,$pos)); $include_file = trim(substr($input_string,0,$pos));
$input_string = trim(strchr($input_string, ' ')) . ' '; $input_string = trim((string) strchr($input_string, ' ')) . ' ';
break; break;
case 1: case 1:
// cut off function as second part of input string and keep rest for further parsing // cut off function as second part of input string and keep rest for further parsing
$function = trim(substr($input_string,0,$pos), "' "); $function = trim(substr($input_string,0,$pos), "' ");
$input_string = trim(strchr($input_string, ' ')) . ' '; $input_string = trim((string) strchr($input_string, ' ')) . ' ';
break; break;
case 2: case 2:
+1 -1
View File
@@ -169,7 +169,7 @@ print 'valid:' . $user_logins_valid .
function get_session_save_path() : mixed { function get_session_save_path() : mixed {
if (session_save_path() !== '') { if (session_save_path() !== '') {
// if default temp path is not in use // if default temp path is not in use
return realpath(session_save_path()); return realpath((string) session_save_path());
} }
if (function_exists('sys_get_temp_dir')) { if (function_exists('sys_get_temp_dir')) {
+1 -1
View File
@@ -17,4 +17,4 @@ $cmd .= " status | awk '{print \$6 }'";
$sql = shell_exec($cmd); $sql = shell_exec($cmd);
// Cacti expects 'U' on error, not empty string or 0. // Cacti expects 'U' on error, not empty string or 0.
print trim($sql ?? '') ?: 'U'; print trim((string) $sql) ?: 'U';
+1 -1
View File
@@ -38,7 +38,7 @@ function ss_apache_stats(string $host = '', string $section = 'all') : mixed {
$url = "http://$host/server-status?auto"; $url = "http://$host/server-status?auto";
$result = file_get_contents($url); $result = file_get_contents($url);
$array_result = []; $array_result = [];
$array_result = explode("\n",$result); $array_result = explode("\n",(string) $result);
$i = 0; $i = 0;
$output = ''; $output = '';
$line = []; $line = [];
+1 -1
View File
@@ -125,7 +125,7 @@ function ss_net_snmp_disk_bytes(mixed $host_id_or_hostname = '') : string {
if (!db_table_exists('host_value_cache')) { if (!db_table_exists('host_value_cache')) {
if (is_file("$tmpdir/$tmpfile")) { if (is_file("$tmpdir/$tmpfile")) {
$previous = json_decode(file_get_contents("$tmpdir/$tmpfile"), true); $previous = json_decode((string) file_get_contents("$tmpdir/$tmpfile"), true);
$found = true; $found = true;
} }
} else { } else {
+1 -1
View File
@@ -126,7 +126,7 @@ function ss_net_snmp_disk_io(mixed $host_id_or_hostname = '') : string {
if (!db_table_exists('host_value_cache')) { if (!db_table_exists('host_value_cache')) {
if (file_exists("$tmpdir/$tmpfile")) { if (file_exists("$tmpdir/$tmpfile")) {
$previous = json_decode(file_get_contents("$tmpdir/$tmpfile"), true); $previous = json_decode((string) file_get_contents("$tmpdir/$tmpfile"), true);
$found = true; $found = true;
} }
} else { } else {
+1 -1
View File
@@ -247,7 +247,7 @@ function ss_netsnmp_lmsensors(int $host_id = 0, string $sensor_type = '', string
(array_key_exists('value', $snmp_array[0]) == false) || (array_key_exists('value', $snmp_array[0]) == false) ||
(substr($snmp_array[0]['value'],0,16) == 'No Such Instance') || (substr($snmp_array[0]['value'],0,16) == 'No Such Instance') ||
(is_numeric($snmp_array[0]['value']) == false) || (is_numeric($snmp_array[0]['value']) == false) ||
(trim($snmp_array[0]['value']) == '')) { (trim((string) $snmp_array[0]['value']) == '')) {
cacti_log(sprintf('WARNING: Device with ID %s Does not appear to have lmsensors installed!', $host_id), false, 'LMSENSORS'); cacti_log(sprintf('WARNING: Device with ID %s Does not appear to have lmsensors installed!', $host_id), false, 'LMSENSORS');
return null; return null;
+7 -7
View File
@@ -46,12 +46,12 @@ function ss_sql() : string {
$result = shell_exec($cmd) ?? ''; $result = shell_exec($cmd) ?? '';
$result = preg_replace('/: /', ':', $result); $result = preg_replace('/: /', ':', (string) $result);
$result = preg_replace('/ /', ' ', $result); $result = preg_replace('/ /', ' ', (string) $result);
$result = preg_replace('/Slow queries/', 'SlowQueries', $result); $result = preg_replace('/Slow queries/', 'SlowQueries', (string) $result);
$result = preg_replace('/Open tables/', 'OpenTables', $result); $result = preg_replace('/Open tables/', 'OpenTables', (string) $result);
$result = preg_replace('/Queries per second avg/', 'QPS', $result); $result = preg_replace('/Queries per second avg/', 'QPS', (string) $result);
$result = preg_replace('/Flush tables/', 'FlushTables', $result); $result = preg_replace('/Flush tables/', 'FlushTables', (string) $result);
return trim($result) ?: 'U'; return trim((string) $result) ?: 'U';
} }
+11 -7
View File
@@ -89,14 +89,18 @@ if ($mibcache_changed !== null || file_exists($path_mibcache) === false) {
// create lock file // create lock file
$lock = fopen($path_mibcache_lock, 'w'); $lock = fopen($path_mibcache_lock, 'w');
// Note: If SNMPAgent plugin has been disabled the cache will be truncated automatically if (is_resource($lock)) {
if (cacti_sizeof($cache)) { // Note: If SNMPAgent plugin has been disabled the cache will be truncated automatically
file_put_contents($path_mibcache, '<?php $cache = ' . var_export($cache, true) . ';', LOCK_EX); if (cacti_sizeof($cache)) {
} file_put_contents($path_mibcache, '<?php $cache = ' . var_export($cache, true) . ';', LOCK_EX);
}
// destroy lock file // destroy lock file
fclose($lock); fclose($lock);
unlink($path_mibcache_lock); unlink($path_mibcache_lock);
} else {
cacti_log('WARNING: Unable to open MIB cache lock file; skipping cache rebuild to avoid clobbering a concurrent writer.', false, 'SNMPAGENT');
}
} }
return; return;
+3 -3
View File
@@ -93,7 +93,7 @@ if (cacti_strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
gc_enable(); gc_enable();
while (true) { while (true) {
$input = trim(fgets(STDIN)); $input = trim((string) fgets(STDIN));
switch($input) { switch($input) {
case '': case '':
@@ -104,7 +104,7 @@ while (true) {
break; break;
case 'get': case 'get':
$oid = trim(fgets(STDIN)); $oid = trim((string) fgets(STDIN));
if ($data = cache_read($oid)) { if ($data = cache_read($oid)) {
fwrite(STDOUT, $oid . $eol . (isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') . $eol . $data['value'] . $eol); fwrite(STDOUT, $oid . $eol . (isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') . $eol . $data['value'] . $eol);
@@ -114,7 +114,7 @@ while (true) {
break; break;
case 'getnext': case 'getnext':
$oid = trim(fgets(STDIN)); $oid = trim((string) fgets(STDIN));
if ($next_oid = cache_get_next($oid)) { if ($next_oid = cache_get_next($oid)) {
if ($data = cache_read($next_oid)) { if ($data = cache_read($next_oid)) {
+5 -5
View File
@@ -1175,7 +1175,7 @@ function show_database_tables() : void {
function show_cacti_changelog() : void { function show_cacti_changelog() : void {
$changelog = file(CACTI_PATH_BASE . '/CHANGELOG'); $changelog = file(CACTI_PATH_BASE . '/CHANGELOG');
foreach ($changelog as $s) { foreach (($changelog ?: []) as $s) {
if (trim($s) == '') { if (trim($s) == '') {
continue; continue;
} }
@@ -2020,7 +2020,7 @@ function show_tech_environment() : void {
if ($php_binary != '' && file_exists($php_binary) && is_executable($php_binary)) { if ($php_binary != '' && file_exists($php_binary) && is_executable($php_binary)) {
$cli_json = shell_exec(cacti_escapeshellcmd($php_binary) . ' -q ' . cacti_escapeshellarg(CACTI_PATH_INSTALL . '/cli_check.php') . ' extensions'); $cli_json = shell_exec(cacti_escapeshellcmd($php_binary) . ' -q ' . cacti_escapeshellarg(CACTI_PATH_INSTALL . '/cli_check.php') . ' extensions');
$cli_ext = @json_decode($cli_json, true); $cli_ext = @json_decode((string) $cli_json, true);
if (is_array($cli_ext)) { if (is_array($cli_ext)) {
foreach ($cli_ext as $name => $ext) { foreach ($cli_ext as $name => $ext) {
@@ -2176,7 +2176,7 @@ function support_redact(string $value) : string {
$value = preg_replace_callback('/(?:[0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}/', function ($m) { $value = preg_replace_callback('/(?:[0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}/', function ($m) {
return filter_var($m[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false ? '<ipv6>' : $m[0]; return filter_var($m[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false ? '<ipv6>' : $m[0];
}, $value); }, $value);
$value = preg_replace('/\b(?:\d{1,3}\.){3}\d{1,3}\b/', '<ipv4>', $value); $value = preg_replace('/\b(?:\d{1,3}\.){3}\d{1,3}\b/', '<ipv4>', (string) $value);
// FQDNs (foo.bar.example). The alphabetic TLD requirement leaves version // FQDNs (foo.bar.example). The alphabetic TLD requirement leaves version
// numbers such as 1.7.2 untouched. This must run before the node-name // numbers such as 1.7.2 untouched. This must run before the node-name
@@ -2184,7 +2184,7 @@ function support_redact(string $value) : string {
// in "db01.local"), masking the node name first would strip the prefix and // in "db01.local"), masking the node name first would strip the prefix and
// leave a bare suffix ("local") that no longer looks like an FQDN, leaking // leave a bare suffix ("local") that no longer looks like an FQDN, leaking
// part of the domain. // part of the domain.
$value = preg_replace('/\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}\b/', '<host>', $value); $value = preg_replace('/\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}\b/', '<host>', (string) $value);
// Replace this host's own node name wherever it appears (php_uname, SNMP banner, etc.). // Replace this host's own node name wherever it appears (php_uname, SNMP banner, etc.).
$node = function_exists('php_uname') ? php_uname('n') : ''; $node = function_exists('php_uname') ? php_uname('n') : '';
@@ -2194,7 +2194,7 @@ function support_redact(string $value) : string {
} }
// /home/<user>/ and /Users/<user>/ path segments. // /home/<user>/ and /Users/<user>/ path segments.
$value = preg_replace('#/(?:home|Users)/[^/\s]+#', '/home/<redacted>', $value); $value = preg_replace('#/(?:home|Users)/[^/\s]+#', '/home/<redacted>', (string) $value);
return $value; return $value;
} }
+2 -2
View File
@@ -62,7 +62,7 @@ function form_save() : void {
// file upload // file upload
$fp = fopen($_FILES['import_file']['tmp_name'],'r'); $fp = fopen($_FILES['import_file']['tmp_name'],'r');
$xml_data = fread($fp,filesize($_FILES['import_file']['tmp_name'])); $xml_data = fread($fp,filesize($_FILES['import_file']['tmp_name']));
fclose($fp); is_resource($fp) && fclose($fp);
} else { } else {
header('Location: templates_import.php'); header('Location: templates_import.php');
@@ -101,7 +101,7 @@ function form_save() : void {
foreach ($_POST as $var => $val) { foreach ($_POST as $var => $val) {
if (str_contains($var, 'chk_')) { if (str_contains($var, 'chk_')) {
$id = base64_decode(str_replace('chk_', '', $var), true); $id = base64_decode(str_replace('chk_', '', $var), true);
$id = json_decode($id, true); $id = json_decode((string) $id, true);
if (isset($id['hash'])) { if (isset($id['hash'])) {
$import_hashes[] = $id['hash']; $import_hashes[] = $id['hash'];
+2 -1
View File
@@ -67,7 +67,8 @@ test('sql.php uses no bare escapeshellarg calls', function () use ($sqlPhpPath)
test('sql.php handles null return from shell_exec', function () use ($sqlPhpPath) { test('sql.php handles null return from shell_exec', function () use ($sqlPhpPath) {
$contents = file_get_contents($sqlPhpPath); $contents = file_get_contents($sqlPhpPath);
expect($contents)->toContain("?? ''"); // (string) cast coerces both null and false from shell_exec() to ''.
expect($contents)->toContain('(string) $sql');
}); });
test('sql.php returns U on empty/null shell_exec output', function () use ($sqlPhpPath) { test('sql.php returns U on empty/null shell_exec output', function () use ($sqlPhpPath) {
+2 -2
View File
@@ -64,9 +64,9 @@ test('DOMPurify is pinned and generated from the matching npm release', () => {
const packageJson = JSON.parse(readFileSync('package.json', 'utf8')); const packageJson = JSON.parse(readFileSync('package.json', 'utf8'));
const source = 'node_modules/dompurify/dist/purify.js'; const source = 'node_modules/dompurify/dist/purify.js';
assert.equal(packageJson.dependencies.dompurify, '3.4.15'); assert.equal(packageJson.dependencies.dompurify, '3.4.16');
assert.equal(assetMap[source], 'include/js/purify.js'); assert.equal(assetMap[source], 'include/js/purify.js');
assert.match(readFileSync(source, 'utf8'), /DOMPurify 3\.4\.15/); assert.match(readFileSync(source, 'utf8'), /DOMPurify 3\.4\.16/);
}); });
test("screenfull's ESM export is rewritten to a global assignment", () => { test("screenfull's ESM export is rewritten to a global assignment", () => {
@@ -67,7 +67,7 @@ cmd_exec ./lib/poller.php $fp = popen($command, 'rb');
cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' ' . $redirect_args . ' &'); cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' ' . $redirect_args . ' &');
cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' > /dev/null 2>&1 &'); cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' > /dev/null 2>&1 &');
cmd_exec ./lib/poller.php $output = shell_exec($command); cmd_exec ./lib/poller.php $output = shell_exec($command);
cmd_exec ./lib/poller.php $setsid_path = trim(shell_exec('which setsid 2>/dev/null') ?? ''); cmd_exec ./lib/poller.php $setsid_path = trim((string) shell_exec('which setsid 2>/dev/null'));
cmd_exec ./lib/poller.php $process = @proc_open($command, $descriptors, $pipes, null, null, ['bypass_shell' => true]); cmd_exec ./lib/poller.php $process = @proc_open($command, $descriptors, $pipes, null, null, ['bypass_shell' => true]);
cmd_exec ./lib/poller.php $process = proc_open('exec ' . $cmd_full, $descriptors, $pipes); cmd_exec ./lib/poller.php $process = proc_open('exec ' . $cmd_full, $descriptors, $pipes);
cmd_exec ./lib/poller.php * of the proc_open() and proc_close() functions (php 4.3+) cmd_exec ./lib/poller.php * of the proc_open() and proc_close() functions (php 4.3+)
Can't render this file because it contains an unexpected character in line 22 and column 251.
@@ -67,7 +67,7 @@ cmd_exec ./lib/poller.php $fp = popen($command, 'rb');
cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' ' . $redirect_args . ' &'); cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' ' . $redirect_args . ' &');
cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' > /dev/null 2>&1 &'); cmd_exec ./lib/poller.php exec($safe_filename . ' ' . $args . ' > /dev/null 2>&1 &');
cmd_exec ./lib/poller.php $output = shell_exec($command); cmd_exec ./lib/poller.php $output = shell_exec($command);
cmd_exec ./lib/poller.php $setsid_path = trim(shell_exec('which setsid 2>/dev/null') ?? ''); cmd_exec ./lib/poller.php $setsid_path = trim((string) shell_exec('which setsid 2>/dev/null'));
cmd_exec ./lib/poller.php $process = @proc_open($command, $descriptors, $pipes, null, null, ['bypass_shell' => true]); cmd_exec ./lib/poller.php $process = @proc_open($command, $descriptors, $pipes, null, null, ['bypass_shell' => true]);
cmd_exec ./lib/poller.php $process = proc_open('exec ' . $cmd_full, $descriptors, $pipes); cmd_exec ./lib/poller.php $process = proc_open('exec ' . $cmd_full, $descriptors, $pipes);
cmd_exec ./lib/poller.php * of the proc_open() and proc_close() functions (php 4.3+) cmd_exec ./lib/poller.php * of the proc_open() and proc_close() functions (php 4.3+)
@@ -678,7 +678,7 @@ header_redirect ./utilities.php header('Location: utilities.php');
header_redirect ./utilities.php header('Location: utilities.php?action=view_poller_cache'); header_redirect ./utilities.php header('Location: utilities.php?action=view_poller_cache');
header_redirect ./utilities.php header('Location: utilities.php?action=view_snmpagent_cache'); header_redirect ./utilities.php header('Location: utilities.php?action=view_snmpagent_cache');
xml_parse ./cli/genmanifest.php $xmldata = simplexml_load_string($data); xml_parse ./cli/genmanifest.php $xmldata = simplexml_load_string($data);
xml_parse ./cli/rrdresize.php $rrd_data = json_decode(json_encode(simplexml_load_string($file_dump)), true); xml_parse ./cli/rrdresize.php $rrd_data = json_decode((string) json_encode(simplexml_load_string($file_dump)), true);
xml_parse ./install/functions.php $xmlget = simplexml_load_string($xml); xml_parse ./install/functions.php $xmlget = simplexml_load_string($xml);
xml_parse ./lib/import.php $xmlget = simplexml_load_string($data); xml_parse ./lib/import.php $xmlget = simplexml_load_string((string) $data);
xml_parse ./lib/import.php $xmlget = simplexml_load_string($xml); xml_parse ./lib/import.php $xmlget = simplexml_load_string($xml);
Can't render this file because it contains an unexpected character in line 22 and column 251.
+1 -1
View File
@@ -641,7 +641,7 @@ function sort_recursive(int $branch, int $tree_id) : void {
} }
function leaves_exist(int $parent, int $tree_id) : int { function leaves_exist(int $parent, int $tree_id) : int {
return db_fetch_assoc_prepared('SELECT COUNT(*) return (int) db_fetch_cell_prepared('SELECT COUNT(*)
FROM graph_tree_items FROM graph_tree_items
WHERE graph_tree_id = ? WHERE graph_tree_id = ?
AND parent = ? AND parent = ?
+8 -3
View File
@@ -189,9 +189,14 @@ function utilities_clear_logfile() : void {
} }
$log_fh = fopen($logfile, 'w'); $log_fh = fopen($logfile, 'w');
fwrite($log_fh, __('%s - WEBUI NOTE: Cacti Log Cleared from Web Management Interface.', $date) . PHP_EOL);
fclose($log_fh); if (is_resource($log_fh)) {
print '<tr><td>' . __('Cacti Log Cleared') . '</td></tr>'; fwrite($log_fh, __('%s - WEBUI NOTE: Cacti Log Cleared from Web Management Interface.', $date) . PHP_EOL);
fclose($log_fh);
print '<tr><td>' . __('Cacti Log Cleared') . '</td></tr>';
} else {
print "<tr><td class='deviceDown'><b>" . __('Error: Unable to clear log, no write permissions.') . '<b></td></tr>';
}
} else { } else {
print "<tr><td class='deviceDown'><b>" . __('Error: Unable to clear log, no write permissions.') . '<b></td></tr>'; print "<tr><td class='deviceDown'><b>" . __('Error: Unable to clear log, no write permissions.') . '<b></td></tr>';
} }