* fix(plugins): honor version range boundaries and compatibility status
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): preserve null hook diagnostics and enforce dependency versions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): report config failures and confine error attribution
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): guard entrypoint frames and bind realm filenames
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): propagate install hook failures on develop
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): match realm filenames literally
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): defer release entries to final backlog PR
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(plugins): add standard GPL headers
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci(coverage): require 80 percent of changed PHP statements
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): run request coverage with portable path matching
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
plugin_fetch_latest_plugins() now follows each plugin repository's default_branch (fallback develop) for the second fetch, instead of always using the develop branch.
* security: consolidate verified GHSA fixes for develop (batch 4)
Develop counterparts of the 1.2.x batch-4 fixes in #8144, re-verified against
current develop HEAD.
- GHSA-4rmr-wvjq-qxc2: include/auth.php Basic Auth and guest branches fall
through to the per-page realm check instead of returning early.
- GHSA-j67j-wpm4-9g3x: the pre-dispatch update_policy branch in user_admin.php
and user_group_admin.php requires a CSRF-token POST. The denylist -> allowlist
redesign is tracked for 1.3 in #8143.
- GHSA-2p3x-f5jm-rg6p: the View-Graphs -> poller RCE chain is broken by the
realm check (4rmr), the update_policy guard (j67j) and shell-free webhits (x5pw).
- GHSA-x5pw-cg7j-mj4r: scripts/webhits.pl runs wc through a shell-free list-form open.
- GHSA-9737-rqh3-h7fh: names interpolated into raise_message() now use __esc()
across the UI; URL- and HTML-bearing messages are excluded.
- GHSA-9x9h-2577-9w86: the colordropdown input is built as a node and the label
is no longer round-tripped through parseHTML (the list item already used
createTextNode on develop).
- GHSA-h96j-8xhc-2p3w: remote_agent.php authorizes on $_SERVER['REMOTE_ADDR'],
not get_client_addr(), which honours client-settable proxy headers.
Regression guards under tests/Unit/Security/{Auth,Csrf,Xss,ShellInjection}.
php -l, check-changelog.py and the sink/architectural baselines all pass.
* chore: reference PR #8145 on the batch-4 1.3.0-dev CHANGELOG entries
* security: resolve develop merge - keep id-only xmlerror unescaped (matches #8141 h745 test)
* security(GHSA-j67j): use REQUEST_METHOD POST guard instead of raw \ (hardening-pattern-guard)
* security(GHSA-9737): fix review findings - drop double-encoding in __esc, escape missed name sinks, correct plugins format-arg count
* 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>
* fix: accept scalar or array primary in api_plugin_db_table_create()
api_plugin_db_table_create() inline-interpolated $data['primary'] as a string,
so a plugin passing an array primary produced PRIMARY KEY (`Array`) and table
creation failed on a fresh install. Route the primary through
db_format_index_create() (already used for the keys just below), which accepts
either a scalar column name (the legacy string form, required for backward
compatibility) or an array of columns -- matching db_table_create() and
db_update_table().
* tests: cover scalar and array/composite primary DDL in api_plugin_db_table_create()
* fix: allow api_plugin_db_table_create to update, and correct default drift
Mirrors the 1.2.x change so api_plugin_db_table_create() refreshes an
existing plugin table via db_update_table() instead of silently doing
nothing, recording the change in plugin_db_changes as a 'create'.
Also teaches db_update_table() to compare the column default, so a
refresh reconciles a column whose live default has drifted from the
canonical definition (e.g. DEFAULT NULL where the definition specifies
DEFAULT ''). Date/time defaults are left to the type comparison to
avoid churn.
* fix: do not re-record plugin_db_changes when refreshing an existing table
Mirrors the 1.2.x fix: plugin_db_changes has no unique key, so REPLACE INTO
on the update path duplicated the 'create' ownership record on every call and
could mark a pre-existing/shared table as plugin-created (dropped on uninstall
by api_plugin_db_changes_remove()). Update existing tables without inserting
another ownership record.
* Contain plugin archive writes and validate the repository URL
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Use the full Cacti copyright header and reject non-base repository URLs
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Move the path containment helpers into lib/functions.php
They live in lib/functions.php on 1.2.x; keeping a separate module on develop
split the same helpers across two files. plugin_validate_repository_url() goes
to lib/plugins.php with its caller.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: refresh the sink baseline for the containment guard
The archive guard shifts eleven sink line numbers in lib/plugins.php.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: drop the baseline refresh this branch did not need
The sink and hotspot gates compare on a line-agnostic signature, so pure line
drift never tripped them and refreshing only invites merge conflicts.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: remove plugin table entries left behind by uninstalled plugins
A plugin directory can disappear without its uninstall running, and the realm
rows it leaves carry user and group grants a later plugin would inherit.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: append the changelog entry at the end of the issue block
Matches .github/copilot-instructions.md, which appends rather than inserting
in numeric order.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: use the full licence header on the new test files
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: treat CACTI_PATH_LOG as a directory and pass ctor args to the statement class
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: delete orphan realm rows set-based rather than three statements each
The cleanup runs on every render of the plugin page, so the per-orphan loop was
an N+1 in the page path.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: bind the orphan realm ids instead of interpolating them
db_in_clause() builds the list into the statement, which the SQL interpolation
ratchet counts; a sized placeholder list keeps them bound.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* fix(defensive): path containment in package_import.php and plugins.php
package_import.php: package_diff_file() read the local file at
CACTI_PATH_BASE/$filename without verifying the resolved path stays
inside CACTI_PATH_BASE. Add realpath() + str_starts_with() containment
before file_get_contents(). All four tmp-dir write paths also lacked
basename() stripping, allowing $filename to escape $tmp_dir via
traversal sequences. Apply basename() to each $xmlfile assignment.
lib/plugins.php: api_plugin_hook_function() was missing the same
'..' guard that api_plugin_hook() already applies. Add the matching
check with the same SECURITY-level log message.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(defensive): allow package diff of files missing locally
package_diff_file() rejected files that do not exist locally because
realpath() returns false for them. Resolve the parent directory and
re-attach the leaf so new package files still diff while the
containment check holds. Also relax the FILTER_VALIDATE_REGEXP test
to assert only that an E_WARNING fired and restore the error handler
in a finally block.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(defensive): guard plugin name and basename package temp write
Reject '..' in the plugin hook name component and apply basename() to the package_import temp write so neither escapes its directory.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: ignore phpstan function.alreadyNarrowedType identifier
Clears the level 6 alreadyNarrowedType error on lib/data_query.php:2591 that
develop currently emits, matching the sibling narrowing identifiers already ignored.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: preserve id=0 rows when copying plugin_config into temp table
plugins_load_temp_table() creates a temp table LIKE plugin_config and
then does INSERT INTO ... SELECT * FROM plugin_config. plugin_config.id
is AUTO_INCREMENT; Cacti intentionally strips NO_AUTO_VALUE_ON_ZERO on
every connection (database.php line 139). Without that mode, a row with
id=0 is treated as NULL by AUTO_INCREMENT and gets assigned the next
sequence value -- colliding with the existing row that holds that id,
producing ERROR 1062.
Set NO_AUTO_VALUE_ON_ZERO for the single copy INSERT only, then restore
the session sql_mode immediately after, so subsequent AUTO_INCREMENT
inserts (new plugins discovered on disk) are unaffected.
Root cause: a plugin upgrade script inserted into plugin_config with
id=0, which requires NO_AUTO_VALUE_ON_ZERO to round-trip correctly.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: guard api_plugin_moveup/movedown against NULL prior/next id
When a plugin holds the lowest id and moveup is called, the subquery
MAX(id) WHERE id < ? returns NULL. With strict SQL modes stripped on
connect, UPDATE SET id = NULL on a NOT NULL column silently stores 0,
corrupting the primary key and causing subsequent 1062 errors in any
code that copies plugin_config into a temp table.
Same NULL->0 path exists in movedown when the plugin is last.
Add an empty() guard around the three-step swap in both functions so
attempting to move beyond the boundary is a no-op.
Also add the missing !empty($id) guard to movedown (moveup had it,
movedown did not).
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: regression tests for plugin_config id=0 corruption
Source-scan tests verify three structural invariants introduced by the
bug fixes:
1. api_plugin_moveup: the three-step id swap is wrapped in
!empty($prior_id) so calling moveup on the first plugin is a no-op
rather than setting id=NULL (which non-strict MariaDB stores as 0).
2. api_plugin_movedown: same guard for !empty($next_id), plus the outer
!empty($id) guard that was missing.
3. plugins_load_temp_table: @@SESSION.sql_mode is saved before the bulk
INSERT, NO_AUTO_VALUE_ON_ZERO is active during the copy so any id=0
row is preserved literally, and the original mode is restored after.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style: single quotes on db_execute_prepared sql_mode restore
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: replace include_once with require_once for core and plugin loader paths
Core library files in include/global.php are unconditionally required for
Cacti to function; a missing file should produce an immediate fatal error
rather than silently continuing with undefined functions. Convert all
include_once calls to require_once.
Plugin setup.php loaders in lib/plugins.php and cli/audit_database.php
already have file_exists() guards at the two sites that need them. Add a
guard + explicit error/redirect in api_plugin_install() where none existed.
Convert include_once to require_once at all three sites so a file that
passes the existence check but fails to load produces a clear error at
the point of failure.
Closes#6788
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: guard header() in install path with is_web check; tighten test assertion
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: convert remaining include_once to require_once in hook dispatch path
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: remove deprecated curl_close() and imagedestroy() for PHP 8.5
PHP 8.5 deprecates curl_close(), imagedestroy(), and xml_parser_free().
Handles are automatically freed when they go out of scope.
- cli/add_site.php: remove 2 curl_close() calls
- lib/auth.php: remove curl_close() in secpass_check_pwned()
- lib/plugins.php: remove curl_close() in plugin fetch
- lib/reports.php: remove 2 imagedestroy() calls in jpeg2png/png2gif
- lib/rrd.php: remove 3 imagedestroy() calls in graph rendering
No behavioral change; resources are freed implicitly.
Made-with: Cursor
* test: add Pest tests for PHP 8.5 curl_close/imagedestroy removal
- Php85DeprecationsTest: static checks that no curl_close or imagedestroy
calls remain in the 5 changed files
- ReportsImageConversionTest: png2jpeg/png2gif produce valid output
without explicit imagedestroy (resources freed on scope exit)
Made-with: Cursor
---------
Co-authored-by: TheWitness <thewitness@cacti.net>
* cleanup: remove unreachable defensive error logs in aggregate graph item validation
* fix: replace strtolower/strtoupper with locale-independent wrappers
PHP 8.5 deprecates locale-sensitive strtolower() and strtoupper().
Add cacti_strtolower() and cacti_strtoupper() wrappers that use
mb_strtolower/mb_strtoupper with explicit UTF-8 encoding, then
replace all 185 call sites across 65 files.
Existing mb_strtolower() calls (email normalization) are left as-is
since they already specify encoding explicitly.
Includes 18 Pest tests covering ASCII, UTF-8, protocol names, config
values, hex strings, NaN detection, and file extension patterns.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: correct docblock references and month_shift() strpos check
Fix docblocks to reference strtolower()/strtoupper() (the deprecated
PHP builtins) instead of the wrapper names. Fix month_shift() to use
strpos() !== false instead of > 0 so 'month' at position 0 is matched.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* chore: drop unrelated lib/api_aggregate changes
Keep PR scope focused on the issue for this branch.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* refactor: replace strpos() boolean checks with str_contains/str_starts_with
Completes the PHP 8.x string function migration started in lib/.
Converts remaining legacy patterns across 81 files:
- strpos($x, $y) !== false → str_contains($x, $y)
- strpos($x, $y) === false → !str_contains($x, $y)
- strpos($x, $y) != false → str_contains($x, $y)
- bare if (strpos($x, $y)) → if (str_contains($x, $y))
- substr($x, 0, strlen($y)) == $y → str_starts_with($x, $y)
Intentionally preserves strpos() calls that use the return value as
an integer offset:
- user_admin.php / user_group_admin.php (4 calls, ternary for position)
- auth_profile.php (2 calls, offset for substr); guards fixed from
bare if ($pos) to if ($pos !== false)
Behavior fix: ss_esxi_vhosts.php:55 bare strpos() missed position-0
matches; str_contains() now correctly detects 'not installed' at any
position. Adjacent line already used str_contains().
Ref: https://github.com/Cacti/cacti/issues/6641
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: correct dead-code elseif in plugin_display_compat() version comparison
The if/elseif chain in plugin_display_compat() checked >=, >=, >, <
— the second >= was unreachable dead code. Corrected to <= to complete
the operator set (>=, <=, >, <).
Without this fix, <= constraints (e.g. "<=1.2") fell through to the <
branch and were rendered as "< =1.2" instead of "<= 1.2".
This pre-existing bug was exposed when converting strpos() to
str_contains(), which made PHPStan detect the always-false condition.
Ref: https://github.com/Cacti/cacti/issues/6641
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: add limit to explode('=') in CLI argument parsers
17 CLI scripts used explode('=', $parameter) without a limit of 2,
silently truncating values containing = (e.g. --note=a=b parsed as
$value='a' instead of 'a=b'). The other 40 CLI scripts already had
the correct limit.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* Fix#6539 - Allow Standard Cacti Log Files to be Rotated on Demand from the Cacti UI
* QA: php-cs-fixer updates and documentation for lib/database.php
* QA: Update .gitignore for composer files
* QA: Update .gitignore for composer files
* QA: Back off .gitignore change its duplicated
* QA: Fix typing of db_has_permissions
* QA: Fixing typing issue in db_format_index_create
* Update lib/clog_webapi.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* QA: Fix additional code issues
* QA: Applying more defaults to add device
* QA: Fix at the database layer
* QA: Fixes based upon automated testing
* QA: Fix at the database layer
* QA: After new SQL checking
* QA: Skip MacTrack oui database download warnings
* QA: Fixing type issue
* QA: Recommendation from Copilot
* QA: Recommendation from Copilot
* QA: Recommendation from Copilot
* QA: Recommendation from Copilot
* QA: Some minor changes to avoid errors in testing
* QA: Unused variable
* QA: Recommendation from Copilot
* QA: Recommendation from Copilot
* QA: Recommendation from Copilot
* QA: Minor introduced code defect
* QA: Adding some unifying space around concatination
* QA: Consistent comments and new function alias'
* QA: Multi-line comment corrections
* QA: Fix SQL Style
* QA: Missed one function alias
* QA: PHPStan Level 2 and PHPDoc fixes
* QA: PHPStan Level 2 and PHPDoc Fixes
* QA: PHPStan Level 6 Fixes
* QA: Fix lib/xml.php to PHPStan Level 6
* QA: Wrong grep -v
* PHPStan Level 6 for lib/vdef.php
* PHPStan Level 8 for lib/time.php
* QA: Raise PHPStan to Level 6 for lib/database.php
* QA: Remove @deprecated tag from grv()
* QA: Switch to htmle() alias over html_escape()
* QA: More addressing PHPStan issues at Level 6
* QA: Change recommended by Copilot for Readability
* QA: More PHPStan fixes
* QA: More PHPStan fixes
* QA: More PHPStan fixes for lib/utility.php
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: Raise PHPStan to Level 6 More Functions
* QA: More PHPStan fixes at Level 6
* QA: Some phpseclib3 fixups to update to latest
* QA: More fixups for graphing for magic strings
* QA: More PHPStan fixes at Level 6
* QA: Fixing order string type on get_allowed_graphs()
* QA: Fixing improper use of print
* QA: Optimization of color_templates
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Copilot recommendation
* QA: Raise PHPStan to Level 6 More Functions
* QA: Issues insalling Cacti
* QA: Issues insalling Cacti
* QA: Issues insalling Cacti
* QA: Issues insalling Cacti
* QA: Issues insalling Cacti
* QA: Issues testing Cacti
* QA: Copilot recommendation
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: More PHPStan fixes at Level 6
* QA: Installer failing
* Undo ownership changes to remove tar errors
* QA: Updates after php-cs-fixer
* QA: Adding code checks to syntax checking
* QA Change syntax flow language
* QA: Reduce the number of cures
* QA: Use sequentional option
* Change runner to self-hosted for check job
* Fix typo in OS version in workflow file
* Add Git installation step in workflow
Added step to install Git if not already installed.
* Add '-y' flag to apt-get install and update commands
Updated apt-get commands to include '-y' for automatic confirmation.
* Change workflow OS version to 'ubuntu-latest'
Updated the workflow to use 'ubuntu-latest' instead of 'ubuntu:latest' and modified the 'runs-on' configuration.
* Remove sequential option from phpcsfixer script
* Remove PHPCS fixer step from workflow
Removed PHP coding standards check from workflow.
* Move code checks to before plugins
Moving these core checks to before the plugins are installed as we really want to check only the base Cacti here.
* Add Composer validation and caching to start of workflow
* QA: Addressing PHPStan additional
* QA: Restore composer lock file
* QA: Addressing PHPStan additional
* QA: Addressing PHPStan additional
* QA: Complete LDAP Project
* QA: php-cs-fixer doing it's thing
* QA: Syntax is already happening in PHPStan
* QA: The md5 function no longer exists
* QA: Update after ldap changes
* QA: Undo that last password hack
* QA: Attempting to switch to MariaDB 11.8
* QA: Attempting to switch to MariaDB 11.8
* QA: Resolving some issues with PHP8.4
* QA: Resolving some issues with PHP8.4
* QA: Add PHP8.5 to the matrix
* QA: Removing PHP8.5 due to dependency issues
* QA: Add the DB version to the testing output
* QA: Switch back to MySQL for the moment
* QA: More fidelity in reporting
* QA: The pipe must be mixed
* QA: Moving audit_schema.php changes from 1.2.x
* QA: Moving audit_schema.php changes from 1.2.x
* QA: Restore mysql monitoring
* QA: php-cs-fixer issues
* QA: Attempt to roll back to MariaDB 10.6
* QA: Attempt to fix check_all_pages.sh
* QA: Make installer functional again
* QA: Fix installer php-cs-fixer issues
* QA: Type to a string
* QA: Get the database version correctly
* QA: Fix issue with reports in check_all_pages.sh
* QA: Check the server version in the right place
* Feature: Support SHA256 as a new hash for passwords
* QA: Function definition and return typing audit
* QA: Refinement of form types
* QA: Refinement of form types
* QA: Consistency of comments
* QA: Issues with php-cs-fixer and more comments
* QA: More typing issues
* QA: php-cs-fixer on merge conflict resolution
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This removes most entries to $config in the base code. A few new constants were defined to achieve this:
* CACTI_CONNECTION - The status of the current connection
* CACTI_CSRF_SECRET - The path to the csrf secret file
* CACTI_PHP_SNMP - True if php-snmp is installed
* CACTI_WHITELIST - The path to the Cacti Whitelist file if defined
I also moved several $config['poller_id'] to the existing POLLER_ID and move a number of $config['is_web'] to the existing CACTI_WEB constants.
There remain a few artifacts in the code. They will be handled in a separate commit.
* Add Rector
* Add Rector
* Fix "Cashed" misspelling
Also harmonize the phrase with the one below it
* Fix implode error in db_table_create
Only relevant when multiple primary keys
* Fix auth issue, parentheses in the wrong location
Was causing too many arguments to be sent to cacti_sizeof which only take 1, instead of get_allowed_devices.
* Fix issue with session_var not properly using class variable
* Fix pass by reference error in get_allowed_devices
get_allowed_devices has a pass by reference on the "total_rows" field. It is used in several places to pass the total_rows back to a counter. Here though, we are passing a number directly to the function, which errors out with "Uncaught Error: get_allowed_devices(): Argument #4 ($total_rows) cannot be passed by reference". So we will just place a dummy variable in front to catch the pass.
This wasn't caught before because the previous parentheses issue.
* Fix undefined variable "field_array" in html_filter
* Fix undefined function 'get_nfilter_filter_request_var'
* Fix undefined variable 'resizable'
I corrected the function parameter, as that was technically the incorrect spelling
* Fix invalid variable $user_id
* Fix undefined vars in spikekill class
* Fix copy and paste error
Oops
* Forgot to use the dummy variables
* Add missing $
Oops
* Start converting to newer PHP Syntax and Functions
* Test fixing the workflow by install composer
* Lets not valid the composer file right now
Seems we have a few things to fix it in
* Validate composer
* Lite formating changes
* lite formatting
* lite formatting
* lite format changes
* lite format changes
* lite format changes
* lite format changes
* lite format changes
* lite format changes
* lite format changes
* lite format changes
---------
Co-authored-by: TheWitness <thewitness@cacti.net>
* This allows the function to be the arbitrator of whether or not to upgrade.
* This will allow the simplification of the plugin development best practices after 1.3 is rolled out.
* When a plugin is disabled, set a status of Plugin Errors.
* Normalize the status' in the status' array.
* ToDo: The logic for setting plugin status is still a big wonky from my perspective.
* Add a few more checkss for installed plugins missing key files
* Filter and Sort issues
* Column naming to accommodate legacy design
* Add the schema to the default schema.
* Change the last_updated column upon install/upgrade
* Add new api_plugin_upgrade() function to standardize what get's updated when a plugin self upgrades.
* ToDo - Audit Schema