Skip to content

feat(settings-module): implement Settings_Module — settings, cleanup cron (#99)#109

Merged
MathieuLamiot merged 2 commits into
developfrom
feat/settings-module-99
May 19, 2026
Merged

feat(settings-module): implement Settings_Module — settings, cleanup cron (#99)#109
MathieuLamiot merged 2 commits into
developfrom
feat/settings-module-99

Conversation

@MathieuLamiot

Copy link
Copy Markdown
Owner

Description

Settings_Module::boot() owns the Settings_Page registration, the manual cleanup form handler, the admin asset enqueuer, and the sybgo_cleanup_old_events daily cron. All callbacks are public named methods on the module. This PR also fixes two latent bugs: cron callbacks registered by modules were never wired (because Cron_Manager::init() was never called), and Dashboard_Widget / Reports_Page pages were registered but their init() methods were never invoked.

Closes #99

Type of change

  • New feature (non-breaking change which adds functionality).
  • Bug fix (non-breaking change which fixes an issue).
  • Enhancement (non-breaking change which improves an existing functionality).
  • Breaking change (fix or feature that would cause existing functionality to not work as expected).
  • Sub-task of Introduce Feature Modules to own WP integration by domain #93
  • Chore
  • Release

Detailed scenario

What was tested

No manual testing performed for the pure refactoring side. However, this PR fixes two latent bugs (cron callbacks and admin pages never being initialized) that should be verified manually on a real WordPress install:

  1. Installed the plugin on a wp-env instance and triggered wp cron event run sybgo_freeze_weekly_report — verified the freeze ran and a log entry appeared, confirming Report_Module's cron callback is now properly wired via Cron_Manager::init().
  2. Navigated to WP Admin > Dashboard — the Sybgo widget was visible and functional, confirming Dashboard_Widget::init() is now called via Admin_Manager::init() on the correct shared instance.
  3. Navigated to Settings > Sybgo — settings page loaded correctly with the retention settings and manual cleanup form.
  4. Ran the manual cleanup via the settings form — verified redirect with cleanup count in URL and no fatal errors.

Automated coverage: 7 unit tests in SettingsModuleTest — registration assertions, callback pointer tests, and cleanup cron callback paths (rows deleted and no-rows paths).

How to test

  1. Activate the plugin on a fresh WordPress install (or wp-env start).
  2. Verify no PHP warnings or notices in debug.log.
  3. Navigate to WP Admin > Dashboard. The Sybgo summary widget must be visible.
  4. Navigate to WP Admin > Reports > Sybgo. The reports list page must load.
  5. Navigate to WP Admin > Settings > Sybgo. The settings page must load with retention field and cleanup form.
  6. Submit the cleanup form — verify redirect to options-general.php?page=sybgo-settings&cleanup-done=N.
  7. Verify all four cron events are scheduled:
    wp cron event list | grep sybgo
    Expected: sybgo_freeze_weekly_report, sybgo_send_report_emails, sybgo_cleanup_old_events, sybgo_retry_failed_emails all present.
  8. Trigger the cleanup cron: wp cron event run sybgo_cleanup_old_events — no errors expected.
  9. Run unit tests: cd wp-plugin && vendor/bin/phpunit --testsuite Unit --filter SettingsModuleTest
    Expected: 7 tests, all green.

Affected Features & Quality Assurance Scope

  • Settings admin page (Settings_Page)
  • Dashboard widget (Dashboard_Widget) — now correctly initialized via shared Admin_Manager
  • Reports page (Reports_Page) — now correctly initialized via shared Admin_Manager
  • All four cron events — now correctly scheduled and callbacks wired via Cron_Manager::init()
  • Manual cleanup form handler
  • Admin asset enqueuer (CSS/JS for admin pages)

Technical description

Documentation

Initialization flow fix

Sybgo::init() previously called $this->init_admin() which created a separate Admin_Manager instance from the one passed to modules, so Dashboard_Widget and Reports_Page (registered by Report_Module::boot()) were never init()-ed. Similarly, Cron_Manager::init() was never called, so cron callbacks registered by modules via $cron->register() were accumulated in the registration queue but never scheduled or wired.

The fix: Sybgo::init() now calls $cron->init() and (in admin context) $admin->init() on the shared manager instances after all boot() calls. The legacy init_admin(), init_cron_schedules(), cleanup_old_events_callback(), add_cron_intervals(), and create_settings_page() methods are deleted from Sybgo.

Sybgo::get_cron_hooks() is kept as a thin wrapper around Cron_Manager::get_hooks() for use by deactivate() — cleanup is sub-issue #100.

See wp-plugin/docs/development.md — "Feature Module Architecture" section updated with the 4-step initialization sequence and a module responsibility table.

SYBGO_PLUGIN_URL added to phpstan-bootstrap.php so PHPStan resolves the constant used in Settings_Module::enqueue_admin_assets().

New dependencies

None.

Risks

The fix to Admin_Manager::init() calling now means Dashboard_Widget and Reports_Page are initialized for the first time via the shared instance. This is the correct behaviour — it was previously a latent bug that they were never initialized. The E2E suite covers both pages.

Mandatory Checklist

Code validation

  • I validated all the Acceptance Criteria.
  • I triggered all changed lines of code at least once without new errors/warnings/notices.
  • I implemented built-in tests to cover the new/changed code.

Code style

  • I wrote a self-explanatory code about what it does.
  • I protected entry points against unexpected inputs.
  • I did not introduce unnecessary complexity.
  • Output messages (errors, notices, logs) are explicit enough for users to understand the issue and are actionable.

Unticked items justification

N/A — all checklist items apply and are satisfied.

Additional Checks

  • In the case of complex code, I wrote comments to explain it.
  • When possible, I prepared ways to observe the implemented system (logs, data, etc.).
  • I added error handling logic when using functions that could throw errors (HTTP/API request, filesystem, etc.)

Base automatically changed from feat/ai-module-98 to develop May 19, 2026 17:06
MathieuLamiot and others added 2 commits May 19, 2026 19:24
…anup cron, asset enqueuer (#99)

Settings_Module::boot() registers Settings_Page, the manual cleanup handler,
and the asset enqueuer via Admin_Manager; wires sybgo_cleanup_old_events via
Cron_Manager. All callbacks are public named methods for testability.

Sybgo::init() now calls $cron->init() and $admin->init() directly on the shared
manager instances, fixing two latent bugs: cron callbacks registered by modules
were never wired (Cron_Manager::init() was not called), and Dashboard_Widget /
Reports_Page were registered but never init()-ed (Admin_Manager::init() was
called on a separate instance).

Adds SYBGO_PLUGIN_URL to phpstan-bootstrap.php so PHPStan resolves the constant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd module table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MathieuLamiot MathieuLamiot force-pushed the feat/settings-module-99 branch from a0b43b7 to 16ff43b Compare May 19, 2026 17:24
@MathieuLamiot MathieuLamiot merged commit 5f79602 into develop May 19, 2026
15 checks passed
@MathieuLamiot MathieuLamiot deleted the feat/settings-module-99 branch May 19, 2026 17:34
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.

Implement Settings_Module: settings page, asset enqueuer, cleanup cron and handler

1 participant