Skip to content

fix(plugins-window): align dock badge with in-window update count (#258)#263

Merged
epeicher merged 2 commits into
trunkfrom
fix/plugins-dock-badge-orphans-258
May 21, 2026
Merged

fix(plugins-window): align dock badge with in-window update count (#258)#263
epeicher merged 2 commits into
trunkfrom
fix/plugins-dock-badge-orphans-258

Conversation

@epeicher
Copy link
Copy Markdown
Collaborator

@epeicher epeicher commented May 21, 2026

Summary

Closes #258.

The Plugins dock badge could show a higher count than the "Update available" filter inside the Plugins window (reporter saw badge=3, filter=2, persistent across hard reload).

Root cause. The dock badge is regex-extracted from $menu['plugins.php'] title HTML, which Core builds from count( $update_plugins->response ) — the raw transient count. The in-window filter counts REST /wp/v2/plugins rows where desktop_mode_update_available.available === true, which is set only when the transient entry maps to a plugin file get_plugins() returns. They drift when the transient holds orphan rows — entries for deleted plugin files, or rows injected by third-party update servers that key on a file get_plugins() doesn't return. The reporter's site runs Bricks + Admin Columns Pro, both of which use that pattern.

Fix. Override the badge for plugins.php with the intersection of update_plugins->response and get_plugins() — the same intersection the REST endpoint already applies.

  • New helper desktop_mode_plugins_window_count_visible_updates() in rest-fields.php next to the related transient logic.
  • desktop_mode_build_dock_items() calls it for the plugins.php slug after the regex extraction (the regex stays as a fallback for the generic case).
  • Two new PHPUnit tests: orphan-stripping and empty-transient → 0. Existing regex-extraction test moved to themes.php so it still exercises the generic path.

Reproduction (verified live)

Seeded update_plugins with 3 rows where only one (crowdsignal-forms/crowdsignal-forms.php) matched get_plugins(). Without the override the dock badge rendered 3 while the window filter showed Update available 1. With the override the badge correctly rendered 1.

WP menu badge would render: 3
Plugins window filter would render: 1

Test plan

  • npm run test:php -- --filter='Tests_DesktopMode_BuildDockItems' passes (new + existing).
  • On an install with at least one plugin updating: dock badge equals the count in the Plugins window's "Update available" filter.
  • Plant an orphan in update_plugins (docker exec ... wp eval 'set_site_transient("update_plugins", …);'), hard reload → badge does not over-count.
Open WordPress Playground Preview

Core builds the Plugins menu badge from `count( $update_plugins->response )`,
which the dock-builder regex captures verbatim. That raw count can include
orphan rows the in-window "Update available" filter ignores — entries for
deleted plugin files or rows injected by third-party update servers
(`update_plugins_{hostname}` filter, custom `site_transient_update_plugins`
filters) that key on a file `get_plugins()` doesn't return. Reported on a
Bricks + Admin Columns Pro site: badge says 3, filter says 2, hard reload
doesn't help because the orphans persist in the transient.

Override the badge for the `plugins.php` slug on non-multisite with the
intersection of `update_plugins->response` and `get_plugins()` — the same
intersection the REST `/wp/v2/plugins` rows already apply — so the dock
count provably matches what the user sees inside the window. Multisite
keeps Core's intentional "no badge" posture untouched.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

Plugin Check's `plugin_updater_detected` rule treats the literal string
`site_transient_update_plugins` as evidence of a self-updater regardless
of whether it appears in code or a comment. The previous wording named
the filter in a docblock; reword to reference the standard `Update URI`
mechanism instead.

No behavior change.
@epeicher epeicher merged commit cc1f75f into trunk May 21, 2026
5 checks passed
@epeicher epeicher deleted the fix/plugins-dock-badge-orphans-258 branch May 21, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugins update count badge value incorrect

1 participant