diff --git a/.phpstan.neon b/.phpstan.neon index fdf7671c5..8053af2b6 100644 --- a/.phpstan.neon +++ b/.phpstan.neon @@ -38,6 +38,7 @@ parameters: - identifier: if.alwaysFalse - identifier: notEqual.alwaysFalse - identifier: notEqual.alwaysTrue + - identifier: notIdentical.alwaysTrue - identifier: equal.alwaysTrue - identifier: if.alwaysTrue - identifier: while.alwaysTrue @@ -46,6 +47,7 @@ parameters: - identifier: identical.alwaysFalse - identifier: booleanAnd.leftAlwaysTrue - identifier: booleanAnd.leftAlwaysFalse + - identifier: booleanAnd.alwaysFalse - 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 intval expects array\|bool\|float\|int\|resource\|string\|null, mixed given.$/' diff --git a/api/public/index.php b/api/public/index.php index e49d80854..fee041a3a 100644 --- a/api/public/index.php +++ b/api/public/index.php @@ -74,14 +74,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $verror = validate_parameters($params, $allowed_hosts_filter); if ($verror) { - $response->getBody()->write(json_encode($verror)); + $response->getBody()->write((string) json_encode($verror)); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); 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); @@ -95,14 +95,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $verror = validate_parameters($params, $allowed_host_templates_filter); if ($verror) { - $response->getBody()->write(json_encode($verror)); + $response->getBody()->write((string) json_encode($verror)); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); 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); @@ -112,7 +112,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $infoGroup->get('/graph_list', function (Request $request, Response $response) { $params = $request->getQueryParams(); $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); @@ -126,14 +126,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $verror = validate_parameters($params, $allowed_automation_networks_filter); if ($verror) { - $response->getBody()->write(json_encode($verror)); + $response->getBody()->write((string) json_encode($verror)); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); 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); @@ -148,13 +148,13 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $poller_id = $params['poller_id'] ?? 0; $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'); }); $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); @@ -162,7 +162,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) { }); $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); @@ -170,7 +170,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) { }); $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); @@ -178,7 +178,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) { }); $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); @@ -189,19 +189,19 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $ping_result = db_fetch_row('SELECT 1 from version'); 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'); } - $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'); }); // automation status endpoint $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); @@ -219,14 +219,14 @@ $app->group('/v1', function (RouteCollectorProxy $group) { $verror = validate_parameters($params, $allowed_thold_filter); if ($verror) { - $response->getBody()->write(json_encode($verror)); + $response->getBody()->write((string) json_encode($verror)); cacti_log($verror . ' By HOST: ' . $client_ip, false, 'API'); 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); @@ -234,7 +234,7 @@ $app->group('/v1', function (RouteCollectorProxy $group) { }); $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); diff --git a/auth_changepassword.php b/auth_changepassword.php index d7076eadd..1a132f83f 100644 --- a/auth_changepassword.php +++ b/auth_changepassword.php @@ -318,7 +318,7 @@ if (isrv('ref')) { } if (!$valid && cacti_sizeof($server_info)) { - foreach ($server_info as $record) { + foreach (($server_info ?: []) as $record) { if (isset($record['host']) && $record['host'] == $server_ref) { $valid = true; diff --git a/cli/add_device.php b/cli/add_device.php index 4e5ea3ffa..786e2e403 100755 --- a/cli/add_device.php +++ b/cli/add_device.php @@ -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; } - $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, $snmp_port, $snmp_timeout, $disable, $avail, $ping_method, $ping_port, $ping_timeout, $ping_retries, $notes, diff --git a/cli/add_graphs.php b/cli/add_graphs.php index 0ab375933..759538ad0 100755 --- a/cli/add_graphs.php +++ b/cli/add_graphs.php @@ -429,7 +429,7 @@ if (cacti_sizeof($parms)) { // process the snmp fields if ($graph_type == 'dq' || $graph_type == 'ds' || $listSNMPFields || $listSNMPValues) { - $snmpFields = getSNMPFields($host_id, $dsGraph['snmpQueryId']); + $snmpFields = getSNMPFields($host_id, (int) $dsGraph['snmpQueryId']); if ($listSNMPFields) { 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 = ''; $snmpValueRegex = ''; diff --git a/cli/add_site.php b/cli/add_site.php index 3e8b625a2..b39627aed 100755 --- a/cli/add_site.php +++ b/cli/add_site.php @@ -549,7 +549,7 @@ function fetchCurl(string $url) : string|false { $buffer = curl_exec($curl); - if ($buffer === false) { + if (!is_string($buffer)) { $error = curl_error($curl); echoQuiet('Error: cURL request failed: ' . $error . PHP_EOL); diff --git a/cli/add_tree.php b/cli/add_tree.php index 3b4d4a486..9aeb54b57 100755 --- a/cli/add_tree.php +++ b/cli/add_tree.php @@ -48,7 +48,8 @@ if (cacti_sizeof($parms)) { $siteId = 0; // The ID of the site to add $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; $hostGroupStyle = 1; // 1 = Graph Template, 2 = Data Query Index @@ -104,6 +105,10 @@ if (cacti_sizeof($parms)) { case '--host-id': $hostId = intval($value); + break; + case '--site-id': + $siteId = intval($value); + break; case '--quiet': $quietMode = true; diff --git a/cli/audit_database.php b/cli/audit_database.php index a2a60aa6f..56a9c9d51 100755 --- a/cli/audit_database.php +++ b/cli/audit_database.php @@ -259,7 +259,7 @@ function upgrade_database() : void { $preorder[] = CACTI_PATH_PLUGINS . '/thold'; $preorder[] = CACTI_PATH_PLUGINS . '/syslog'; - foreach ($plugins as $p) { + foreach (($plugins ?: []) as $p) { if (str_contains($p, 'thold')) { // Skip, upgrading this first } elseif (str_contains($p, 'syslog')) { diff --git a/cli/clone_device_template.php b/cli/clone_device_template.php index ad5231aa0..bfbe729f1 100755 --- a/cli/clone_device_template.php +++ b/cli/clone_device_template.php @@ -260,10 +260,14 @@ if (cacti_sizeof($parms)) { if (!$quiet) { $fin = fopen('php://stdin', 'r'); + if ($fin === false) { + exit(1); + } + while (true) { 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') { fclose($fin); diff --git a/cli/float_rrdfiles.php b/cli/float_rrdfiles.php index d7a34880e..51e649413 100755 --- a/cli/float_rrdfiles.php +++ b/cli/float_rrdfiles.php @@ -105,7 +105,7 @@ if (cacti_sizeof($parms)) { break; case '--child': - $thread_id = $value; + $thread_id = (int) $value; break; case '--host-id': @@ -197,7 +197,7 @@ if (!is_numeric($end_time)) { // validate the start and end times are sane 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); } @@ -359,6 +359,8 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s $fp = fopen($tmp_file, 'w'); + $lf = false; + if ($seebug) { $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 * 24 * 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 @@ -397,7 +399,7 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s $line .= PHP_EOL; } elseif ($in_database) { // split the database record into pieces - $parts = preg_split('/[\s]+/', trim($line)); + $parts = preg_split('/[\s]+/', trim($line)) ?: []; $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 != '') { if ($seebug) { 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 { - 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; 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)); - fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n", trim($prev_line), trim($line), trim($nline))); + 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)); + is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n", trim($prev_line), trim($line), trim($nline))); } $line = $nline; } else { 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)); - fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line))); + 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)); + is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line))); } $in_range = false; @@ -468,7 +470,7 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s } if ($seebug) { - fclose($lf); + is_resource($lf) && fclose($lf); } if ($return == 0) { @@ -693,7 +695,7 @@ function sig_handler(int $signo) : void { float_kill_running_processes(); } - unregister_process('rfloat', 'rmaster', $thread_id, getmypid()); + unregister_process('rfloat', 'rmaster', $thread_id, (int) getmypid()); exit(1); default: diff --git a/cli/genmanifest.php b/cli/genmanifest.php index edd8532f6..ff76a9c7d 100755 --- a/cli/genmanifest.php +++ b/cli/genmanifest.php @@ -133,7 +133,7 @@ if (cacti_sizeof($directory)) { pkg_debug('Processing files'); if (cacti_sizeof($files)) { - foreach ($files as $file) { + foreach (($files ?: []) as $file) { pkg_debug("Processing file: $file"); if (is_readable($file)) { diff --git a/cli/import_package.php b/cli/import_package.php index 9b86095af..6cd2f7bf9 100755 --- a/cli/import_package.php +++ b/cli/import_package.php @@ -171,9 +171,9 @@ if (cacti_sizeof($parms)) { $fp = fopen($filename, 'r'); $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); diff --git a/cli/import_template.php b/cli/import_template.php index 188593c39..ea72d06f2 100755 --- a/cli/import_template.php +++ b/cli/import_template.php @@ -125,9 +125,9 @@ if (cacti_sizeof($parms)) { if (file_exists($filename) && is_readable($filename)) { $fp = fopen($filename,'r'); $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); diff --git a/cli/input_whitelist.php b/cli/input_whitelist.php index 11d40070a..997d57c69 100755 --- a/cli/input_whitelist.php +++ b/cli/input_whitelist.php @@ -103,7 +103,7 @@ if ($audit) { 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; $items = cacti_sizeof($input); @@ -148,7 +148,7 @@ if ($audit) { WHERE input_string != ""'); 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 { $input_ws = []; } diff --git a/cli/md5sum.php b/cli/md5sum.php index 2b11e628a..938e9b53e 100755 --- a/cli/md5sum.php +++ b/cli/md5sum.php @@ -166,7 +166,7 @@ if (!$quiet && $debug) { } 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) { printf('ERROR: %s' . PHP_EOL, $e->getMessage()); exit(6); diff --git a/cli/migrate_poller.php b/cli/migrate_poller.php index 15d6d8ae3..09afa174b 100755 --- a/cli/migrate_poller.php +++ b/cli/migrate_poller.php @@ -336,7 +336,7 @@ function migrate_all_devices(int $source_poller, int $dest_poller, bool $quietMo print PHP_EOL; print 'Are you sure you want to continue? (y/N): '; - $confirmation = trim(fgets(STDIN)); + $confirmation = trim((string) fgets(STDIN)); if (cacti_strtolower($confirmation) !== 'y') { 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 'Are you sure you want to continue? (y/N): '; - $confirmation = trim(fgets(STDIN)); + $confirmation = trim((string) fgets(STDIN)); if (cacti_strtolower($confirmation) !== 'y') { print 'Migration cancelled by user' . PHP_EOL; diff --git a/cli/poller_reindex_hosts.php b/cli/poller_reindex_hosts.php index 2945eb810..b6fb245bb 100755 --- a/cli/poller_reindex_hosts.php +++ b/cli/poller_reindex_hosts.php @@ -132,7 +132,7 @@ foreach ($parms as $parameter) { break; case '--child': - $thread_id = $value; + $thread_id = (int) $value; break; case '--force': @@ -440,7 +440,7 @@ function sig_handler(int $signo) : void { reindex_kill_running_processes(); } - unregister_process('reindex', 'rmaster', $thread_id, getmypid()); + unregister_process('reindex', 'rmaster', $thread_id, (int) getmypid()); exit(1); default: diff --git a/cli/rebuild_poller_cache.php b/cli/rebuild_poller_cache.php index 01024a96b..e62fb8ca4 100755 --- a/cli/rebuild_poller_cache.php +++ b/cli/rebuild_poller_cache.php @@ -124,7 +124,7 @@ foreach ($parms as $parameter) { break; case '--child': - $thread_id = $value; + $thread_id = (int) $value; break; case '--force': @@ -398,7 +398,7 @@ function sig_handler(int $signo) : void { 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); default: diff --git a/cli/remove_broken_graphs.php b/cli/remove_broken_graphs.php index 9f4f7204a..3ae5fcc11 100755 --- a/cli/remove_broken_graphs.php +++ b/cli/remove_broken_graphs.php @@ -45,7 +45,7 @@ $columns = 80; if (CACTI_SERVER_OS == 'unix' && stream_isatty(STDIN)) { $stty = shell_exec('stty size'); - $sizes = explode(' ', $stty); + $sizes = explode(' ', (string) $stty); if (!empty($sizes[1])) { $columns = $sizes[1]; diff --git a/cli/repair_database.php b/cli/repair_database.php index d2b0277c1..b521bc72c 100755 --- a/cli/repair_database.php +++ b/cli/repair_database.php @@ -112,7 +112,7 @@ detailed_checks(); snmp_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); printf('NOTE: Pushing out %s Devices after repairs!' . PHP_EOL . PHP_EOL, cacti_sizeof($repaired_hosts)); diff --git a/cli/rrdresize.php b/cli/rrdresize.php index a2c6ab570..faf59db7e 100755 --- a/cli/rrdresize.php +++ b/cli/rrdresize.php @@ -237,7 +237,7 @@ $known_ds_types = [1 => 'GAUGE', 2 => 'COUNTER', 3 => 'DERIVE', 4 => 'ABSOLUTE'] if ($scanned_directory['folders']) { // create backup folder - if (!mkdir($tmp_backup_folder)) { + if (!mkdir((string) $tmp_backup_folder)) { print 'ERROR: Unable to create a backup folder!' . PHP_EOL; exit(1); @@ -556,7 +556,7 @@ if ($scanned_directory['folders']) { // ## log_missing continue; } 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) { f_notify(false, "\033[0;31m[FAILED]\033[0m"); @@ -939,7 +939,7 @@ function rrdtool_parse_info(string $lines) : array { $key_count = count($keys); $pointer = &$store; - foreach ($keys as $key_num => $key) { + foreach (($keys ?: []) as $key_num => $key) { $pointer = &$pointer[$key]; if ($key_num + 1 === $key_count) { @@ -978,7 +978,7 @@ function rrdtool_pipe_execute(string $command, mixed $pipes) : string { $line = fgets($pipes[1], 8092); // 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; } $stdout .= $line; diff --git a/cli/show_perms.php b/cli/show_perms.php index a15799c5b..67a35c56a 100755 --- a/cli/show_perms.php +++ b/cli/show_perms.php @@ -84,7 +84,7 @@ $perms = db_get_permissions(true); $count = 0; if ($output_json) { - print cacti_strtolower(json_encode($perms, JSON_PRETTY_PRINT)); + print cacti_strtolower((string) json_encode($perms, JSON_PRETTY_PRINT)); } else { if ($output_grants) { $pad = str_repeat('-', 20); diff --git a/cli/splice_rrd.php b/cli/splice_rrd.php index 25d0ca739..08f7b6dc7 100755 --- a/cli/splice_rrd.php +++ b/cli/splice_rrd.php @@ -272,8 +272,8 @@ if (!file_exists($rrdtool)) { $response = shell_exec(cacti_escapeshellcmd($rrdtool)); -if (strlen($response)) { - $response_array = explode(' ', $response); +if (strlen((string) $response)) { + $response_array = explode(' ', (string) $response); print 'NOTE: Using ' . $response_array[0] . ' Version ' . $response_array[1] . PHP_EOL; } 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; @@ -815,7 +815,7 @@ function processXML(array &$output) : array { if (cacti_sizeof($output)) { foreach ($output as $line) { if (substr_count($line, '')) { - $line = trim(str_replace('', '', str_replace('', '', $line))); + $line = trim(str_replace('', '', str_replace('', '', (string) $line))); $larray = explode('', $line); $time = trim(str_replace('', '', str_replace('', '', $larray[0]))); diff --git a/cmd.php b/cmd.php index 790d2cc84..664bbd10b 100755 --- a/cmd.php +++ b/cmd.php @@ -351,7 +351,7 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on') } else { $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); } diff --git a/data_source_profiles.php b/data_source_profiles.php index 1410ad877..a1b3ac2bb 100644 --- a/data_source_profiles.php +++ b/data_source_profiles.php @@ -473,7 +473,7 @@ function profile_validate_upload() : bool { 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); diff --git a/graph_image.php b/graph_image.php index 591aa1d4e..2cfbdb8a3 100644 --- a/graph_image.php +++ b/graph_image.php @@ -206,9 +206,9 @@ if ($output !== false && $output != '') { } 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 { - $image = rrdtool_create_error_image($error); + $image = rrdtool_create_error_image((string) $error); } ob_end_clean(); diff --git a/graph_json.php b/graph_json.php index 94d8cedcd..c12bfd76e 100644 --- a/graph_json.php +++ b/graph_json.php @@ -202,11 +202,11 @@ if ($output !== false && $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) { // 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) { $image_data_pos = $image_data_line_end + 1; @@ -216,7 +216,7 @@ if ($output !== false && $output != '') { } } else { // 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) { $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'])) { - $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 { - $image = rrdtool_create_error_image($error); + $image = rrdtool_create_error_image((string) $error); } if (isset($graph_data_array['graph_width'])) { @@ -342,12 +342,12 @@ if ($output !== false && $output != '') { if ($image != false) { $oarray['image'] = base64_encode($image); } 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('Cache-Control: max-age=15'); $json = json_encode($oarray); -header('Content-Length: ' . strlen($json)); +header('Content-Length: ' . strlen((string) $json)); print $json; diff --git a/graph_realtime.php b/graph_realtime.php index 33f8c50c0..e27d568c4 100644 --- a/graph_realtime.php +++ b/graph_realtime.php @@ -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'; if (file_exists($graph_rrd)) { - print base64_encode(file_get_contents($graph_rrd)); + print base64_encode((string) file_get_contents($graph_rrd)); } exit; diff --git a/host.php b/host.php index 7f19397c1..7e229114a 100644 --- a/host.php +++ b/host.php @@ -625,7 +625,7 @@ function host_export() : void { if (cacti_sizeof($hosts)) { $columns = array_keys($hosts[0]); - fputcsv($stdout, $columns); + is_resource($stdout) && fputcsv($stdout, $columns); foreach ($hosts as $h) { // Flatten embedded newlines as the previous export format did, then @@ -641,11 +641,11 @@ function host_export() : void { $h[$hc] = $v; } - fputcsv($stdout, $h); + is_resource($stdout) && fputcsv($stdout, $h); } } - fclose($stdout); + is_resource($stdout) && fclose($stdout); } function host_add_query() : void { @@ -1533,7 +1533,7 @@ function get_device_records(int &$total_rows, int $rows) : mixed { "(host.status = ? OR (status != 2 AND thold_failure_count > 0 AND status_event_count >= thold_failure_count) - AND NOT $host_where_disabled)"; // @phpstan-ignore-line + AND NOT $host_where_disabled)"; $sql_params[] = $status; } else { diff --git a/include/global.php b/include/global.php index 6dae2de5e..c6c9cab85 100644 --- a/include/global.php +++ b/include/global.php @@ -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_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_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 . '/plugins.php'); diff --git a/include/global_languages.php b/include/global_languages.php index be06c8505..8ebd712bd 100644 --- a/include/global_languages.php +++ b/include/global_languages.php @@ -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); } - $origlocales = explode(';', setlocale(LC_ALL, null)); + $origlocales = explode(';', (string) setlocale(LC_ALL, null)); setlocale(LC_ALL, $cacti_locale); $locale = localeconv(); diff --git a/include/global_settings.php b/include/global_settings.php index 187fb1215..b070695cb 100644 --- a/include/global_settings.php +++ b/include/global_settings.php @@ -56,15 +56,18 @@ global $weekly_timespans, $yearly_timespans; // Workaround End -while (false !== ($entry = $dir->read())) { - if ($entry != '.' && $entry != '..') { - if (is_dir(CACTI_PATH_INCLUDE . '/themes/' . $entry)) { - $themes[$entry] = __(ucwords($entry)); +if ($dir !== false) { + while (false !== ($entry = $dir->read())) { + if ($entry != '.' && $entry != '..') { + if (is_dir(CACTI_PATH_INCLUDE . '/themes/' . $entry)) { + $themes[$entry] = __(ucwords($entry)); + } } } + + asort($themes); + $dir->close(); } -asort($themes); -$dir->close(); // tab information $tabs = [ diff --git a/include/session.php b/include/session.php index d8fe346cf..78d99307e 100644 --- a/include/session.php +++ b/include/session.php @@ -128,7 +128,7 @@ function cacti_db_session_destroy(string $id) : bool { 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)) { $old = time() - 14400; } else { diff --git a/install/install.php b/install/install.php index 518649cc8..57c534bdf 100644 --- a/install/install.php +++ b/install/install.php @@ -68,7 +68,7 @@ if (CACTI_SERVER_OS == 'unix') { } elseif (file_exists('/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'; } } diff --git a/install/step_json.php b/install/step_json.php index 24995b40e..746ae9105 100644 --- a/install/step_json.php +++ b/install/step_json.php @@ -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)) { $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('Cache-Control: no-store'); header('X-Content-Type-Options: nosniff'); -header('Content-Length: ' . strlen($json)); +header('Content-Length: ' . strlen((string) $json)); print $json; diff --git a/lib/aggregate.php b/lib/aggregate.php index 8fa371112..9acfbcd13 100644 --- a/lib/aggregate.php +++ b/lib/aggregate.php @@ -1025,7 +1025,7 @@ function auto_title(int $_local_graph_id) : string { // remove all '- |host_*|' occurrences $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); diff --git a/lib/api_automation.php b/lib/api_automation.php index 7ff42f4c4..724beda6c 100644 --- a/lib/api_automation.php +++ b/lib/api_automation.php @@ -1815,7 +1815,7 @@ function build_graph_object_sql_having(array $rule, string $filter) : string { $i = 0; - foreach ($field_names as $column) { + foreach (($field_names ?: []) as $column) { /* The name becomes an identifier in the generated SQL, and it * arrives from snmp_query_field, which a data query XML import * 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 "; if (cacti_sizeof($field_names) > 0) { - foreach ($field_names as $column) { + foreach (($field_names ?: []) as $column) { $field_name = $column['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 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__); 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 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__); 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. * - * @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__); 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']); // 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_branch_data'] = automation_device_rule_export_branches($tree_rule['tree_id'], $tree_rule['tree_item_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']); // collapse the graph rule items $tree_rule['tree_rule_items'] = $tree_rule_items; diff --git a/lib/api_device.php b/lib/api_device.php index 85e3cbcc3..06d1ea3ac 100644 --- a/lib/api_device.php +++ b/lib/api_device.php @@ -1282,8 +1282,8 @@ function api_device_save(int $id, int $device_template_id, string $description, $owner_id = fileowner(CACTI_PATH_RRA); $group_id = filegroup(CACTI_PATH_RRA); - if ((chown($host_dir, $owner_id)) && - (chgrp($host_dir, $group_id))) { + if ($owner_id !== false && $group_id !== false && + chown($host_dir, $owner_id) && chgrp($host_dir, $group_id)) { // permissions set ok } else { 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)) { foreach ($files as $file) { 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)) { foreach ($files as $file) { 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)) { - $archive = base64_encode(file_get_contents($package_file)); + $archive = base64_encode((string) file_get_contents($package_file)); $md5sum = md5($archive); db_execute_prepared('INSERT INTO host_template_archive diff --git a/lib/api_scheduler.php b/lib/api_scheduler.php index b0ad51148..c5ed886d5 100644 --- a/lib/api_scheduler.php +++ b/lib/api_scheduler.php @@ -402,7 +402,7 @@ function api_scheduler_augment_save(array $save, array $post) : array { $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 { // the time is in the future, we are safe to store it $save['next_start'] = date('Y-m-d H:i:s', $start_at); diff --git a/lib/api_tree.php b/lib/api_tree.php index 4aa815d4d..48a795e63 100644 --- a/lib/api_tree.php +++ b/lib/api_tree.php @@ -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['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['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['sort_children_type'] = form_input_validate($sort_children_type, 'sort_children_type', '', true, 3); diff --git a/lib/auth.php b/lib/auth.php index a10b58e19..ab1a1159f 100644 --- a/lib/auth.php +++ b/lib/auth.php @@ -420,7 +420,7 @@ function get_basic_auth_username() : string|false { $found = false; if (cacti_sizeof($records)) { - foreach ($records as $r) { + foreach (($records ?: []) as $r) { if (trim($r) === '') { continue; } @@ -5201,7 +5201,7 @@ function remote_agent_validate_effective_user(mixed $value, ?callable $lookup = 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 FROM user_auth WHERE id = ?', diff --git a/lib/boost.php b/lib/boost.php index d9b90bf32..c0ed3cf99 100644 --- a/lib/boost.php +++ b/lib/boost.php @@ -1777,7 +1777,7 @@ function boost_process_poller_output(int $local_data_id, mixed $rrdtool_pipe = [ $multi_ok = false; if (cacti_sizeof($values)) { - foreach ($values as $value) { + foreach (($values ?: []) as $value) { $matches = explode(':', $value); 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); 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) { - $success = chgrp(CACTI_PATH_RRA . $spath, $group_id); + $success = $group_id !== false && chgrp(CACTI_PATH_RRA . $spath, $group_id); } if (!$success) { diff --git a/lib/clog_webapi.php b/lib/clog_webapi.php index 4f4ce05c7..806216c77 100644 --- a/lib/clog_webapi.php +++ b/lib/clog_webapi.php @@ -181,11 +181,15 @@ function clog_purge_logfile(string $action = 'purge') : void { $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 { raise_message('clog_permissions'); diff --git a/lib/csp_report_endpoint.php b/lib/csp_report_endpoint.php index 591041796..7d595eb5a 100644 --- a/lib/csp_report_endpoint.php +++ b/lib/csp_report_endpoint.php @@ -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. $v = preg_replace('/[\x00-\x1f\x7f]/', ' ', $v); - if (strlen($v) > 256) { - $v = substr($v, 0, 253) . '...'; + if (strlen((string) $v) > 256) { + $v = substr((string) $v, 0, 253) . '...'; } return $v; diff --git a/lib/data_query.php b/lib/data_query.php index de5a2c558..3d6ff435e 100644 --- a/lib/data_query.php +++ b/lib/data_query.php @@ -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:')) { $value = preg_replace('/' . str_replace('OID2HEX/REGEXP:', '', $field_array['source']) . '/', '\\1', $oid); - $parts = explode('.', $value); + $parts = explode('.', (string) $value); $ip_value = ''; 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 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) { 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 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)); @@ -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; - if (mb_detect_encoding($value, mb_detect_order(), true) === false) { - $value = bin2hex($value); + if (mb_detect_encoding((string) $value, mb_detect_order(), true) === false) { + $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)'; @@ -2023,7 +2023,7 @@ function rewrite_snmp_enum_value(string|null $field_name, string|null $value = n foreach ($mapcache[$field_name] as $src => $dst) { 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)); $value = $nvalue; @@ -2799,7 +2799,7 @@ function get_script_query_path(string $args, string $script_path, int $host_id) $extra_arguments = ''; - foreach ($parts as $index => $part) { + foreach (($parts ?: []) as $index => $part) { /* only the hostname/IP placeholders are stripped of '%'; SNMP * community and credential substitutions may legitimately * contain one, so they keep their value unmodified. */ diff --git a/lib/database.php b/lib/database.php index 12d407660..caf4db041 100644 --- a/lib/database.php +++ b/lib/database.php @@ -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(); } @@ -1442,7 +1442,7 @@ function db_cacti_initialized(bool $is_web = true) : bool { $db_conn = false; } - if (!is_object($db_conn)) { + if (!($db_conn instanceof PDO)) { return false; } @@ -2123,12 +2123,12 @@ function db_begin_transaction(mixed $db_conn = false) : bool { global $database_sessions, $database_default, $database_hostname, $database_port; // 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"])) { $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; } - if (!is_object($db_conn)) { + if (!($db_conn instanceof PDO)) { return false; } } @@ -2147,12 +2147,12 @@ function db_commit_transaction(mixed $db_conn = false) : bool { global $database_sessions, $database_default, $database_hostname, $database_port; // 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"])) { $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; } - if (!is_object($db_conn)) { + if (!($db_conn instanceof PDO)) { return false; } } @@ -2179,12 +2179,12 @@ function db_rollback_transaction(mixed $db_conn = false) : bool { global $database_sessions, $database_default, $database_hostname, $database_port; // 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"])) { $db_conn = $database_sessions["$database_hostname:$database_port:$database_default"]; } - if (!is_object($db_conn)) { + if (!($db_conn instanceof PDO)) { return false; } } @@ -2465,7 +2465,7 @@ function db_qstr(mixed $s, mixed $db_conn = false) : string { return 'NULL'; } - if (is_object($db_conn)) { + if ($db_conn instanceof PDO) { 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]); 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); if ($db_grant_perm == 'ALL' || diff --git a/lib/functions.php b/lib/functions.php index 40f74be72..28f08b719 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -557,7 +557,7 @@ function read_user_setting(string $config_name, mixed $default = false, bool $fo [$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']; } elseif ($default !== false) { $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 if (cacti_sizeof($headers)) { - foreach ($headers as $name => $value) { + foreach (($headers ?: []) as $name => $value) { $emailMessage->getHeaders()->addTextHeader($name, $value); } } @@ -9445,7 +9445,7 @@ function get_cacti_base_tables() : array { } if (cacti_sizeof($schema)) { - foreach ($schema as $line) { + foreach (($schema ?: []) as $line) { if (str_contains($line, 'CREATE TABLE')) { $table = str_replace(['CREATE TABLE', '`', '(', ' '], '', $line); $base_tables[] = trim($table); @@ -10076,9 +10076,9 @@ function substring_index(string $subject, string $delim, int $count) : string { } 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 { - 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)); } } diff --git a/lib/graph_variables.php b/lib/graph_variables.php index b5bbe5339..4bf47227e 100644 --- a/lib/graph_variables.php +++ b/lib/graph_variables.php @@ -83,7 +83,7 @@ function rrdtool_function_stats(mixed $local_data_ids, int $start_seconds, int $ include_once(CACTI_PATH_LIBRARY . '/rrd.php'); if (!is_array($local_data_ids)) { - return json_encode([]); + return (string) json_encode([]); } // 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. */ if (!$good_data) { - return json_encode([]); + return (string) json_encode([]); } $stats = []; @@ -217,7 +217,7 @@ function rrdtool_function_stats(mixed $local_data_ids, int $start_seconds, int $ $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 { @@ -716,7 +716,7 @@ function variable_bandwidth_summation(array &$regexp_match_array, array &$graph, switch($regexp_match_array[2]) { 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; case 'total': @@ -724,13 +724,13 @@ function variable_bandwidth_summation(array &$regexp_match_array, array &$graph, if (!empty($graph_element['data_template_rrd_id']) && !empty($graph_element['local_data_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; 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; } diff --git a/lib/html.php b/lib/html.php index ce8404401..54ea1ee41 100644 --- a/lib/html.php +++ b/lib/html.php @@ -766,7 +766,7 @@ function html_header_sort(array $header_items, string $sort_column, string $sort 'columns' => $header_items ]; - print ""; + print ""; $i = 1; @@ -964,7 +964,7 @@ function html_header_sort_checkbox(array $header_items, string $sort_column, str 'columns' => $header_items ]; - print ""; + print ""; foreach ($header_items as $db_column => $display_array) { // 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 ]; - print ""; + print ""; $i = 0; @@ -1205,7 +1205,7 @@ function html_header_checkbox(array $header_items, bool $include_form = true, st 'columns' => $header_items ]; - print ""; + print ""; foreach ($header_items as $item) { if (is_array($item)) { @@ -2327,7 +2327,7 @@ function html_show_tabs_left() : void { ob_start(); api_plugin_hook('top_graph_header_tabs'); - $tab_text = trim(ob_get_clean()); + $tab_text = trim((string) ob_get_clean()); $tab_text = str_replace('', '|', $tab_text); $tab_text = str_replace('')) { + if (str_contains((string) $x, '')) { $binary_signature = base64_decode(trim(str_replace(['', ''], ['', ''], $x)), true); $x = " \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. - $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) { 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); $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) { 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'); if (is_resource($file)) { - $bytesWritten = fwrite($file, $fdata, strlen($fdata)); + $bytesWritten = fwrite($file, $fdata, strlen((string) $fdata)); fclose($file); clearstatcache(); - if ($bytesWritten === strlen($fdata)) { + if ($bytesWritten === strlen((string) $fdata)) { $filestatus[$filename] = __('written'); } else { $filestatus[$filename] = __('incomplete write'); @@ -784,7 +784,7 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha } else { cacti_log('Previewing file: ' . $filename, false, 'IMPORT', POLLER_VERBOSITY_MEDIUM); - $new = md5($fdata); + $new = md5((string) $fdata); if (file_exists($filename)) { $existing = md5_file($filename); @@ -843,7 +843,7 @@ function import_package(string $xmlfile, int $profile_id = 1, bool $remove_orpha $name = $f['name']; if (isset($f['type']) && $f['type'] == 'template') { - $template_data = xml2array($fdata); + $template_data = xml2array((string) $fdata); if (cacti_sizeof($template_data)) { 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(); } else { $output = ob_get_clean(); - $output = explode("\n", $output); + $output = explode("\n", (string) $output); if (cacti_sizeof($output)) { foreach ($output as $line) { diff --git a/lib/installer.php b/lib/installer.php index 034f83524..9454202fe 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -976,7 +976,7 @@ class Installer implements JsonSerializable { // cacti_escapeshellcmd() replaces backslashes on Windows; normalize first $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')); $should_set = false; } @@ -1430,7 +1430,7 @@ class Installer implements JsonSerializable { * * @return array */ - private function getTemplates() : array { // @phpstan-ignore-line + private function getTemplates() : array { $known_templates = install_setup_get_templates(); $db_templates = array_rekey( @@ -1645,7 +1645,7 @@ class Installer implements JsonSerializable { $selected = []; $select_count = 0; - foreach ($known_tables as $known) { + foreach (($known_tables ?: []) as $known) { $table = $known['Name']; $key = $known['Name']; $option = ''; @@ -2226,7 +2226,7 @@ class Installer implements JsonSerializable { $themes = glob($themePath . '*', GLOB_ONLYDIR); $themeOutput = '