Changelog
=========

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog] and this project adheres to [Semantic Versioning].

## [Unreleased]

## [2.0.9] - 2025-09-30
### Changed
- Add clearer phpcs comments, formatted CHANGELOG.md.

## [2.0.8] - 2025-09-30
### Security
- Add proper sanitization for `$_POST['option_page']` value in settings API token callback with appropriate phpcs documentation.

## [2.0.7] - 2025-09-30
### Security
- Sanitize and normalize all Quote API payloads before persistence, enforcing `absint()` on identifiers and WordPress text/email sanitizers on freeform fields while tightening localized IDs and prefill strings to keep hostile data out of custom tables and the editor UI.

## [2.0.6] - 2025-09-30
### Fixed
- Require `wqrm_*` AJAX handlers to read `post_id` from the POST body, unslash it before `absint()`, and drop the legacy `$_REQUEST` fallback to align with Plugin Handbook guidance.

### Tests
- Mirror WordPress core's URL sanitization helpers inside the PHPUnit bootstrap so that `esc_url_raw()` behaves identically to production, and add coverage validating publish notification payloads use sanitized URLs.

## [2.0.5] - 2025-09-26
### Changed
- Require the Quotes API base URL setting to pass `esc_url_raw` validation and only allow `http`/`https` values.
- Stop forwarding request metadata and always send `null` to the external API because the field is not consumed.

### Tests
- Align AJAX tests with the simplified metadata handling and cover the stricter URL sanitizer.

## [2.0.4] - 2025-09-24
### Fixed
- Restrict the Quotes settings screen to administrators and stop echoing the saved API token so credentials are never exposed in the browser UI.
- Keep automation-friendly behaviour when clearing the stored API bearer token while preserving the UI affordance to retain existing secrets.

## [2.0.3] - 2025-09-19
### Fixed
- Tighten Plugin Check suppressions so they target only required sniffs and document the nonce/DB contexts.
- Remove the unused Composer installer helper to keep the submission package clean for wordpress.org review.
- Verify the plugin passes the official Plugin Check ruleset locally.

## [2.0.2] - 2025-09-19
### Fixed
- Reinstate the text domain loader so bundled translations remain available while documenting the just-in-time behaviour for Plugin Check.
- Normalize PHPCS suppressions for custom table queries and admin flows to satisfy WordPress.org Plugin Check guidance.

## [2.0.1] - 2025-09-19
### Changed
- Add translator comments to metabox and prefill strings and lean on WordPress' just-in-time textdomain loader to satisfy wordpress.org Plugin Check guidance.
- Refresh the public readme summary and align the `Tested up to` metadata with WordPress 6.8.
- Capture the WPCS review context inline so Plugin Check sees why nonce verification and direct DB access are acceptable in these admin flows.

### Fixed
- Ensure release artifacts omit `.gitignore` files by excluding them in the Makefile and asserting the absence during CI packaging.
- Correct PHPCS suppression annotations so WPCS notices are properly silenced in Plugin Check runs.

## [2.0.0] - 2025-09-18
### Changed
- Rename the plugin package, entry point, and text domain to `tmx-quote-request-manager`, updating build tooling, autoloaders, and tests accordingly.
- Ship a WordPress.org compliant `readme.txt`, keep a concise contributor `README.md`, and bundle the GPLv2-or-later license text for distribution builds.
- Stop tracking local Composer binaries and ignore helper tool directories to keep release zips free of executables.
- Localise the metabox JavaScript strings via `wp.i18n.__()` and load script translations so GlotPress translations apply without code changes.
- Document TMX Messenger signup and plan details in the WordPress readme to clarify service access for reviewers.

### Fixed
- Enforce nonce validation for the `wqrm_get_post_data` AJAX endpoint via the shared request verifier to close a CSRF gap.
- Require `current_user_can('edit_post', $post_id)` before returning or mutating quote data over AJAX, including the prefill generator, to prevent unauthorized data access.
- Replace metabox whitespace detection regex with a trim-based helper to avoid regex backtracking concerns while keeping preview truncation behaviour unchanged.

### Security
- Enable GitLab-managed Semgrep SAST scanning in CI (Jobs/SAST.gitlab-ci.yml) with vendor/output directories excluded to keep security checks focused on plugin source, run scans on tags, and publish the JSON report alongside release assets.

### Tests
- Add regression coverage ensuring `ajax_get_post_data` refuses users without `edit_post` capabilities.

### QA
- `make qa`
- `make test`

## [1.5.2] - 2025-09-15
### Fixed
- Admin: ensure publish notification reports the exact permalink by using `get_permalink($post)` and skipping when empty.
- JS: harden `escapeHtml()` to correctly escape quotes and single quotes to prevent incorrect rendering.

### Tests
- Add coverage for publish notification permalink value (`AdminPublishNotifyLinkTest`).
- Add coverage for `/submitted-post` payload body (`APIClientNotifyPayloadTest`).

### Added
- Tests: Add focused coverage for critical Admin paths:
  - Assets enqueue (register + localize payload on editor screens).
  - Settings sanitizers (URL, token, poll interval min bound, boolean toggle).
  - Admin pages rendering for Settings and Requests tabs (basic table rows + counts).
  - Init hook registrations (verifies all actions registered by Admin::init()).
  - Publish notify error path (gracefully handles WP_Error from API client).

## [1.5.1] - 2025-09-10
### Changed
- CI/CD: Publish JUnit test reports so results appear in GitLab UI (artifacts:reports:junit). PHPUnit config now logs to `coverage/junit.xml`.
- CI/CD: Add Cobertura coverage visualization in MRs (native via PHPUnit 10) and aggregate coverage across PHP 8.1/8.2/8.3 jobs. Coverage percent shown in MR widget via `coverage:` regex.

## [1.5.0] - 2025-09-10
### Changed
- Tests/CI: Upgrade to PHPUnit 10 and php-code-coverage 10; generate Cobertura reports directly from PHPUnit for GitLab MR diff annotations. Remove custom Clover→Cobertura conversion.
- CI: Integrate coverage reports per matrix job and publish `artifacts:reports: coverage_report` for GitLab to aggregate; drop redundant coverage job.
- CI: Enforce version consistency between plugin header `Version:` and `WQRM_VERSION` via a lint job.
- Platform: Raise minimum supported PHP to 8.1 (test matrix covers 8.1, 8.2, 8.3).

### Notes
- If using PHP 8.1 locally, ensure Xdebug is installed and `XDEBUG_MODE=coverage` is set to generate coverage.

## [1.4.5] - 2025-09-10
### Fixed
- Admin UI: Toggle label now switches between "Show more" and "Show less" correctly when expanding/collapsing request previews in the metabox and editor block UI.

### Changed
- CI/CD: Surface PHPUnit line coverage in GitLab via `coverage:` regex aligned to docs; disabled ANSI colors in `make coverage` to ensure stable parsing.
- CI/CD: Create releases via GitLab CLI (`glab` ≥ 1.58) and upload the plugin ZIP as a persistent release asset; fail early if `VERSION` is missing. Build validates the ZIP structure to prevent WordPress install errors.

### QA
- Build validation: CI asserts the ZIP contains `wp-quote-requests/quote-requests.php` to guard against packaging regressions.

## [1.4.4] - 2025-09-10
### Changed
- Metabox UX: Replace hard truncation with preview + Show more/less toggle for request text.
- Replies UX: Add subtle separators and spacing between replies to improve scanability.
- i18n: Localize Show more/less labels via `WQRM.i18n`.

### Fixed
- Preserve newlines in request previews and quote replies using `white-space: pre-wrap`.

### QA
- Lint, coding standards, and tests passing via `make qa`. No regressions observed.

## [1.4.3] - 2025-09-04
### Changed
- CI/CD: Replace deprecated `release-cli` usage with job-level `release:` and `glab` image; forward-compatible with GitLab 19.0.
- CI/CD: Add top-level `workflow: rules` to run pipelines only for tags, merge requests, and default branch.
- CI/CD: Key Composer cache by `composer.lock` via `cache.key.files` for better reuse across jobs.
- CI/CD: Limit `coverage` job to default branch; keep matrix tests for tags, MRs, and default branch.
- CI/CD: Ensure Composer bootstrap tools (`curl`, `unzip`, `git`) are present in CI images.

## [1.4.2] - 2025-09-03
### Changed
- CI/CD: Adopt GitLab CI with stages (lint, test, build, release) wired to Makefile targets to avoid duplication and drift.
- CI/CD: Add Composer install in CI with caching (vendor and Composer cache) pinned by composer.lock for reproducibility.
- CI/CD: Build on default branch and tags; release job creates a GitLab Release and attaches the plugin zip.
- CI/CD: Add tag/version guard to ensure git tag matches plugin header Version.
- Maintenance: Remove GitHub Actions workflow to avoid duplicate pipelines.

## [1.4.1] - 2025-09-03
### Changed
- Admin UI copy: metabox label now reads “Request a quote”; primary button now reads “Send Request”.
- Prefill (overlay provider): phrasing updated to “What comments do you need for your story on %s?”.

### Tests
- Updated provider and AJAX prefill tests to match new phrasing.

### Chore
- Ignore `.phpunit.result.cache` and remove it from version control.

## [1.4.0] - 2025-09-03
### Added
- Prefill: New `OverlayReportingProvider` that returns the same suggested text as the title-based provider, and also POSTs to a drafts overlay endpoint (`POST /quote-draft`) with the site name as `publication_name` and the raw post title as `quote_request`. This runs best-effort and never blocks the editor.
- API client: Added `API_Client::submit_draft()` to centralize draft submission calls.

### Tests
- Expanded unit and integration coverage for providers, Admin AJAX paths, and DB methods. Overall line coverage is ~60%.

### Notes
- When prefill is generated via the live title-based AJAX (debounced), the overlay endpoint may receive calls as titles change if API settings are configured. To limit to draft saves only, swap the provider wiring.

## [1.3.3] - 2025-09-03
### Changed
- Metabox UX: Prefill now displays as placeholder text in the quote request textarea instead of being injected as actual content. Users only submit what they type.
- Live prefill: Title-based prefill updates the placeholder dynamically rather than the textarea value.

## [1.3.2] - 2025-09-02
### Fixed
- Test suite: aligned draft prefill test with current behavior (use `update_post_meta`, no revision gate) to reflect the intended functionality.
- Changelog: corrected 1.3.1 notes to accurately describe autosave handling and prefill persistence.


## [1.3.1] - 2025-09-02
### Fixed
- Classic editor: Prefill not appearing after autosave when creating a new post. `on_draft_save` now handles autosaves by mapping to the parent draft and persists earlier. Revision checks were removed to avoid dropping prefills during revision flows.
- Live behavior: Added provider-backed, debounced title sync in the metabox so the textarea reflects the active prefill provider as the user types. Debounce set to 3000ms to avoid suggesting text based on half-typed titles and to reduce network chatter.

### Notes
- The prefill generation remains centralized in `Prefill\\ProviderInterface`, used for both persistence and the live suggestion. No tokens or secrets are exposed to the browser; AJAX calls use nonce + capability checks.

## [1.3.0] - 2025-09-02
### Added
- Draft prefill: Introduced a pluggable prefill provider (`WQRM\Prefill\ProviderInterface`) with a default `TitleBasedProvider` that suggests “What quotes do you need for [post title]?”.
- Setting: New “Prepopulate quote request” toggle (default: on). When enabled, draft saves populate a suggested message; the metabox renders it in the textarea.
- Hooking: Intercept draft saves via `wp_after_insert_post` with guards for autosaves/revisions and capabilities.
- Tests: Added unit tests covering prefill behavior, toggle off behavior, and bailouts for non-draft/autosave.

### Changed
- `Admin` now accepts an optional prefill provider dependency for easier swaps in future implementations.
- Prefill persistence switched to `update_post_meta` to avoid multiple post meta fields.

## [1.2.0] - 2025-09-02
### Changed
- Removed publication name and metadata inputs from the metabox UI; the server now derives `publication_name` from the WordPress Site Name to satisfy the OpenAPI requirement without exposing tokens to the browser.
- Editor/block UI remains in sync by reusing the metabox renderer; IDs were preserved where applicable.

### Added
- Lean QA: integrated `phpcs` (complexity + nesting) and `php-parallel-lint`, with `make lint`, `make cs`, and `make qa` targets, plus Composer scripts.

### Fixed
- Artifact hygiene: build now excludes `.composer-cache`, PHPCS config, and other dev-only files; build name automatically includes the plugin version.

## [1.1.0] - 2025-08-26
### Added
- Editor-only block `wqrm/quotes-panel` to surface the Quote Requests UI directly in post content or templates.
- Metabox suppression when the block is present to avoid duplicate UI/IDs.
- Tests covering block registration, render behavior, and metabox suppression.
- `AGENTS.md` with onboarding details, dev commands, and conventions.

### Changed
- Bumped plugin version to 1.1.0 and updated build artifact naming.
- README updated with block usage instructions.

### Fixed
- Excluded `coverage/` directory from build artifacts.

## [1.0.0] - 2025-08-26
### Added
- Initial release with metabox UI, AJAX actions, API client, DB layer, admin pages, and settings.

[Unreleased]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.9...HEAD
[2.0.9]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.8...v2.0.9
[2.0.8]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.7...v2.0.8
[2.0.7]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.6...v2.0.7
[2.0.6]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.5...v2.0.6
[2.0.5]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.4...v2.0.5
[2.0.4]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.3...v2.0.4
[2.0.3]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.2...v2.0.3
[2.0.2]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.1...v2.0.2
[2.0.1]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v2.0.0...v2.0.1
[2.0.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.5.2...v2.0.0
[1.5.2]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.5.1...v1.5.2
[1.5.1]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.5.0...v1.5.1
[1.5.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.5...v1.5.0
[1.4.5]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.4...v1.4.5
[1.4.4]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.3...v1.4.4
[1.4.3]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.2...v1.4.3
[1.4.2]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.1...v1.4.2
[1.4.1]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.4.0...v1.4.1
[1.4.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.3.3...v1.4.0
[1.3.3]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.3.2...v1.3.3
[1.3.2]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.3.1...v1.3.2
[1.3.1]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.3.0...v1.3.1
[1.3.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.2.0...v1.3.0
[1.2.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.1.0...v1.2.0
[1.1.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/compare/v1.0.0...v1.1.0
[1.0.0]: https://gitlab.com/tmx/backend-codebase/wqrm/-/tags/v1.0.0

[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/
[Semantic Versioning]: https://semver.org/spec/v2.0.0.html
