Release - #1379
Merged
Merged
Release#1379
Conversation
* fix: guard action scheduler * fix: update PHP version * fix: enhance action scheduler checks Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pirate-bot <58979018+pirate-bot@users.noreply.github.com>
Contributor
Author
|
Make sure you've reviewed the |
Contributor
Author
Co-authored-by: HardeepAsrani <2649903+HardeepAsrani@users.noreply.github.com>
…me-tag Align readme stable tag with release version and trim changelog surface
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Bumps [codeinwp/themeisle-sdk](https://github.com/Codeinwp/themeisle-sdk) from 3.3.61 to 3.3.62. - [Release notes](https://github.com/Codeinwp/themeisle-sdk/releases) - [Changelog](https://github.com/Codeinwp/themeisle-sdk/blob/v3.3.62/CHANGELOG.md) - [Commits](Codeinwp/themeisle-sdk@v3.3.61...v3.3.62) --- updated-dependencies: - dependency-name: codeinwp/themeisle-sdk dependency-version: 3.3.62 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.13 to 2.2.14. - [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.2.14 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The first SDK release that carries the AI Connect module this PR opts into. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Picks up the AI Connect fixes since 3.3.64: the Enable button hides once the connector is active, the notice matches core's height, and the "enabled" event for products with their own notification UI. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
feat: register abilities with the Abilities API
- Added AI agent support: let AI assistants read and change your Visualizer charts and settings.
* fix: keep the DB refresh scheduled when Action Scheduler creation fails as_schedule_recurring_action() returns 0 instead of throwing when it cannot store an action. The activation path ignored that return, cleared the WP-Cron fallback anyway, and left the refresh hook with no trigger at all. Nothing recovered it: the recovery hook stood down whenever Action Scheduler was usable, and the migration was gated on the WP-Cron event that had just been deleted, so even a reactivation could fail the same way. Clear the fallback only after re-querying Action Scheduler for the action. Turn the recovery hook into a plain "is anything going to fire this hook" check, which also covers the legacy WP-Cron migration, so the duplicate scheduling code in Visualizer_Module_Upgrade is no longer needed. Two consequences of running that check on every request: - Re-arm WP-Cron only when the event is missing or its interval changed. Re-arming unconditionally pinned it to a past timestamp on every request, so the refresh became due on every cron spawn. - Schedule the action as unique. Action Scheduler creates the next recurrence only after the current one completes, so a concurrent request can arrive while nothing is pending and add a duplicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: clear a WP-Cron event left beside the Action Scheduler action Both schedulers fire visualizer_schedule_refresh_db, so a site holding an action and an event refreshes twice per interval. The recovery check counted the action alone as settled and left the event in place. Treat the refresh as settled only when Action Scheduler holds the action and no event fires the same hook beside it. Also from review: reuse the first lookup instead of querying Action Scheduler again when the action already exists, and name the hook and the group once instead of repeating the literals. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: skip instead of fatal when Action Scheduler is not loaded index.php loads Action Scheduler only when visualizer_can_use_action_scheduler() passes, so a host without wpdb::db_server_info() has none. set_up() called the library unconditionally, which ended the whole suite with a fatal before any test could report. Skip the file instead. Also corrects the WP-Cron comment: the check is missing or different interval, not a stale timestamp. A timestamp criterion would pin the event to the past again, which is what the check exists to prevent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: recover the refresh chain a killed run ends, and throttle the check Hands-on investigation on the reporting site corrected the premise of #1384. Reactivation did restore the action; the customer was reading WP Crontrol, where the hook correctly no longer appears after the Action Scheduler migration. The real defect is that a run killed mid flight ends the recurring chain for good: Action Scheduler creates the next occurrence inside schedule_next_instance(), which a host kill, fatal or timeout never reaches, and the queue cleaner then marks the action failed with no successor. The per-request check already recovers this. Add the two pieces it was missing: - Hook action_scheduler_ensure_recurring_actions, Action Scheduler's own daily assurance hook, as a floor under the per-request check for sites that serve few requests. - Throttle the per-request check to one run per 300s, recorded in an autoloaded option so a settled site spends no query on it. Action Scheduler needs the same 300s to mark a killed run failed, so a shorter window cannot recover one any sooner. The daily hook ignores the window. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: start a recovered run now, and stop rewriting an autoloaded option Two findings from review. The start time is local midnight derived from gmt_offset. West of UTC that midnight has not arrived yet, so a recovered run was parked up to twelve hours ahead and the charts stayed stale for the rest of the day. Fall back to the previous midnight when the computed one is still in the future. The throttle recorded its timestamp in an autoloaded option, so every window rewrote the alloptions blob and invalidated it for every process. A transient with the window as its expiry is not autoloaded, expires on its own, and keeps the read cached. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: prove the filter argument order instead of assuming it Review has now questioned the pre_as_schedule_recurring_action argument order twice. The racer records the two arguments it receives and the test asserts their types, so a swap fails loudly instead of silently forwarding the wrong value. Types separate them whatever value the code under test passes. Also from review: guard set_up() on the ActionScheduler classes the tests call statics on, not only the functions, and scope the gmt_offset change to a filter the framework restores. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: do not depend on plugin_basename() for the lifecycle hook name plugin_basename() resolves differently depending on where the plugin directory is loaded from, so the hook name register_activation_hook() used is not stable across environments. Loading the plugin from outside WP_PLUGIN_DIR registers the full path as the hook name while the test computes the short one, and the activation test then fires a hook nothing listens to and passes vacuously or fails. Call the callback the hook points at instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: say why the Action Scheduler precondition fails instead of skipping A red build on this assertion needs to point somewhere. Absent is skipped in set_up() because some hosts cannot run Action Scheduler; loaded but not initialized means the load order broke, and every other test in the class would then assert nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: do not drop the refresh on an unknown interval or a fractional offset Two findings from review, both on the WP-Cron fallback. wp_schedule_event() refuses a schedule WP-Cron does not know, and the fallback cleared the existing event before asking, so a visualizer_chart_schedule_interval filter returning an unregistered key left the refresh with nothing and the throttle then held the retry off. Fall back to the plugin's own schedule when the filtered key is not registered, which is what get_schedule_interval_seconds() already does for the interval itself. gmt_offset is a number rather than an integer, so the start time could carry a fraction. WP-Cron keys its array by that value, and PHP reports losing precision from wp-includes/cron.php. Cast the start time to an integer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: note that tear_down restores hooks, so test filters need no removal Reviewers have read the missing remove_filter() calls as a leak four times across this PR and its pro counterpart. WP_UnitTestCase_Base backs up $wp_filter in set_up() and restores it wholesale in tear_down(). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: record the check window only when a trigger exists The window skips work that is already done, so recording it after an attempt that established no trigger left the site without one until the window expired, with the daily assurance hook a day away. ensure_refresh_db_action() now reports whether the refresh ended up scheduled, and the caller caches only that. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: treat a live WP-Cron fallback as scheduled for the check window Where Action Scheduler is present but refuses, the fallback is the trigger, and the previous commit reported that as unscheduled. The window was then never recorded, so every request repeated the whole check and the refused insert. Split the two questions: settled means the refresh sits on the scheduler this site should use, which is what decides whether to act; having a trigger means something will fire the hook at all, which is what decides whether to cache. ensure_refresh_db_action() goes back to returning nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: read the cron schedules once when scheduling the refresh The key check and the interval lookup each called wp_get_schedules(). Read it once and derive both from the same array, which also makes the one-line helper that did the second lookup unnecessary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: keep the old WP-Cron event until its replacement is scheduled Changing interval cleared the old event and then scheduled the new one, so a refused schedule left the refresh with nothing. That is the bug this PR fixes on the Action Scheduler path, repeated on the WP-Cron one. Schedule first and remove the old event by its own timestamp afterwards. wp_clear_scheduled_hook() would remove the new event too, since WP-Cron does not dedupe recurring events for a hook. A matching timestamp means the write already replaced the old entry in place, so nothing is removed in that case. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: unschedule the old refresh event without passing its arguments The refresh is scheduled without arguments, so the old event has none to match. Keeps this in step with the Pro plugin, where PHPStan objected to passing the typed-as-array field where a list is expected. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: trim the comments Requested in review: keep the one line that says why, drop the paragraphs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test: type the pending action IDs as numeric strings Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
🎉 This PR is included in version 4.0.9 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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.
Linked issues
This release will close the following issues once merged:
wpdb::db_server_info()error #1361visualizer_schedule_refresh_dbremains missing after Visualizer reactivation #1384Public changelog