mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-28 23:57:30 +09:00
10 KiB
10 KiB
applyTo
| applyTo |
|---|
| **/*.php |
Cacti PHP instructions
Use these instructions for PHP changes in Cacti organization repositories. Repository-local AGENTS.md, .github/copilot-instructions.md, CONTRIBUTING.md, Composer scripts, and CI workflows take precedence when they are more specific.
Establish the repository contract first
- Before editing, inspect the target branch,
composer.json, CI matrix, test configuration, formatter configuration, and nearby code. Do not assume that Cacti core and every plugin support the same PHP or Cacti versions. - Write syntax and dependencies for the lowest PHP version supported by the target repository and branch. For plugins, also respect the Cacti branch/version used by plugin CI.
- Preserve the repository's GPL header, copyright form, bootstrap pattern, changelog process, and established file organization. Do not perform unrelated cleanup or repository-wide formatting.
- Confirm that a reported defect exists on the target branch before fixing it. Cacti release branches and
developcan differ substantially.
PHP style
- Indent PHP with tabs, displayed at four spaces. Use Unix line endings, remove trailing whitespace, and leave one newline at end of file.
- Put opening braces on the same line for functions, classes, closures, and control structures.
- Prefer single-quoted strings. Use double quotes only when interpolation or escape handling makes them appropriate.
- Use short arrays (
[]), lowercase PHP keywords andtrue,false, andnull, and strict comparisons when the type is known. - Put one space around concatenation and binary operators. Do not add spaces inside array offsets.
- Prefer
foreachand current PHP constructs over removed legacy constructs. Prefer simple string functions when a regular expression is unnecessary; never introduceereg_*. - Preserve readable alignment already used in a touched block, but do not create large whitespace-only diffs.
- Use the repository's PHP CS Fixer configuration when present. Do not replace Cacti's established style with a generic PSR preset.
Cacti architecture and entry points
- Web pages must bootstrap through the repository's established authenticated entry point, normally
include/auth.php; do not bypass authentication or initialize Cacti piecemeal. - CLI scripts must use the established CLI bootstrap, normally
include/cli_check.php. - Use Cacti headers, footers, form helpers, table helpers, URL helpers, and plugin APIs instead of duplicating framework behavior or emitting a parallel UI.
- Follow the common page flow where applicable: initialize defaults, validate request variables, dispatch the action, then render through Cacti's header/footer helpers.
- Plugin changes must preserve the plugin
INFOmetadata and registration conventions. Register hooks and realms through the plugin APIs. AJAX plugin URLs normally includeheader=falsewhen the surrounding Cacti layout must be suppressed. - Reuse shared functions and existing domain helpers before adding a new abstraction. Keep behavior-preserving refactoring limited to the area already being changed.
Input, authorization, CSRF, and output
- Treat all request, session, database, device, SNMP, file, and command output as untrusted at the relevant boundary.
- Do not read
$_GET,$_POST, or$_REQUESTdirectly in new code. Use Cacti request helpers such asget_filter_request_var()/gfrv(),get_request_var()/grv(),get_nfilter_request_var()/gnrv(), and the repository's form validation helpers. - Understand request caching: once
gfrv()has validated a variable, latergrv()orgnrv()calls for that variable retrieve the cached value. Do not add misleading duplicate validation or casts, but ensure every externally controlled variable has an appropriate validation point. - Validate by allowlist and expected type, range, or format. Never rely on escaping as input validation.
- Enforce authorization on the server for every privileged page and action. Hiding a control in the UI is not authorization. For plugins, keep realm registration, upgrade/repair behavior, and action-level permission checks consistent.
- Protect state-changing forms and AJAX requests with Cacti's CSRF mechanism. AJAX posts include
__csrf_magic: csrfMagicTokenunless a repository-local helper supplies it. - Escape at output time for the exact context. Use Cacti's HTML text and attribute helpers; use
html_escape_attr()for attribute contexts. Do not use a text-context escape helper for JavaScript, JSON, URL, or HTML attributes. - Build local URLs with
cacti_url()where available and redirect withcacti_redirect(). Do not redirect to unvalidated user-controlled destinations. - Encode JSON with the repository's safe JSON conventions and return the correct content type. Do not build JSON by concatenating strings.
- Wrap user-visible strings in
__()and pass the plugin text domain where the surrounding plugin does so.
Database access
- Use the database helpers supplied by Cacti or the plugin's established database wrapper. Do not add a second connection layer without a repository-specific need.
- Use prepared helpers such as
db_fetch_row_prepared(),db_fetch_assoc_prepared(), anddb_execute_prepared()whenever values are variable. The same rule applies to plugin-prefixed wrappers. - Never interpolate request data or other untrusted values into SQL. Placeholders bind values, not identifiers; validate dynamic table names, column names, sort directions, and SQL fragments against a strict allowlist before composing SQL.
- Do not quote numeric SQL values. Quote strings through parameter binding. Use
ASfor aliases and explicitINNER JOIN,LEFT JOIN, or other join types. - Avoid
SELECT *in production queries. Select the required columns and check the schema and indexes before changing a performance-sensitive query. - Make schema installation and upgrades idempotent and safe for existing installations. Preserve data unless a clearly named, authorized migration intentionally changes it.
Polling performance
- For polling, script-server, SNMP, subprocess and RRD update changes, follow the detailed polling performance rules in the repository's
.github/copilot-instructions.mdandAGENTS.md. Inspect the actual branch's call chain before adding work to a loop. - Cache shared template metadata once per process or explicit cycle, including empty results, with appropriate invalidation. Avoid repeated per-source metadata reads and caches that grow to millions of entries for a template-level lookup. Preserve source-specific correctness.
- Avoid fixed per-call sleeps and repeated launches, includes or SNMP requests introduced by wrappers. Measure wrapper overhead against direct execution and preserve streaming output, timeouts, exit status and cleanup.
- Verify repeated query/call counts and memory at representative scales. Measure credential-cache benefits separately. Label synthetic results accurately; production throughput claims require representative end-to-end evidence.
Files, commands, logging, and secrets
- Treat file paths and archive contents as untrusted. Constrain them to the intended base directory and reject traversal or unexpected file types.
- Avoid shell execution when a PHP or Cacti API exists. When execution is necessary, keep the executable fixed, validate arguments, and escape each argument with
escapeshellarg(); never concatenate raw input into a command. - Use
cacti_log()and related repository helpers rather than ad hoc log files orerror_log()when application logging is intended. - Do not log credentials, tokens, session identifiers, SNMP secrets, database passwords, or full sensitive request payloads.
- Never commit generated configuration containing secrets. Keep
.distexamples inert and clearly placeholder-based.
Dependencies and generated code
- Do not add, copy, or refresh third-party source trees in the repository. Do not hand-edit Composer-generated autoload files.
- Manage PHP dependencies through Composer when the repository uses it. Update
composer.jsonand the lock file together when a lock file is part of that repository's policy. - Validate dependency changes with
composer validateand a cleancomposer install. Do not runcomposer updateunless the change intentionally updates dependency resolution. - Preserve the configured vendor directory. In Cacti core it may be
include/vendor; plugins commonly consume the Cacti installation's toolchain instead of owning a separate vendor tree.
Tests and verification
- Add or update the smallest relevant automated test for changed behavior. Use the repository's existing Pest/PHPUnit structure and bootstrap; do not impose core's directory layout on plugins that use a different layout.
- Name tests after behavior, not an issue or advisory number. Put the tracking identifier in the test description or docblock when useful.
- Do not declare or conditionally redefine Cacti core functions at test-file scope. Shared Pest collection can make those definitions order-dependent; use the repository's configurable stubs or fixtures.
- Test both the success path and important failure boundaries, especially validation, authorization, CSRF, escaping, SQL construction, upgrades, and compatibility behavior.
- Run the repository-provided checks. Prefer Composer scripts and CI-equivalent commands over invented commands. At minimum, run PHP syntax checks and the focused tests for touched code; when available, also run PHPStan and PHP CS Fixer in dry-run mode.
- For plugins, verify inside a compatible Cacti installation when the change depends on Cacti bootstrap, schema, hooks, realms, polling, or rendered UI. A standalone syntax check is not an integration test.
- Report verification precisely: list commands and PHP versions used, distinguish static analysis from runtime/integration/browser checks, and treat a pull request with zero CI checks as unverified rather than passing.
Completion checklist
- The change supports the target repository's minimum PHP and Cacti versions.
- Request data is validated; privileged actions are authorized and CSRF-protected.
- SQL values use prepared statements and dynamic identifiers are allowlisted.
- Output is escaped for its exact context and visible strings are translatable.
- Existing install and upgrade paths remain safe.
- No secrets, generated dependencies, or unrelated formatting changes were added.
- Relevant lint, formatter, static-analysis, unit, integration, and UI checks were run or explicitly reported as not run.