mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-29 16:17:14 +09:00
99 lines
10 KiB
Markdown
99 lines
10 KiB
Markdown
---
|
|
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 `develop` can 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 and `true`, `false`, and `null`, and strict comparisons when the type is known.
|
|
- Put one space around concatenation and binary operators. Do not add spaces inside array offsets.
|
|
- Prefer `foreach` and current PHP constructs over removed legacy constructs. Prefer simple string functions when a regular expression is unnecessary; never introduce `ereg_*`.
|
|
- 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 `INFO` metadata and registration conventions. Register hooks and realms through the plugin APIs. AJAX plugin URLs normally include `header=false` when 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 `$_REQUEST` directly in new code. Use Cacti request helpers such as `get_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, later `grv()` or `gnrv()` 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: csrfMagicToken` unless 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 with `cacti_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()`, and `db_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 `AS` for aliases and explicit `INNER 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.md` and `AGENTS.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 or `error_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 `.dist` examples 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.json` and the lock file together when a lock file is part of that repository's policy.
|
|
- Validate dependency changes with `composer validate` and a clean `composer install`. Do not run `composer update` unless 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.
|