Plugin: backport PHP 8 syntax to PHP 7.4 (hc-eff)
The central history server work introduced four PHP 8.0+ syntax sites in the plugin codebase. The main plugin file's "Requires PHP: 7.4" header was already there; the code had silently drifted past that bound. - includes/class-att-hc-session.php:244 — str_starts_with($host, 'www.') → substr($host, 0, 4) === 'www.'. - includes/class-att-hc-api.php:52 — self::request(…, requires_auth: false) → positional false. Same default semantics, same callee signature. - includes/admin-page.php:165 and class-att-hc-session.php:126 — list_healthchecks(…, include_steps: …, limit: …) → positional. Same values, no semantic change. Verified by linting all 16 plugin files against PHP 7.4.33 — no syntax errors, no residual PHP 8+ patterns (str_starts_with/contains/ends_with, nullsafe, enum, readonly, mixed/never, constructor promotion, match). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
{"_type":"issue","id":"hc-eff","title":"Plugin fatals on PHP 7.4 — PHP 8 syntax in central-server work","description":"The central history server work (epic hc-0p1) introduced four PHP 8.0+ syntax sites in the plugin codebase. PHP 7.4 fails to parse the affected files, so on a host running PHP 7.4 (eg one user reported Ubuntu 7.4.3-4ubuntu2.29) the plugin throws a fatal on load.\n\nSites:\n- includes/class-att-hc-session.php:244 — str_starts_with()\n- includes/class-att-hc-api.php:52 — named argument requires_auth: false\n- includes/class-att-hc-session.php:126 — named arguments include_steps:, limit:\n- includes/admin-page.php:165 — named arguments include_steps:, limit:\n\nPlugin main file header still says 'Requires PHP: 7.4', so the expectation is PHP 7.4 support. Backport: replace str_starts_with with substr === comparison; convert named args to positional (signatures accept positional already).\n\nAffects every plugin user on PHP \u003c 8.0.","status":"closed","priority":1,"issue_type":"bug","assignee":"Steve Hanlon","owner":"steve@hanlon.co.uk","created_at":"2026-06-30T08:27:51Z","created_by":"Steve Hanlon","updated_at":"2026-06-30T08:29:22Z","started_at":"2026-06-30T08:27:57Z","closed_at":"2026-06-30T08:29:22Z","close_reason":"Backported four PHP 8.0+ syntax sites to PHP 7.4-compatible equivalents. str_starts_with replaced with substr(...) === literal. Three named-argument call sites converted to positional — signatures already accept positional with the same values, no semantic change. Verified by linting all 16 plugin files (att-site-healthcheck.php + includes/) against PHP 7.4.33 on sjh: no syntax errors, no residual PHP 8+ patterns. Plugin's 'Requires PHP: 7.4' header is now actually true.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"hc-cc8","title":"Plugin: per-step 'view previous notes' panel","description":"Each step card gets a small link/disclosure: 'Previous notes for this step (N)' where N is the count from the server.\n\nOn expand: render a list of past notes from GET /healthchecks/steps/{step_id}?site_key=\u003ccurrent\u003e\u0026limit=5. Each entry shows:\n- started_at (formatted)\n- status badge\n- notes (or 'no notes')\n- reporting_url if different from the current session\n\nLoaded lazily on first expand (one request per step) to avoid hammering the server on page load. Cache result for the page lifetime.","status":"closed","priority":1,"issue_type":"feature","assignee":"Steve Hanlon","owner":"steve@hanlon.co.uk","created_at":"2026-06-29T11:10:17Z","created_by":"Steve Hanlon","updated_at":"2026-06-29T11:41:06Z","started_at":"2026-06-29T11:36:10Z","closed_at":"2026-06-29T11:41:06Z","close_reason":"Per-step history disclosure shipped end-to-end.\n\nServer:\n- New GET /step-counts?site_key=...\u0026exclude_id=... returns {counts: {step_id: int}} for the (N) badge in one round-trip\n- stepHistory + stepCountsForSite both grew an exclude_id param so the active session doesn't appear in its own 'previous notes' panel\n- Routes: /step-counts moved to top-level path to avoid the /healthchecks/{id} pattern claiming 'step-counts' as an id\n\nPlugin:\n- ATT_HC_Api::step_counts() and step_history() pass exclude_id when available\n- att_hc_render_active_session pre-fetches step counts once and passes per-step count to the card renderer\n- Step card now renders a \u003cdetails class=att-hc-history data-step-id=…\u003e with summary 'Previous notes for this step (N)' when N\u003e0\n- New att_hc_print_step_history_assets prints the inline CSS + vanilla JS that hooks the details.toggle event: lazy-fetches on first expand via admin-ajax (action=att_hc_step_history), renders entries with date + status badge + notes + 'Reported from \u003curl\u003e' when different from current reporting_url. Marks data-loaded=yes to cache for page lifetime; resets to no on error so user can retry.\n- New wp_ajax_att_hc_step_history admin-ajax handler returns wp_send_json_success/error with nonce verification (att_hc_step_history nonce)\n\nVerified end-to-end against live server: counts correct with + without exclude_id (4 vs 3 for active vs prior), step_history filters active session, empty step / unknown site return cleanly, reordered routes still work.","dependencies":[{"issue_id":"hc-cc8","depends_on_id":"hc-0p1","type":"parent-child","created_at":"2026-06-29T12:13:24Z","created_by":"Steve Hanlon","metadata":"{}"},{"issue_id":"hc-cc8","depends_on_id":"hc-9jl","type":"blocks","created_at":"2026-06-29T12:10:37Z","created_by":"Steve Hanlon","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"hc-m1a","title":"Plugin: start screen — site_key field + recent dropdown + resume","description":"When no active local session exists, the start screen shows:\n\n1. Text input 'Site / engagement key' — defaults to normalised get_site_url() (lowercase, strip scheme + leading www., trim trailing slash). Editable. Help text: 'Used to group runs that span dev + live for the same engagement. Pick from recent engagements below if continuing one.'\n2. Dropdown 'Recent engagements' populated from GET /sites?limit=20. Selecting one fills the input.\n3. After site_key is set, GET /healthchecks?site_key=...\u0026include=steps. If any UNFINISHED sessions exist, list them with started_at and progress, each with a [Resume] button. Plus a separate [Start fresh] button.\n\nResume: load the chosen session into the local option (no new POST). Start fresh: new POST /healthchecks.","status":"closed","priority":1,"issue_type":"task","assignee":"Steve Hanlon","owner":"steve@hanlon.co.uk","created_at":"2026-06-29T11:10:05Z","created_by":"Steve Hanlon","updated_at":"2026-06-29T11:36:09Z","started_at":"2026-06-29T11:33:33Z","closed_at":"2026-06-29T11:36:09Z","close_reason":"Start screen rewritten:\n- Editable 'Site / engagement key' input, defaults to ATT_HC_Session::normalise_site_url(get_site_url()).\n- datalist-backed autocomplete from GET /sites?limit=20 (recent engagements). Picking one fills the input via native browser UX.\n- 'Look up engagement' submits as GET with site_key in the URL, so re-rendering picks it up and re-queries incompletes.\n- Table of in-progress sessions for the selected site_key with started_at, last-activity, reporting_url, and a [Resume] button per row. Each Resume button posts to a new att_hc_handle_resume handler which calls ATT_HC_Session::resume($id).\n- Separate Start button below labelled differently depending on whether incompletes exist.\n\nDouble-click guard: att_hc_handle_start (and att_hc_handle_resume) early-return to the main page if ATT_HC_Session::current() is non-null, so a stray repeat click can't 409 against the (site_key, started_at) unique constraint with a confusing duplicate error.\n\nEnd-to-end verified: /sites populates the datalist, incomplete filter shows 2 alpha + 1 beta + 0 unknown correctly, resume() repopulates cache and restores step notes, finish() removes from incomplete list. Lookup-err and recent-sites-err paths both surface as inline warnings without blocking the Start button.","dependencies":[{"issue_id":"hc-m1a","depends_on_id":"hc-0p1","type":"parent-child","created_at":"2026-06-29T12:13:23Z","created_by":"Steve Hanlon","metadata":"{}"},{"issue_id":"hc-m1a","depends_on_id":"hc-9jl","type":"blocks","created_at":"2026-06-29T12:10:36Z","created_by":"Steve Hanlon","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"hc-9jl","title":"Plugin: refactor ATT_HC_Session to write-through","description":"Session is now server-of-truth. Local WP option becomes a thin cache of the *active* session for fast page loads.\n\nChanges:\n- start(): generates id locally, POSTs to /healthchecks, stores response in option. site_key + reporting_url are new fields.\n- update_step(): updates option AND PUTs to /healthchecks/{id}/steps/{step_id}. If server call fails, the option is NOT updated and the caller sees the error (no drift).\n- finish(): PUT /healthchecks/{id} with finished_at, then update option.\n- set_autocheck(): same write-through pattern.\n- previous(): replace local 'att_hc_previous_session' option with a call to GET /healthchecks?site_key=...\u0026include=steps\u0026limit=2, return the most recent FINISHED one before the current session.\n- discard(): delete option only. Server keeps the record (intentional; history is the point).\n\nRemove the att_hc_previous_session option entirely (data is on the server now).","status":"closed","priority":1,"issue_type":"task","assignee":"Steve Hanlon","owner":"steve@hanlon.co.uk","created_at":"2026-06-29T11:09:55Z","created_by":"Steve Hanlon","updated_at":"2026-06-29T11:30:29Z","started_at":"2026-06-29T11:25:28Z","closed_at":"2026-06-29T11:30:29Z","close_reason":"ATT_HC_Session refactored to write-through. Every mutating method (start / update_step / finish / set_autocheck) POSTs or PUTs to the central server first; only on success does the local WP option cache get updated. ATT_HC_Api_Exception bubbles to callers — admin handlers (start / save_step / finish / refresh_checks / step_action) now wrap calls in try/catch and surface via att_hc_api_error transient → admin notice. Added: site_key field (defaults to normalise_site_url(get_site_url())), reporting_url field, ATT_HC_Session::resume(id) for hc-m1a, ATT_HC_Session::normalise_site_url(). previous() now fetches from server (list_healthchecks ?include=steps) and reconstructs into the local session shape; degrades silently on server unreachable since diff is a nice-to-have. Removed att_hc_previous_session option entirely. Also added a config-error gate at the top of the admin page that blocks the UI with a clear notice when wp-config.php constants are missing or wrong. Added server/dev-router.php to work around PHP -S 405-ing dotted uniqid paths (production Apache/nginx unaffected). End-to-end verified against live server: 13 assertions covering happy path, autocheck preservation across upserts, multi-session-per-site, previous()/resume() reconstruction, discard-preserves-server-record, and error bubbling.","dependencies":[{"issue_id":"hc-9jl","depends_on_id":"hc-0p1","type":"parent-child","created_at":"2026-06-29T12:13:23Z","created_by":"Steve Hanlon","metadata":"{}"},{"issue_id":"hc-9jl","depends_on_id":"hc-0rr","type":"blocks","created_at":"2026-06-29T12:10:36Z","created_by":"Steve Hanlon","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
|
||||
|
||||
Reference in New Issue
Block a user