WB Ad Manager Pro uses WordPress cron to run background tasks for analytics aggregation, campaign budget monitoring, billing, classified expiration, and cleanup. All cron jobs are managed centrally by the Cron_Manager class (Core/class-cron-manager.php) and are scheduled on plugin activation.
Cron Jobs Overview
| Hook | Schedule | Description |
|---|---|---|
wbam_pro_daily_aggregation |
Daily (3:00 AM) | Aggregates raw analytics data into daily summary stats |
wbam_pro_hourly_cleanup |
Hourly | Cleans up old raw analytics data beyond retention period |
wbam_pro_hourly_billing |
Hourly | Calculates CPM/CPC charges for active campaigns with unlimited budgets |
wbam_check_campaign_budgets |
Every 15 minutes | Checks campaign spend against budgets and auto-pauses exhausted campaigns |
wbam_check_low_balances |
Twice daily | Sends low balance alert emails to advertisers approaching zero |
wbam_expire_classifieds |
Hourly | Marks active classified listings as expired when their expires_at date passes |
wbam_expire_upgrades |
Hourly | Expires classified upgrades (featured, highlighted, urgent, top) past their expiration date and downgrades listings that lose their last active featured upgrade |
wbam_cleanup_audit_log |
Daily | Deletes audit log entries older than the configured retention period (default: 90 days) |
Additional Billing Cron Jobs
The Classified_Billing class registers two additional cron jobs independently of the main Cron_Manager:
| Hook | Schedule | Description |
|---|---|---|
wbam_process_classified_billing |
Hourly | Processes recurring billing for featured/premium classifieds; uses MySQL advisory locks to prevent double-billing on distributed servers |
wbam_classified_expiration_warnings |
Daily | Sends email warnings to advertisers whose featured listing will expire within a configurable number of days (default: 3) |
Custom Schedules
The plugin registers two custom WordPress cron schedules in addition to the built-in hourly, twicedaily, and daily schedules:
| Schedule Name | Interval | Display Name |
|---|---|---|
wbam_fifteen_minutes |
900 seconds (15 min) | Every 15 Minutes |
wbam_five_minutes |
300 seconds (5 min) | Every 5 Minutes |
The 15-minute schedule is used by wbam_check_campaign_budgets to catch exhausted campaigns quickly. The 5-minute schedule is available for custom use via the wbam_pro_cron_jobs filter.
Customizing Cron Jobs
Adding or Modifying Jobs
Use the wbam_pro_cron_jobs filter to add, remove, or modify cron jobs:
add_filter( 'wbam_pro_cron_jobs', function( $jobs ) {
// Add a custom cron job.
$jobs['my_custom_cleanup'] = array(
'schedule' => 'daily',
'callback' => array( MyClass::class, 'run_cleanup' ),
'description' => 'my_custom_cleanup',
);
// Change campaign budget check to every 5 minutes.
$jobs['wbam_check_campaign_budgets']['schedule'] = 'wbam_five_minutes';
// Remove a job.
unset( $jobs['wbam_cleanup_audit_log'] );
return $jobs;
} );
After modifying the filter, deactivate and reactivate the plugin (or visit the Tools page) to reschedule the cron events with the new intervals.
Action Hooks
Several cron jobs delegate their work via WordPress actions rather than calling module methods directly. This avoids tight coupling and lets modules register their own handlers:
| Cron Hook | Delegates To Action |
|---|---|
wbam_pro_hourly_billing |
wbam_calculate_hourly_billing (handled by Wallet module) |
wbam_check_campaign_budgets |
wbam_do_check_campaign_budgets (handled by Campaign module) |
wbam_check_low_balances |
wbam_do_check_low_balances (handled by Wallet module) |
The action names intentionally differ from the cron hook names to prevent infinite recursion if do_action() were called with the same hook name that triggered the cron callback.
Post-Execution Hooks
Each cron job fires a completion action that you can hook into for logging or follow-up tasks:
| Action | Fired After |
|---|---|
wbam_daily_aggregation_complete |
Daily analytics aggregation |
wbam_hourly_cleanup_complete |
Hourly raw data cleanup |
wbam_classifieds_expired |
Classified listings expired (passes count) |
wbam_upgrades_expired |
Classified upgrades expired (passes count) |
wbam_classified_downgraded |
A classified lost its last featured upgrade (passes classified ID) |
wbam_audit_log_cleaned |
Audit log entries deleted (passes count) |
Manual Execution
From the Tools Page
Admins can trigger any cron job manually from the WB Ad Manager -> Tools page. The Tools page lists all registered jobs with their schedule, next run time, and a “Run Now” button.
Programmatically
Use the Cron_Manager::run_job() method to execute a job manually:
$cron = \WBAM_Pro\Core\Cron_Manager::get_instance();
$cron->run_job( 'wbam_expire_classifieds' );
This fires wbam_before_manual_cron before execution and wbam_after_manual_cron after, both passing the hook name.
Scheduling and Unscheduling
- Activation:
Cron_Manager::activate()is called on plugin activation, which schedules all defined jobs. Daily jobs are set to run at 3:00 AM (server time); all other jobs start immediately. - Deactivation:
Cron_Manager::deactivate()unschedules all jobs to prevent orphaned cron events. - Classified Billing: The
Classified_Billingclass handles its own scheduling viaschedule_cron()/unschedule_cron()methods, called oninit.
Viewing Scheduled Status
The get_scheduled_jobs() method returns an array of all jobs with their current status:
$cron = \WBAM_Pro\Core\Cron_Manager::get_instance();
$jobs = $cron->get_scheduled_jobs();
foreach ( $jobs as $hook => $job ) {
echo $job['hook']; // e.g., 'wbam_expire_classifieds'
echo $job['schedule']; // e.g., 'hourly'
echo $job['description']; // e.g., 'Mark expired classified listings'
echo $job['scheduled']; // true or false
echo $job['next_run']; // e.g., '2026-03-04 15:00:00' or null
}
Troubleshooting
Cron jobs not running
WordPress cron is “pseudo-cron” — it runs when someone visits the site. On low-traffic sites, use a real system cron to call wp-cron.php:
# Add to crontab (every 5 minutes)
*/5 * * * * curl -s https://yoursite.com/wp-cron.php > /dev/null 2>&1
Then disable WordPress pseudo-cron in wp-config.php:
define( 'DISABLE_WP_CRON', true );
Jobs scheduled but not executing
- Check for conflicts with caching plugins that may skip
wp-cron.phpon cached pages - Use a plugin like WP Crontrol to inspect the cron schedule and verify events are registered
- Check the WordPress error log for fatal errors in cron callbacks
Classified upgrades not expiring
- Confirm the
wbam_expire_upgradescron event is scheduled (check via Tools page or WP Crontrol) - The job only expires upgrades with
status = 'active'andexpires_at < NOW()— verify the upgrade records in thewbam_classified_upgradestable
Next Steps
- Plugin Architecture
- Hooks & Filters Reference
- Tools & Demo Data
