Skip to content

Releases: wpgaurav/gt-performance

GT Performance 1.0.6

Choose a tag to compare

@github-actions github-actions released this 31 Aug 11:08

Added

  • Separate controls for the main feed and the secondary feeds. "Disable secondary feeds only" keeps /feed/ serving and indexable while returning a 404 for comment feeds (site-wide and per post), category, tag, custom taxonomy, author, date, search, and post type archive feeds. "Remove secondary RSS feed links" keeps the main feed's discovery link in the document head and removes the rest. The existing all-or-nothing controls are unchanged and still win when enabled: "Disable every RSS feed" blocks the main feed too, and "Remove every RSS feed link" removes every discovery link.

Changed

  • The gauravtiwari.org WordPress preset now applies the two secondary-feed controls instead of removing every feed discovery link, so the main feed stays discoverable and indexable.

GT Performance 1.0.5

Choose a tag to compare

@github-actions github-actions released this 27 Aug 03:55

Fixed

  • Uninstalling with data removal enabled deleted this plugin's options and tables but never touched the filesystem, so wp-content/cache/gt-performance/ survived in full: cached HTML, generated CSS and JavaScript, logs, and both configuration files. redis-config.json.php holds a host, username, and password. The guard kept those unreadable over HTTP, but someone who asked for their data to be removed should not be left with credentials in wp-content. Uninstall now removes the directory, resolving the path the way Core\Paths does and confirming with realpath() that it still sits inside wp-content before deleting anything. wp-content/cache itself is left for other plugins.

GT Performance 1.0.4

Choose a tag to compare

@github-actions github-actions released this 27 Aug 03:35

Removed

  • All upgrade compatibility carried since 1.0.1. DropinRuntime::serve() no longer loads ConfigFile on behalf of a drop-in published before 1.0.1, Settings::compile() no longer deletes the configuration files those releases wrote, Database::install() no longer drops their tables, and uninstall.php no longer lists their names.

Upgrade note

  • A site running 1.0.0 or earlier still has that release's generated advanced-cache.php on disk. It loads a fixed list of runtime files that predates ConfigFile, so on the first request after this update it raises a fatal from wp-settings.php, before WordPress can catch it, taking the front end and wp-admin down together. Replace the drop-in before or during the update. The build distributed from gauravtiwari.org carries a migrator that does this automatically; for any other route, run the standalone migration snippet first: https://gist.github.com/wpgaurav/03d61d313df00b4127db92393ed74681

GT Performance 1.0.3

Choose a tag to compare

@github-actions github-actions released this 27 Aug 03:19

Fixed

  • The License screen's Activate, Deactivate, and Check buttons returned a blank page in the store build. Identical cause to the controls fixed in 1.0.2 - the handlers were still registered as admin_post_gtp_license_* while the buttons submitted gtperf_license_* - in a file the 1.0.2 sweep did not reach. The WordPress.org build has no licensing code and was never affected.
  • AdminActionWiringTest now discovers every PHP file under src/ instead of checking a hardcoded list of four. The hardcoded list was the same mistake the test exists to catch: it could not see the licensing module, which only ships in the store build, so 1.0.2 shipped believing the wiring was fully verified.

GT Performance 1.0.2

Choose a tag to compare

@github-actions github-actions released this 27 Aug 03:09

Fixed

  • Every admin control in 1.0.1 returned a blank page. The 1.0.1 rename moved the action names the controls submit from gtp_ to gtperf_, but left all 21 add_action( 'admin_post_gtp_...' ) and add_action( 'wp_ajax_gtp_...' ) registrations untouched, so nothing was hooked to the names being submitted. WordPress does not error in that case: it fires an action with no listeners and exits, which the browser renders as an empty response and which leaves no trace in the error log. Purge, Cloudflare connect/sync/preview/diagnose/token, Redis test and install, page-cache drop-in install, xCloud refresh, purge verification, Commerce Safety Lab, CSS training and regeneration, Fleet export and import, database cleanup, the admin-bar quick actions, the CSS report poll, and the Private Islands fragment endpoint were all dead.
  • The rename missed these because it matched \bgtp_, and in admin_post_gtp_purge the gtp_ is preceded by an underscore, which is a word character, so the boundary never applied. Hook strings are the one place that flaw could hide, and nothing compared the two sides.

Added

  • AdminActionWiringTest asserts that every action an admin control submits, every admin-bar action, and every AJAX action posted by the bundled JavaScript has a matching handler registered, and that no hook is registered under the retired prefix. A silent-blank-page regression of this shape now fails the test suite.

GT Performance 1.0.1

Choose a tag to compare

@github-actions github-actions released this 27 Aug 02:41

Security

  • The compiled cache configuration and the Redis runtime configuration are no longer executable PHP. Both are stored as JSON behind a fixed <?php exit; ?> guard line and are read with file_get_contents() and json_decode(), never included. The guard keeps a direct web request from disclosing the Redis credentials on servers that do not honour .htaccess.
  • The early cache drop-in and RequestContext::fromGlobals() now sanitize the request through one shared implementation. Control characters are stripped and every name and value is bounded before any of it reaches the gt_performance_html filter.

Fixed

  • Updating from 1.0.0 took the whole site down. The drop-in published by that release loads a fixed list of runtime files that predates ConfigFile, so the moment the new plugin files landed it fatally errored inside wp-settings.php — before WordPress exists to catch it — taking the front end and wp-admin down together with no way back except filesystem access. DropinRuntime::serve() now loads its own dependency when an older drop-in did not.
  • Schema 3 renames this plugin's tables from the gtp_ prefix to gtperf_. Without a schema bump the upgrade left the old tables in place and every queue, dependency, and CSS artifact query failed against a table that did not exist. The upgrade now creates the renamed tables and drops the superseded ones.
  • WpCacheConstant::enable() rewrote an already-correct WP_CACHE line to an identical value, read the unchanged file as a failed update, and returned an error — which made DropinInstaller::install() delete the drop-in it had just published. Installing twice in a row disabled page caching.
  • DropinInstaller::syncVersion() gated only on the version, so a migrated or restored site running the same release from a new path kept a compiled configuration naming the old directory. The drop-in found nothing to load and the site served uncached indefinitely without reporting anything. The gate now tracks the location alongside the version.
  • Keyboard focus styles were pruned out of generated CSS. :focus-visible and :focus-within matched the shorter focus alternative in the dynamic-state pattern, leaving -visible and -within fused to the class name, so the rules matched nothing and were removed as unused.
  • RequestContext::fromGlobals() did not unslash the superglobals, so any URL, query value, or cookie containing a quote hashed differently in WordPress than in the drop-in and could never produce a cache hit.
  • DropinInstaller::installedVersion() captured the trailing period after the drop-in signature, which made every version comparison unequal and reinstalled the drop-in on each request.

Changed

  • Page-cache entry metadata is now <hash>.meta.json instead of a generated <hash>.meta.php. Because metadata no longer passes through opcache, the opcode-invalidation workaround is gone along with the stale-metadata window it covered on hosts running opcache.validate_timestamps=0.
  • advanced-cache.php is a bundled file copied verbatim from dropins/, with only its version stamped in. It resolves the cache root from WP_CONTENT_DIR and the plugin directory from the compiled configuration, so no path is baked into the published drop-in.
  • Every output buffer the plugin opens is closed explicitly through Core\OutputBuffer, on shutdown at priority 0, ahead of core's own wp_ob_end_flush_all().
  • Renamed the GTP_ and gtp_ prefixes to GTPERF_ and gtperf_ across constants, transients, AJAX actions, the cron schedule, the Private Islands shortcode, and the Redis key prefix. There is no compatibility shim: wp-config.php constants and any stored shortcode must use the new names.
  • Updated sabberworm/php-css-parser from 8.9.0 to 9.4.0. Version 9 requires thecodingmachine/safe at runtime, which adds about 2.4 MB to the package and eagerly loads 79 function-definition files when the plugin bootstraps. That cost lands only on full WordPress requests, measured at roughly 5 ms; requests served from the page cache never load the plugin autoloader and are unaffected.
  • The compiled configuration files are now config.json.php and redis-config.json.php. The names deliberately differ from the config.php and redis-config.php used up to 1.0.0: a drop-in left over from that release reads those paths with require, so pointing the new guarded files at the old names could have blanked every front-end response if the drop-in swap did not complete. Compiling also deletes the old files.
  • dropins/ is now covered by the coding-standards run.

GT Performance 1.0.0-rc.6

Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 Aug 02:51

Fixed

  • Fixed "Remove WordPress version" pinning every visitor to pre-update core assets. Dropping ver from a core script or stylesheet URL leaves an address that never changes across a WordPress release, so browsers and CDNs holding it under a long max-age keep serving the old bytes indefinitely. The version is now replaced with a stable site-specific hash instead of removed, which hides the release just as well and still busts the cache on every update. Symptom on a 7.1 upgrade: the new admin bar site icon rendered at full size because the cached stylesheet predated the .site-icon rules.

GT Performance 1.0.0-rc.5

Pre-release

Choose a tag to compare

@github-actions github-actions released this 19 Aug 15:22

Fixed

  • Fixed the Operations cards sitting flush against the panel edge while the panel heading above them was inset, and fixed their rows sitting 40px apart against 20px columns. The grid carried no inset of its own, and each card is a panel in its own right whose 20px bottom margin stacked on the grid gap and hung a phantom band under the last row.
  • Fixed the API token permission list and the "Install drop-ins, purge, and sync Cloudflare on the dashboard" link hanging outside the panel inset. The link now uses the existing .gtp-inline-link treatment, matching "View release history".
  • Fixed .gtp-inline-link never picking up the narrow inset at the mobile breakpoint. Its override sat in a media block declared earlier in the file than the rule it was meant to override, so source order silently discarded it.

Changed

  • The panel inset is now a single --gtp-inset token, 24px normally and 20px under 782px, replacing 26 hard-coded values and five per-class media overrides. Because the token is redefined on .gtp-admin rather than on each block, a rule declared later in the file can no longer defeat the responsive override, which is the defect behind the mis-inset link and permission list. Adding a new block to a panel now means using the token instead of remembering to register the class in two places.

GT Performance 1.0.0-rc.4

Pre-release

Choose a tag to compare

@github-actions github-actions released this 19 Aug 14:45

Fixed

  • Fixed the "Other cache rules that also match this site" block rendering at three different left offsets. The heading had no rule at all, so it fell back to the browser default and hung outside the panel inset; the note carried the standard 24px inset; and the conflict list carried none. The heading now uses .gtp-subhead, the list is inset to match its siblings, and both pick up the 20px inset at the mobile breakpoint. The default 1em heading margin stacking on top of the note's own 20px padding also left an oversized gap, which is now collapsed.
  • Fixed the "Or create it automatically" heading inside .gtp-operation-panel inheriting browser default type and margins. It now shares the 14px heading rule already used by the preset and database-result headings.

Changed

  • Admin notices are now a compact status pill instead of a full-width WordPress notice bar. When a failure carries an upstream reason, the pill gains a "Why?" disclosure that opens the detail in an anchored popover rather than pushing the page down. The popover is anchored to its own pill rather than promoted to the top layer, so it lands in the right place without depending on CSS anchor positioning, and it light-dismisses on outside click or Escape. Dismissing removes the gtp_notice query argument instead of hiding the node, so a reload cannot resurrect a notice that has already been read.

GT Performance 1.0.0-rc.3

Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Aug 06:18

Fixed

  • Fixed Cloudflare cache rule synchronization failing outright on any site with more than one bypassed query parameter. RuleExpression::compile() emitted a separate concat("&", http.request.uri.query) per parameter, and Cloudflare rejects an expression that calls concat more than once (error 20127), so every sync returned HTTP 400 and the managed rule silently stopped updating. Each parameter now compiles to an equivalent starts_with() plus contains pair that calls no rationed functions.
  • Fixed the managed rule permanently reporting drift on plans that do not support custom cache keys. A custom cache key is an Enterprise capability, so the write only lands after RuleManager strips it, but RuleCompiler::rule() kept compiling the ideal rule for comparison. Drift was measured against a shape Cloudflare can never store and no amount of syncing cleared it. Comparison now uses the shape the plan accepts, while a sync still attempts the ideal rule so an upgraded plan heals itself.
  • Fixed cache rule conflict detection ignoring rules that never name a hostname. A catch-all expression such as true applies to every hostname in the zone and was reported as zero conflicts.
  • Fixed a fatal error in the connection check on zones with no cache ruleset yet, where a WP_Error was indexed as an array.

Added

  • Cloudflare API failures now report the reason Cloudflare gave, including its numeric error code and any nested error chain, instead of collapsing every failure into one generic sentence. Requests that never reached Cloudflare are reported separately from requests Cloudflare rejected.
  • Added a Cloudflare connection check that walks integration state, edge ownership, credentials, authentication, zone lookup, and cache rule read and write in order, and names the stage that failed with the reason. The write stage rewrites the managed rule with its own current contents, so it proves the write path without changing anything.
  • Added an API token panel listing the exact permissions the integration needs, a Cloudflare token-creation template link, and optional automatic creation of a zone-scoped token when a Global API Key is on file. A newly minted token is exercised before it replaces working credentials, because Cloudflare reveals a token secret only once.
  • The rule plan panel now lists overlapping rules with their expressions and reports whether a custom cache key was applied.

Changed

  • A failed synchronization now still records the live rule plan, so the screen reflects current zone state instead of appearing never to have run.