
Before I was into home labs and media servers, I was a WordPress developer. This week I went back to my roots and opened four PRs across two WordPress plugins — and honestly, it felt great.
🐘 WordPress, Still Kicking
WordPress powers something like 43% of the web. The plugin ecosystem is massive, mostly open source, and — it turns out — very welcoming to new contributors. I picked two plugins I actually use and found some issues worth fixing.
The Plugins
- Redirection by John Godley — 2M+ active installs. Manages 301/302 redirects and 404 logging from your WordPress admin.
- WP Crontrol by John Blackbourn — 2M+ active installs. Gives you a UI to view, edit, and manually trigger WordPress cron events.
Both are indie-maintained by single developers who are responsive and actively merge community PRs. Perfect for first contributions.
1. Redirection — PR #4200

The issue: If a redirect is disabled, the Edit button disappears from the row actions. Want to tweak it? You have to re-enable it, edit it, then disable it again. Annoying.
The fix: One line — removed the enabled && guard from the condition that shows the Edit action. The capability check still applies; it just no longer cares whether the redirect is active.
This was the simplest possible fix. One character change, very satisfying.
2. Redirection — PR #4201
The issue: When you export redirects as a CSV, there’s no group column. Redirection lets you organize redirects into groups, but that information is lost on export — so if you do a bulk edit and re-import, everything lands in whichever group you select in the import UI.
The fix: Added a group column to the CSV export (populated from the groups array already passed to the exporter), and on import, resolve the group name back to an ID using a single get_all() lookup. Falls back gracefully to the UI-selected group if the name isn’t found. Old CSVs import unchanged.
This one touched both PHP (export + import) and the existing test suite. Felt like a proper feature addition.
3. WP Crontrol — PR #275

The issue: WP Crontrol uses manage_options everywhere to control who can access the plugin. On a WordPress multisite network, manage_options is available to all site admins — but you might only want network admins (who have manage_network_options) to see and use it.
The fix: Added a crontrol_manage_cap filter and a get_manage_cap() helper function. Replaced all 13 hardcoded manage_options strings throughout the codebase — including menu registration and action handlers — with get_manage_cap().
Usage is dead simple:
add_filter( 'crontrol_manage_cap', fn() => 'manage_network_options' );
4. WP Crontrol — PR #276
The issue: The “Run Now” button on a cron event wasn’t working for sites running Cavalcade, an alternative cron runner used on large WordPress hosting platforms. The button showed a “Failed to schedule” error, even though the event was actually being created.
The root cause: WP Crontrol was using an internal force_schedule_single_event() function that bypassed wp_schedule_single_event() and called _set_cron_array() directly. Cavalcade hooks into pre_schedule_event to intercept scheduling — but since we were skipping wp_schedule_single_event(), Cavalcade’s hooks never fired, and it returned a falsy result that WP Crontrol read as failure.
The fix: Replace force_schedule_single_event() with wp_schedule_single_event(1, $hook, $args, true). Since WP Crontrol requires WordPress 6.4+, the modern duplicate-check logic means scheduling at timestamp 1 (Unix epoch, 1970) will never trigger the duplicate guard for any real event. So Cavalcade’s hooks fire properly, and the entire force_schedule_single_event() function could be deleted — a net −44 lines.
🔢 The Tally
- 4 PRs across 2 repos
- Language: PHP
- Status: All open, waiting on review




Leave a Reply