Repository navigation
Conversation
W3TC's DbCache wrapper reads `$wpdb->col_info` after each cacheable query, which triggers `wpdb::load_col_info()` -> `mysqli_num_fields()`. For non-SELECT queries the result is `true` (bool), so this fatals with "Argument #1 ($result) must be of type mysqli_result, true given". W3TC bypasses caching for write queries via a regex that matches `START TRANSACTION`, `INSERT`, `COMMIT`, etc. — but not `BEGIN`. Switching `BEGIN` to `START TRANSACTION` (semantically identical in MySQL) lets W3TC's regex catch it and skip the col_info path. Reproduced locally with W3TC 2.9.4: identical stack trace with `BEGIN`, no fatal with `START TRANSACTION`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Filip Ilić <ilic.filip@gmail.com>
Fix W3 Total Cache DbCache fatal in batch_insert
Updates wp-coding-standards/wpcs to 3.4.1, which fixes a security issue in the WordPress.WP.EnqueuedResourceParameters sniff where running PHPCS over untrusted PHP code could lead to arbitrary command execution on the scanning host (GHSA-3pwp-g2mj-5p3v). Also bumps the required transitive dependencies: - phpcsstandards/phpcsutils to 1.2.3 - phpcsstandards/phpcsextra to 1.5.1 Lock-file only; composer.json constraints already allowed 3.4.1. Verified locally with PHPCS: no new violations. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Filip Ilic <ilic.filip@gmail.com>
Security: update WPCS to 3.4.1
Every request writes the options it read to wp_option_optimizer_tracked
on shutdown with INSERT ... ON DUPLICATE KEY UPDATE. InnoDB locks rows in
VALUES order, which followed per-request access order, so concurrent
requests locked the same rows in different orders and deadlocked
("Deadlock found when trying to get lock"), losing that request's counts.
Sort the options before writing so all writers lock in one order. On a
failed insert, ROLLBACK instead of sending COMMIT (which also hid the
error by clearing $wpdb->last_error), and retry once on a deadlock; the
deadlock rolls back the whole transaction, so the retry can't double count.
Reproduced locally with 20 parallel writers x 50 batch_insert() calls of
200 shuffled options: ~920/1000 deadlocks before, 0/1000 after with all
200000 increments landed. Retry path verified with a forced deadlock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PHPStan 1.12 to 2.3, with szepeviktor/phpstan-wordpress 1.3 to 2.0 (which brings WordPress stubs 6.9 to 7.1). The code needed no changes. Two config entries did: - excludePaths: tests does not exist in this repository, which PHPStan 2 refuses; marked optional as tests (?). - The ignore for missingType.generics matched nothing on PHPStan 2 and is reported as unused; removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Filip Ilic <ilic.filip@gmail.com>
Fix deadlocks when concurrent requests write tracked options
Update PHPStan to 2.3
* Bump version to 1.6.2 - Version 1.6.2 in the plugin header, readme Stable tag and package.json. - Changelog: deadlock fix, W3 Total Cache DbCache fix, readme improvements. - Restore "Requires at least: 6.7". The readme rework lowered it to 6.4, but the plugin calls wp_autoload_values_to_autoload() (WP 6.6+) unguarded, so WP 6.4/6.5 sites would be offered an update that fatals. - "Tested up to: 7.1" (current WordPress; Plugin Check flags 7.0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add 1.6.2 upgrade notice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Rename plugin to AAA Autoload Optimizer and release as 1.7.0 - Plugin name, readme title and all user-facing strings: "AAA Autoload Optimizer". #76 had renamed the headers to "Autoload Optimizer"; the admin page, README.md, known-plugins.json and docblocks still said "AAA Option Optimizer". The Tools menu label is now "Autoload Optimizer". - Slug, text domain, option names and PHP namespaces are unchanged. - Version 1.6.2 -> 1.7.0 (plugin header, Stable tag, package.json, changelog, upgrade notice). The rename is a minor-version change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
- New WordPress.org banners (772x250, 1544x500) with the new name. - Add Dutch banners as banner-*-nl_NL.png, the locale naming WordPress.org uses for localized assets. - Replace github_banner_aaaoo_pp.png with github_banner_aaaao_pp.png and point README.md at it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Update banners for the AAA Autoload Optimizer rename
When the table is too narrow, DataTables Responsive moves the Autoload
and Actions cells into a child row. updateRowOnSuccess only patched the
parent <tr>, so the child row kept showing the old status and button and
looked broken. Update the row data and redraw instead, so Responsive
re-renders child rows too (server-side tables re-fetch the page).
Rows are now looked up by DataTables row ID ('#id') instead of a jQuery
'tr#…' selector, so option names with characters like '.' or ':' match.
This also fixes bulk delete, which never converted '.' in names.
Reported at https://wordpress.org/support/topic/changing-row-status-or-deleting-it-wont-work-after-changing-the-table-order/
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tables initialised inside a hidden tab could not measure their
columns, so Responsive never collapsed them and they overflowed the
panel ("table loads broken, missing columns"). Recalculate visible
tables whenever a tab is opened.
- The tab panel was width: 100% plus 60px padding, so it always
overflowed its container by 60px. Use box-sizing: border-box, and bump
the stylesheet version so browsers pick it up.
- The All options table showed "Remove autoload" for options stored as
'off' or 'auto-off' (WordPress 6.6+ values), because only 'no' was
treated as not autoloaded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Option names and values shown in the admin tables are arbitrary strings that may contain HTML metacharacters. Render them through DataTable.render.text() and an escapeHtml() helper, and build element ids/attribute targets from the sanitised row id rather than the raw name, so a crafted name cannot break out of the generated markup. Drop the now-redundant server-side htmlentities() on the value field to avoid double-encoding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Legacy tracking treats every hook starting with 'option_' as an option read,
including 'option_page_capability_{option_page}', which wp-admin/options.php
builds from request data and fires before its capability check. That let any
logged-in user store an arbitrary string as a tracked option name.
- Skip the 'option_page_capability_' hook in legacy tracking; it is a
capability filter, not an option read.
- Reject names that are empty, longer than 191 characters (the column width),
or contain whitespace, quotes, backslashes or angle brackets, in both
tracking modes. Filterable via aaa_option_optimizer_is_trackable_option_name,
except the length limit.
- Keep dots in generated row ids so names like foo.bar and foo_bar no longer
collide.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The same option can be listed in more than one table (e.g. "Used, but not autoloaded" and "All options"). Both rendered the same popover and checkbox ids, so the "Show" button in the second table targeted the popover in the first, hidden table and nothing opened. Prefix these ids with the table id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
generateRowId() replaced every character outside the allow-list with '_', so distinct names like 'foo:bar' and 'foo_bar' got the same row, checkbox and popover id, and an action on one could update the other row's display. Encode each character outside [A-Za-z0-9_] as '-<hex code point>-' instead; '-' never appears literally, so every option name maps to a unique id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Options API accepts whitespace, quotes and backslashes in option names, so rejecting them stopped tracking real options, which then showed up as "Unused, but autoloaded" and were offered for deletion. Only reject empty names and names over 191 characters, counted with mb_strlen() to match the VARCHAR(191) column. The option_page_capability_ skip and output escaping still cover the reported injection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…update Fix table actions and layout when columns are collapsed
…er-ids Make popover and checkbox ids unique across tables
…output Merge admin table escaping and id fixes into develop
- Version 1.7.1 in the plugin header, readme Stable tag, package.json and package-lock.json. - Changelog for the admin table fixes and hardening merged since 1.7.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Release 1.7.1
main's tree at v1.7.0 is identical to develop at c0b331f, so develop's content is kept as is. This only records main as merged so the 1.7.1 release PR from develop to main has no conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Test on Playground |
tacoverdo
self-requested a review
November 2, 2026 12:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 1.7.1: merges
developintomain.After merging, publish the GitHub release
v1.7.1frommain. Publishing it runsdeploy.yml, which pushes the plugin and the.wordpress-org/assets to WordPress.org.🤖 Generated with Claude Code