=== VizProof Timeline ===
Contributors: tommybordas
Tags: visual-regression, screenshots, qa, testing, multisite
Requires at least: 6.2
Tested up to: 7.0
Stable tag: 1.0.2
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Run VizProof scans from WordPress updates, review visual diffs in wp-admin, and automate recurring checks.

== Description ==

VizProof Timeline connects WordPress to VizProof so post-update quality checks are simple and actionable.

Key features:

* Launch post-update scans after plugin, theme, or core updates
* Optionally launch a baseline scan before running updates
* Show scan status directly on the WordPress Updates screen
* Open run history and visual diff summaries from wp-admin
* Run scheduled checks with WP-Cron (Action Scheduler fallback)
* Support multisite in per-site and network-wide modes

== External services ==

This plugin connects to VizProof APIs hosted at `https://vizproof.com` (or a custom VizProof API URL configured by the site administrator).

It sends requests only when plugin features are used (project/page loading, scan launches, run history refresh, post-update workflows, scheduled scans).

Data that may be sent includes:

* API token entered by an administrator
* Linked VizProof site/project ID
* Page IDs or URLs used for scans
* Run trigger metadata required by update workflows

Service documentation and policies:

* Privacy Policy: https://vizproof.com/privacy
* Terms of Service: https://vizproof.com/terms

== Installation ==

1. Upload the `vizproof-timeline` folder to `/wp-content/plugins/`.
2. Activate **VizProof Timeline**.
3. Click **VizProof** in the top admin bar, then **Configuration**.
4. Enter your VizProof API URL (default: `https://vizproof.com`) and API token.
5. Select the VizProof project to link with this WordPress site.
6. Save your settings.

To obtain an API token:

1. Create a free account at [vizproof.com](https://vizproof.com/register).
2. Create a project and add at least one page (use your WordPress site URL).
3. Go to **Account → API Tokens** and generate a token (starts with `vrt_`).
4. Paste the token in the plugin Configuration page.

Multisite:

1. Open `Network Admin -> Settings -> VizProof Timeline`.
2. Choose `Per-site` or `Network-wide` mode.

== Frequently Asked Questions ==

= Does this plugin require a VizProof account? =

Yes. Sign up at [vizproof.com](https://vizproof.com/register), create a project, then generate an API token from Account → API Tokens. See the Installation section for step-by-step instructions.

= What happens after a plugin/theme/core update? =

If post-update scan is enabled, VizProof Timeline queues a scan after the update completes and exposes status/results in wp-admin.

= Does WP-CLI trigger the same scan logic? =

Yes. WP-CLI update commands run through the same updater hooks used by this plugin.

= Is multisite supported? =

Yes.

* `Per-site`: each subsite keeps its own configuration.
* `Network-wide`: one shared network-level configuration.

== Screenshots ==

1. Settings page with API/project linking and page scope.
2. WordPress Updates panel with controls and post-update scan status.
3. Timeline view with run summaries and diff cards.

== Changelog ==

= 1.0.1 =

* Fixed readme: corrected menu location from "Settings > VizProof Timeline" to the actual top-level "VizProof" admin bar menu.
* Added step-by-step instructions for obtaining a VizProof API token in the Installation section.
* Fixed admin notices from other plugins appearing inside VizProof pages (added screen-reader-text h1 anchor for WordPress notice injection).
* Redesigned timeline baseline status bar into a unified single-row component.
* Removed unused baseline-assist and baseline-summary CSS classes.

= 1.0.0 =

First stable WordPress.org release. The plugin has reached production maturity for the VizProof Timeline integration: multisite-aware updates workflow, asynchronous scan queue with retry/backoff, admin bar regression badge, REST API surface, and rollback service with local backups in the uploads directory.

WordPress.org review compliance:
* Removed direct loading of `wp-admin/includes/misc.php` (no function from that file was used) and gated remaining `require_once ABSPATH . 'wp-admin/includes/...'` calls with `function_exists()` / `class_exists()` guards. Each guarded include is followed immediately by a call to a function/class from that file, per WP.org guidelines.
* Replaced hardcoded `WP_PLUGIN_DIR` and `WP_CONTENT_DIR` constants in the rollback service with paths derived from `plugin_dir_path( __FILE__ )` via new `VIZPROOF_TIMELINE_PLUGIN_FILE` / `VIZPROOF_TIMELINE_PLUGIN_DIR` / `VIZPROOF_TIMELINE_PLUGIN_URL` constants. Local backup path validation now reuses the existing `wp_upload_dir()`-based `get_local_backup_root()` helper for consistency.
* Made REST permission callbacks (`can_access_timeline`, `can_launch_runs`) perform an explicit `current_user_can( 'manage_options' )` capability check (previously delegated only via `can_manage_plugin()`), so static analysis can confirm protection on all 23 endpoints.
* Hardened `enqueue_inline_admin_style()` / `enqueue_inline_admin_script()`: CSS now goes through `wp_strip_all_tags()` before `wp_add_inline_style()`, and inline JS is rejected if it contains a `</script>` sequence that could break out of the inline `<script>` block.
* Renamed admin bar regression transients from `vizproof_adminbar_regressions_*` to `vizproof_timeline_adminbar_regressions_*` for prefix consistency with the rest of the plugin.

= 0.4.45 =

WordPress.org compliance:
* Replaced admin inline `<style>`/`<script>` blocks with `wp_add_inline_style()` / `wp_add_inline_script()` attached to enqueued handles.
* Moved admin bar badge CSS injection to `admin_enqueue_scripts`.
* Update panel assets now load consistently on `update-core.php`, `themes.php`, and `plugins.php`.
* Added dedicated nonce handling for post-update request flags (`vizproof_after_update_scan`, `vizproof_before_update_baseline`) and enforced nonce+capability checks before honoring explicit request overrides.

= 0.4.44 =

Bug fixes:
* Fixed post-update scan failing silently when pages already exist on VizProof: the existing page ID from 409 responses was not extracted (nested in proxy body, not at details root).
* Pre-update baseline promotion now polls until the VizProof run completes (up to ~60s) before promoting, instead of promoting an incomplete run which was always rejected by the API.

Improvements:
* API logs now display in chronological order by default (oldest→newest) with a toggle button to switch to reverse order.
* Log rotation: entries older than 7 days are automatically pruned. Retention increased from 120 to 500 entries.
* Log rows with 4xx errors are highlighted in yellow, 5xx in red.

= 0.4.43 =

* VizProof update panel now displays on Themes and Plugins admin pages (was limited to update-core.php).
* Assets (CSS/JS) are now loaded on themes.php and plugins.php for update panel rendering.

= 0.4.42 =

Security:
* Fixed path traversal in restore_local_plugin_backup: added trailing slash to realpath containment check.
* Added bearer token redaction in proxy error log bodies.
* REST rest_save_option now runs options through sanitize_options before update_option.

WordPress compliance:
* Added load_plugin_textdomain() on init for translation loading outside WP.org directory.
* Capped get_sites() calls to 500 (was unbounded number=0, caused timeout on large Multisite).
* Plugin header Description translated to English (WP.org requirement).
* Merged duplicate REST route registrations for runs/{id} (GET+DELETE in single call).
* Complete uninstall cleanup: removes _vizproof_lock_* options, all vizproof_* transients and site transients.

Accessibility (WCAG 2.1 AA):
* Page tree checkboxes now include page title in aria-label ("Suivre — Page title").
* Added label/for association on network settings cache delay input.
* Removed role="presentation" from per-site targets data table.
* Fixed color contrast: warn badge (#6b5100), pending pill (#7a5300).
* Added :focus-visible styles on all custom buttons and clickable elements.
* Replaced invalid <h3> inside <legend> with styled <legend> in automation fieldsets.

i18n:
* Translated network config mode radio labels to French (was mixed EN/FR).
* Wired ~10 hardcoded strings in inline JS bridge to t() translation helper.
* Translated 8 untranslated msgstr entries in fr_FR.po (update summary labels, Status, etc.).

Cleanup:
* Removed dead SETTINGS_MENU_SLUG constant and render_settings_page() method.
* Removed ~6 unused CSS selectors (activity-item, summary-list, health-check).
* Capped scan history to 100 entries (was unbounded).
* Added TODO comments on duplicated inline <style> blocks for future consolidation.

= 0.4.41 =

* Fixed proxy_vizproof_request silently failing when receiving pre-normalization options with empty api_token (self-decrypt from api_token_encrypted).
* Fixed scan lock race condition on standard WP installs (no Redis): replaced non-atomic transient fallback with INSERT IGNORE for cross-process atomicity.
* Removed orphan SETTINGS_MENU_SLUG from is_vizproof_admin_request allowlists (page never registered in admin_menu).
* Removed dead code: register_admin_menu, register_network_admin_menu, register_settings from service-base (duplicated in main plugin file, never hooked).

= 0.4.40 =

* Fixed PHP parse error caused by Unicode smart quotes in French translation strings.
* Fixed dead links: "Réglages avancés" and "Choisir le projet" pointed to unregistered SETTINGS_MENU_SLUG page.
* Simplified redundant boolean comparisons (=== true / === false) in update panel JS.
* Further compacted update panel CSS: tighter padding, margins, and gaps across all panel sections.

= 0.4.39 =

* Fixed redundant boolean logic in token storage validation.
* Fixed race condition in scan lock using atomic wp_cache_add.
* Fixed REST route methods for favorite endpoints (PATCH only instead of PUT+PATCH).
* Fixed function_exists guard in uninstall.php referencing wrong function name.
* Simplified site picker: merged auto-detect into project loading, "Create from WordPress" is now a secondary link.
* Added AJAX save for project selection (no full page reload between onboarding steps).
* Grouped automation settings into sub-sections: Planification, Comportement post-update, Notifications.
* Moved API logs behind a collapsible "Outils développeur" toggle on the dashboard.
* Added empty state on the timeline when no runs exist.
* Translated raw API status strings (partial_failed, queued, etc.) to human-readable French in the update panel.
* Replaced setInterval polling with MutationObserver only in the timeline bridge script.
* Added aria-live attributes on all dynamically updated zones (state, runs, diffs, update panel).
* Fixed timeline filter labels: proper label-for associations instead of span wrappers.
* Restructured network settings form with fieldset groups (Connexion API, Comportement des scans, Notifications).
* Compacted update panel on update-core.php: single-row header, inline checkboxes, collapsible pipeline steps.
* Stale scan results from previous updates are no longer shown on the update listing page.

= 0.4.38 =

* Improved update-flow reliability for async and sync scan events.
* Improved multisite admin URL routing between site and network contexts.
* Improved pre-update baseline behavior by promoting successful pre-update runs.
* Improved update panel consistency for partial-failure handling.
* Improved layout width handling on update-core screens.

= 0.4.0 =

* Added asynchronous queue support with retry/backoff.
* Added update workflows and visual regression notifications in wp-admin.
* Added multisite support for per-site and network-wide modes.

== Upgrade Notice ==

= 1.0.1 =

Fixed incorrect menu path in readme, added API token setup instructions, fixed admin notices leaking into plugin pages.

= 1.0.0 =

First stable WordPress.org release. Full review-compliance pass: replaced `WP_PLUGIN_DIR`/`WP_CONTENT_DIR` with `plugin_dir_path()` helpers, REST checks now call `current_user_can( 'manage_options' )` explicitly, hardened inline CSS/JS escaping, unified transient prefix.

= 0.4.45 =

WP.org compliance hardening: enqueued inline assets (no raw `<style>/<script>` output) and nonce-protected update request flags.

= 0.4.44 =

Critical fix: post-update scans now resolve existing VizProof pages correctly (409 existingPageId extraction). Pre-update baseline waits for run completion before promotion.

= 0.4.43 =

Update panel now visible on Themes and Plugins pages, not just update-core.php.

= 0.4.42 =

Full audit: security hardening, WCAG AA accessibility, WP.org compliance, i18n fixes, dead code cleanup.

= 0.4.41 =

Security and reliability: atomic scan lock, self-decrypting API proxy, dead code cleanup.

= 0.4.40 =

Critical fix: PHP parse error from smart quotes, dead navigation links, tighter update panel layout.

= 0.4.39 =

UX overhaul: compact update panel, simplified onboarding, grouped settings, accessibility improvements, and several logic bug fixes.

= 0.4.38 =

Maintenance release recommended for update workflow reliability, multisite routing, and pre-update baseline consistency.
