roots of an old tree

Going Back to My Roots: Contributing to WordPress Plugins

   

Written by:

roots of an old tree

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

man wearing a safety vest standing in the middle of the road

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

close up photo of a game controller

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

Discover more from EnRoute

Subscribe now to keep reading and get access to the full archive.

Continue reading