Scheduled Tasks (Cron Jobs)

Get Started

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_Billing class handles its own scheduling via schedule_cron() / unschedule_cron() methods, called on init.

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.php on 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_upgrades cron event is scheduled (check via Tools page or WP Crontrol)
  • The job only expires upgrades with status = 'active' and expires_at < NOW() — verify the upgrade records in the wbam_classified_upgrades table

Next Steps

Last updated: March 4, 2026