## CHANGELOG

= 5.12.3 =
* August 2026
* Fix: Multipage posts now purge every numbered page for real. 5.12.1 asked the proxy for a wildcard purge of the post URL, which silently did nothing on the many Varnish configurations that do not implement regex banning (or do not store the object URL for the ban lurker to match), so pages 2..N kept serving pre-edit content. The plugin now purges the actual page URLs (/post/2/, /post/3/, ...) with ordinary PURGE requests, exactly as WordPress builds them, so it works on any setup where purging page 1 already works. Reported by @didierjm.

= 5.12.2 =
* August 2026
* Fix: "max-age=0" is no longer reported as a Site Health error when the response proves a shared cache is serving the page. Proxies on some managed hosts consume "s-maxage" and strip it from the response, so the debugger only saw "max-age=0" and flagged a working site. Cache hit indicators (X-Cache/X-Cache-Status/X-Proxy-Cache HIT, a positive Age, X-Cache-Age or X-Cache-Hits) now downgrade the finding to a warning. Reported by @davidkoster89.

= 5.12.1 =
* July 2026
* Fix: Updating multipage posts now purges every numbered page instead of only page 1.
* Dev: Regex purge tests now respect the requested URL pattern, and standalone test setup runs from the correct directory.

= 5.12.0 =
* June 2026
* Change: The GetPageSpeed Amplify recommendation links (readme + Check Caching results) now point to the dedicated Varnish monitoring landing page for a more relevant first impression.

= 5.11.1 =
* June 2026
* Security: The manual "Purge Cache (This Page)" action (`vhp_flush_do`) now only purges URLs on this site's own host, and requires a capability (filter: `vhp_manual_purge_capability`, default `edit_published_posts`) in addition to the nonce. Previously a low-privileged user could reuse the purge nonce to point the server's outbound PURGE request at an arbitrary host - a blind SSRF reachability oracle. Reported privately by Austin Ginder.

= 5.11.0 =
* June 2026
* Fix: Async purge queue now self-heals from the "stuck full-queue" state where `vhp_process_purge_queue` was silently never re-scheduled. The watchdog in `ensure_purge_queue_scheduled()` re-arms a ghost event when the queue is non-empty and `vhp_varnish_last_queue_run` is older than 5 minutes (filterable via `vhp_purge_queue_watchdog_seconds`).
* Fix: `enqueue_urls()` now calls the scheduler even when the queue already has a full purge queued. Without this, a stuck full-queue state could not recover on subsequent `save_post` events.
* Change: Cron-mode is no longer auto-enabled by `DISABLE_WP_CRON`. That constant means "no visitor-triggered wp-cron"; on hosts running system cron it does NOT imply WP-Cron is unreliable. Site owners who want cron-mode must opt in explicitly via `define('VHP_ENABLE_CRON_PURGING', true)`, the `vhp_varnish_cron_purging` site option, or the existing `vhp_purge_use_cron` filter.
* New: `VHP_ENABLE_CRON_PURGING` constant and `vhp_purge_queue_watchdog_seconds` filter.

= 5.10.0 =
* May 2026
* New: Recommendation for GetPageSpeed Amplify cache monitoring (readme + Check Caching results).

= 5.9.2 =
* May 2026
* Fix: Corrected @param/@return docblock types on purge_post(), purge_url(), generate_urls(), check_upgrades(), and nocache_cssjs() so they match the values actually passed and returned. Removes false IDE and static-analysis warnings reported by Sjoerd Boerrigter. No runtime behavior changes.
* New: CI now lints PHPDoc parameter/return types against real WordPress function signatures (PHPStan + WP stubs), so this class of docblock drift is caught automatically.

= 5.9.1 =
* May 2026
* Update: Tested up to WordPress 7.0
* Update: `Requires PHP` bumped from 5.6 to 7.4 to match WordPress 7.0's PHP floor. Sites on PHP < 7.4 will not see this update.

= 5.9.0 =
* April 2026
* New: NGINX cache-purge backend support -- uses literal * instead of .* regex for wildcard purges
* New: VHP_PURGE_BACKEND constant and settings UI to select Varnish or NGINX backend

= 5.8.3 =
* April 2026
* Fix: REST API purge URLs for custom post types with empty rest_base no longer produce double-slash URLs

= 5.8.2 =
* March 2026
* Fix: Health score widget now uses HTTP when connecting directly to Varnish IP, fixing false "server may block loopback requests" errors on HTTPS sites with a plain HTTP Varnish daemon

= 5.8.1 =
* March 2026
* New: Regex purge URLs for category, tag, and blog listing pages to properly invalidate paginated archive pages (e.g., /category/news/page/2)

= 5.8.0 =
* March 2026
* New: Cache Health Score widget - tests multiple site URLs and shows a visual 0-100 score indicating cache hit ratio
* New: WooCommerce revenue impact notice suggesting Cacheability Pro for stores without cache warming
* Fix: Use ArrayAccess interface for PHPStan header type compatibility
* Tested up to WordPress 6.9

= 5.7.0 =
* February 2026
* New: Detection of "Vary: Accept" header which causes severe cache fragmentation. This is often added by plugins like Jetpack and provides no benefit for most WordPress sites while dramatically reducing cache hit rates.
* New: Contextual Cacheability Pro recommendations in cache diagnostics, post-purge messages, plugin action links, admin menu, E2E test results, and Site Health. All suggestions auto-hide when Cacheability Pro is installed.

= 5.6.5 =
* February 2026
* Fix: Cache detection now correctly validates max-age=0 with s-maxage > 0 (proper Varnish setup)
* Dev: Added comprehensive test coverage for Cache-Control header edge cases

= 5.6.4 =
* January 2026
* New: Added `VHP_DISABLE_CRON_PURGING` wp-config.php constant to force-disable background purging even when `DISABLE_WP_CRON` is enabled. Useful for environments with many low-traffic sites that use external cron but prefer immediate cache purges.

= 5.6.3 =
* January 2026
* Fix: Manual cache purge actions ("Purge Cache All Pages" and "Purge This Page" in admin bar) now execute immediately regardless of WP-Cron mode settings. Previously, when DISABLE_WP_CRON was true, even manual purges were queued for later cron execution, which was confusing for administrators expecting immediate action.
* Dev: Added test coverage for manual purge immediate execution behavior

= 5.6.2 =
* January 2026
* New: Cacheability Pro recommendation

= 5.5.3 =
* December 2025
* New: End-to-End Cache Test in "Check Caching" admin page - a comprehensive 7-step test that verifies both caching AND purging work correctly, without relying on header detection heuristics
* Fix: Header Analysis tab now stays active after running a URL scan (previously switched to first tab)
* Fix: Removed duplicate introductory text in Header Analysis tab

= 5.5.2 =
* December 2025
* Fix: Removed development files from WordPress.org distribution (Cursor rules, PHPStan config, Makefile, etc.)
* Fix: Added concurrency control to CI workflows to prevent SVN deploy race conditions

= 5.5.1 =
* December 2025
* New: WP-CLI `--all` flag for explicit full site cache purge
* New: WP-CLI `--url-only` flag to purge exact URL without wildcard matching
* New: WP-CLI `--tag=<tag>` option for tag-based cache purging (requires Cache Tags mode)
* Doc: Fixed WP-CLI documentation - `wp varnish purge` correctly documented as full site purge
* Doc: Fixed "WP CLI" typo to "WP-CLI" in readme
* Dev: Added PHPCS/PHPStan linting infrastructure
* Dev: Added GitHub Actions CI workflow for linting
* Dev: New pytest coverage for WP-CLI purge command variants

= 5.5.0 =
* December 2025
* Fix: Scheduled posts now properly purge cache when auto-published via WP-Cron. Previously, purges were queued but not processed until the next cron run, leaving stale content.
* New: Added `transition_post_status` hook to handle future → publish transitions synchronously, ensuring immediate cache invalidation for scheduled posts.
* New: Shortlink URLs (`?p=XXX`) are now purged when scheduled posts publish, clearing any cached 404 responses.
* Doc: Added guidance on cron frequency for background purging mode.
* Dev: New pytest coverage for scheduled post publishing via WP-Cron.

= 5.4.0 =
* December 2025
* New (BETA): Optional Cache Tags / Surrogate Key purge mode, controlled via the "Use Cache Tags" setting.
* New (BETA): Tag-mode enablement based on standard Surrogate-Capability headers from surrogates (Edge Architecture spec) or the VHP_VARNISH_TAGS wp-config define.
* New: Admin UI improvements – properly associated labels for checkboxes and clearer explanatory copy.
* Dev: Test VCL and pytest stack updated to cover tag-based purging behaviour.

= 5.3.0 =
* September 2025
* New: `VHP_EXCLUDED_POST_STATUSES` to exclude statuses (e.g. drafts) from purge triggers
* New: `varnish_http_purge_valid_post_statuses` filter to customize statuses programmatically
* Fix: REST URL generation for tags and custom taxonomies respects `rest_base` and uses term IDs
* Fix: Avoid non-string entries in generated URL lists for REST links
* Fix: Correct WP version deactivation check (< 4.7)
* Fix: Correct loop when filtering multiple varnish IPs
* Fix: Strip query strings before deduplication of purge URLs
* Fix: Debugger request args and robust Via header handling (scalar/array)
* Minor: Typo fix in Devmode settings message

= 5.1.3 =
* June 2022
* Check if a required option exists before trying to use it

= 5.1.2 = 
* April 2022
* Fix typo in readme

= 5.1.1 =
* April 2022
* Prevent two versions of the plugin from running at once.
* Correct JSON

= 5.1 =
* February 2022
* WP 5.9 Compat
* Rate limiting to prevent abuse - if you try to purge more than the max number of posts in a go (default 50), a purge ALL is triggered
* Allows customizing the purge URL to support: (credit mickaelperrin)
  - Nginx cache purge mechanism that doesn't support regex directives
  - Custom purge location

= 5.0.3 =
* August 2021
* PHP 8 Compat

= 5.0.2 =
* April 2021
* Wrapping a function_exists check which shouldn't be needed, but it fataled for someone and an ounce of prevention yadda yadda.

= 5.0.1 =
* April 2021
* Updating incompatibility lists
* HHVM deprecation
* Allow saving Proxy IP with ports
* Add check for CloudFlare APO
* Improve purge execution fails
* Double check multiple varnish IPs

= 5.0 =
* March 2021
* Now purges draft and pending posts (to account for people who un-publish) - props @jerlarke
* Localhost the debugger json. They aren't updated that often, and the remote load is unnecessary.
* More support for Health Check
* Remove strtotime check on Age header - props Matt Fields
* Support for multiple IPs (based on P.Brisson's work)

= 4.8.1 =
* May 2019
* Compat with WP 5.2
* Correct changes with DB cache flushing (props @mathieuhays)
* Simplified logic for edge case debugging

= 4.8 =
* March 2019
* Improve debugger
* Clean code per standards
* Improve callback on WP-CLI

= 4.7.3 =
* December 2018
* Bugfix for Jetpack (Props @jherve)

= 4.7.2 =
* October 2018
* Fix regression with IP function name
* Restore "Right Now" activity box _only_ for people who use WP.com toolbar

= 4.7.1 =
* October 2018
* Documentation: Cleaning up language and spelling

= 4.7.0 =
* October 2018
* WP-CLI: documentation
* Bugfix: Nginx compatibility
* Bugfix: Only enqueue CSS on front0end if the admin bar is used (props @mathieuhays)
* Feature: Rebranding
* Deprecation: "Right Now" button (not needed anymore)

= 4.6.6 =
* September 2018
* Bugfix to allow Nginx proxy to flush individual pages.

= 4.6.5 =
* September 2018
* Bugfix to correct footer output. :facepalm: No broken functionality.

= 4.6.4 =

* September 2018
* Remove query variables from URLs to prevent URLs from being flushed more than once per update
* More selective loading of AMP urls

= 4.6.3 =

* August 2018
* Deprecated function support

= 4.6.2 =

* July 2018
* Fixing some translation output.
* Multisite fixes for settings pages.

= 4.6.1 =

* July 2018
* Fix situation where purging wasn't (props @carlalexander)

= 4.6.0 =

* July 2018
* Moved Varnish to it's own menu with a new custom icon (props Olesya)
* Add option to enable development for 24 hours (for super-admins only)
* Change debug mode to development mode and greatly improved overall
* Translation improvements
* Add new action hook for after a full purge (props @futtta)
* Change check for age-header to not require a second run (props @danielbachhuber)
* Confirm plugin and theme blacklist check (props @danielbachhuber)
* WP-CLI: add debug option to show all header output (props @danielbachhuber)
* WP-CLI: add debug option to grep content for known issues (props @danielbachhuber)
* WP-CLI: add new command to change devmode state

= 4.5.1 =
* June 2018
* Due to contention (devs hate it, users like it) the empty cache button colour on the toolbar is removed, and replaced with a carrot icon (I did not make it orange, but I wanted to)
* Add carrot icon to collapsed (mobile) toolbar
* Better button hiding
* Fixed a stupid argument issue with flushing memcached and I should have known better but oh well
* FAQ update re nginx

= 4.5.0 =
* May 2018
* Remote storage of problem plugins/themes
* Prevent auto-loading of scan for improved disclosure and compliance
* Changed colour of the purge button for improved visibility
* Support for nginx proxy headers

= 4.4.0 =
* March 2018
* Improve translations
* Massive improvements to the debugging tools
* Allow for port to be added to host headers (props @davidbarratt)
* WP-CLI for debugging

= 4.3.1 =
* 10 October 2017
* Copied a wrong line.

= 4.3.0 =
* 10 October 2017
* Add Varnish Flush for "this" page on front end
* Do not flush non-public taxonomies

= 4.2.0 =
* 30 August 2017
* More flexible support for custom cat/tag bases
* Added in support for custom taxonomies
* New function to generate the URLs, so it can be called by external plugins
* Move right now box to be called later, preventing double calls
* Extra check for if it's a URL, because some plugins are weird (props @danielkun)

= 4.1.1 =

* JSON - fixed overzealous json assumptions from causing errors
* WP-CLI - fixed prepending of domain on domain when using purge on a domain (props @ocean90)
* Typos. We hate them.

= 4.1 =

* JSON / REST API Support
* Fix for Varnish Status Page on MAMP (props @jeremyclarke)
* Filter for purge headers (props @ocean90)
* Disallow people from editing the Varnish IP on Multisite
* Drop support for pre 4.7 because of JSON / REST API
* Support flushing cache for private pages

= 4.0.3 =
* Better explanation when Cloudflare gets in the way of DNS
* Rename flush button for people who don't speak Varnish

= 4.0.2 =
* Support for WP-CLI commands and PHP > 5.5 (though please upgrade, props @robertpeake)
* Better information regarding Cloudflare
* Better failure on domains for scanner
* Better IP detection
* Break apart settings for faster saving

= 4.0.1 =
* Fix typo (on -> one)
* Correct permissions on Multisite (props @phh - resolves #27 #28)
* Correct weird merge error (props @phh - resolves #25 #26)
* Fix formatting in Changelog

= 4.0 =
* Added Varnish Status Page - Tools -> Varnish Status (includes basic scanning etc)
* Allow filter for `home_url()`
* Update readme with list of filters.
* Added wp-cli commands to flush specific URLs and wildcards
* Requires wp-cli 0.25+ to work [3315](https://github.com/wp-cli/wp-cli/issues/3315) for WP 4.6+
* Update `purge_post()` to validate page_for_posts ([Props JeremyClarke](https://github.com/Ipstenu/varnish-http-purge/pull/20))
* Add check for AMP ([Props JeremyClarke](https://wordpress.org/support/topic/varnish-http-purge-doesnt-update-amp-urls-on-post-update/))
* Purge 'default' AMP URL as well
* Cleanup on Uninstall

= 3.9.3 =
* Update Documentation and Readme

= 3.9.2 =
* Change purge notice so it can be dismissed.
* Fix purging of deleted posts.

= 3.9.1 =
* Fixing i18n which wasn't working and threw a stupid error on sites without pretty permalinks. (Props DH customer Rasmus and employee Heckman!)

= 3.9 =
* Retain query params on purge
* Do not use query part for regex purging [Credit: shaula](https://github.com/Ipstenu/varnish-http-purge/pull/18)
* Allow Varnish IP to be filtered. [Credit: floatingio](https://wordpress.org/support/topic/supply-varnish-ip-via-filter)
* Improve flushing for cases when there's no Post ID
* Add filter so other plugins can add events to trigger purge when they have no post ID
* Add compatibility with [Autoptimize](https://wordpress.org/plugins/autoptimize/) so it flushes Varnish when you flush their cache

= 3.8 =
* Add varnish_http_purge_events filter to allow people to add their own events for purging. (props @norcross)
* Add a method to grab the response from purge request and pass to the 'after_purge_url' action for debugging. (props @shaula)
* Added wp-cli command: wp varnish purge (to purge varnish)
* Adding some docblocks
* Fixing i18n

= 3.7.3 =
* Add varnish_http_purge_schema filter for changing the default schema. The default remains http (even if you set your home and/or site URL to https) because of sanity, but in order to support some edge cases, they can filter if they want. (props Drumba)

= 3.7.2 =
* Revisions were being mishandled and purging all inappropriately. (props Cha0sgr)

= 3.7.1 =
* Archives weren't purging. (props Ingraye)

= 3.7 =
* Optimizing flushes.
* Add filter to allow other people to hook in when 3rd party plugins are abjectly weird (props jnachtigall)

= 3.6 =
* Making purge be http only, since Varnish doesn't support https. This will prevent other issues for people using SSL with Varnish (though goodness knows why...)
* Forcing backslash on home_url. Why WP doesn't, I have no idea, but this will help sites not running regex.

= 3.5.1 =
* Language fix
* Using add_query_arg
* Ignore revisions

= 3.5 =
* Isset wrap for URL path and query which may not be set in rare conditions (props <a href="https://wordpress.org/support/topic/undefined-index-notices-4">hsz</a>)
* Added in flushing for feeds (requested by <a href="https://wordpress.org/support/topic/feed-not-purged">heypete</a>)

= 3.4 =
* Multisite support
* Button in toolbar
* Fix define message in debug mode
* Better parsing for if you set the define in the DB or config.

= 3.3.4 =
* Rollback. Sorry.

= 3.3.3 =
* Per request of Jetpack team, added in a <code>wp_cache_flush()</code> call when manually purging. This should only impact server side PHP caches (APC, Memcached etc)

= 3.3.2 =
* Varnish IP was too persnickity in PHP 5.4 (added in an 'and if not null' check - props <a href="https://wordpress.org/support/topic/patch-a-little-patch-to-purge-on-comment-posting">colinleroy</a>)

= 3.3.1 =
* Language Pack fixing.

= 3.3 =
* Quick and dirty fix for a plugin that is causing the URLs to purge <em>ALL THE TIME</em>

= 3.2 =
* Correcting conflict with host's default config.

= 3.1 =
* Refactoring Cleanup (otherwise known as Copy/Pasta error in variable name). (props Shredder)

= 3.0 =
* Adds 'Purge Varnish' button
* More selective purging, to account for different server setups
* Tighened up what purges and when
* Flushing categories and tags (per code from WP Super Cache, thanks!)
* Clarify requirements (Varnish and Pretty Permalinks)

= 2.3 =
* Purge images on deletion
* Fix for a VarnishIP when behind proxy servers not working on all hosts (props Berler)

= 2.2.1 =
* typo (hit . instead of / - Props John B. Manos)

= 2.2 =
* Added in workaround for Varnish purge reqs going AWOL when another proxy server is in place. (props to Shredder and Berler)
* Cache flushes when you change themes

= 2.1 =
* Header Image

= 2.0 =
* Commit access handed to Ipstenu
* Changed CURL to wp_remote_request (thank you <a href="https://wordpress.org/support/topic/incompatability-with-editorial-calendar-plugin?replies=1">Kenn Wilson</a>) so we don't have to do <a href="https://wordpress.org/support/topic/plugin-varnish-http-purge-incompatibility-with-woocommerce?replies=6">CURLOPT_RETURNTRANSFER</a> Remember kids, CURL is okay, but wp_remote_request is more better.

= 1.2.0 =
* Moved actual request execution to "shutdown" event
* Removed GET request due to bad performance impact
