WordPress Download Manager 7.0.1 introduces a powerful cron job system for handling background tasks like sending emails, cleaning up expired files, and processing bulk operations. This guide covers everything from basic usage to the developer API.
The cron job system consists of two main components:
Access the cron jobs settings via Downloads → Settings → Cron Jobs. The interface shows:
Cleans up expired sessions, cache files, and optionally download statistics.
CronJob::dispatch(\WPDM\__\Jobs\CleanupJob::class)
->withData([ 'cleanup_stats' => false, 'note' => 'Scheduled cleanup' ])
->onQueue('maintenance')
->create();
Moves expired packages to trash based on their expiration date.
CronJob::dispatch(\WPDM\__\Jobs\DeleteExpiredJob::class)
->withData([ 'permanent_delete' => false, 'notify_admin' => true ])
->onQueue('maintenance')
->create();
Sends emails asynchronously using wp_mail or WPDM Email templates.
CronJob::dispatch(\WPDM\__\Jobs\SendEmailJob::class)
->withData([ 'to' => 'user@example.com', 'subject' => 'Your Download is Ready', 'message' => '<h2>Hello!</h2><p>Your file is ready.</p>', 'template' => 'download-ready' ])
->onQueue('emails')
->create();
The CronJob class provides a fluent builder API for dispatching jobs.
use WPDM\__\CronJob;
// Basic dispatch
$jobId = CronJob::dispatch(MyCustomJob::class)
->withData(['param1' => 'value1'])
->create();
// Full options
$jobId = CronJob::dispatch(MyCustomJob::class)
->withData($payload) // Job data/parameters
->onQueue('my-queue') // Queue name for grouping
->priority(5) // 1-10, higher = sooner
->delay(3600) // Delay in seconds
->attempts(3) // Max retry attempts
->unique('job-key-123') // Prevent duplicates
->create();
Create a job class that extends the base Job class:
namespace MyPlugin\Jobs;
use WPDM\__\Jobs\Job;
class ProcessFileJob extends Job
{
/**
* Execute the job
*
* @param object|array $data Job payload
* @return bool Success status
*/
public function handle($data): bool
{
$fileId = $this->get('file_id');
$action = $this->get('action', 'default');
$this->log("Processing file #{$fileId}");
// Your processing logic here
$result = $this->processFile($fileId, $action);
if (!$result) {
$this->log('Processing failed', 'error');
return false;
}
$this->log('File processed successfully');
return true;
}
/**
* Handle job failure
*/
public function failed(\Throwable $e, $data): void
{
parent::failed($e, $data);
// Send admin notification, log to external service, etc.
}
public static function getName(): string
{
return 'Process File';
}
public static function getDescription(): string
{
return 'Processes uploaded files asynchronously';
}
}
// Get job counts by status
$counts = CronJob::getCounts();
// Returns: ['total' => 100, 'pending' => 5, ...]
// Get all jobs with filtering
$jobs = CronJob::getAll([
'limit' => 50,
'status' => 'pending',
'queue' => 'emails',
'orderby' => 'created_at',
'order' => 'DESC',
]);
// Job management
CronJob::retry($jobId); // Retry failed job
CronJob::cancel($jobId); // Cancel pending job
CronJob::delete($jobId); // Delete job
CronJob::cleanup(30); // Delete completed jobs older than 30 days
CronJob::releaseStale(30); // Release locks on stale jobs
// Instead of blocking the request
add_action('wpdm_after_download', function($package_id, $user_id) {
CronJob::dispatch(SendEmailJob::class)
->withData([
'to' => get_userdata($user_id)->user_email,
'subject' => 'Thank you for your download',
'message' => 'Your download of ' . get_the_title($package_id) . ' was successful.',
])
->onQueue('emails')
->create();
}, 10, 2);
// Schedule daily cleanup at midnight
add_action('wpdm_scheduled_tasks', function() {
CronJob::dispatch(CleanupJob::class)
->withData(['cleanup_stats' => false])
->onQueue('maintenance')
->unique('daily_cleanup_' . date('Y-m-d'))
->create();
});
// Process multiple files without timeout
function schedule_bulk_processing($file_ids) {
foreach ($file_ids as $index => $file_id) {
CronJob::dispatch(ProcessFileJob::class)
->withData(['file_id' => $file_id])
->onQueue('file-processing')
->delay($index * 5) // Stagger by 5 seconds
->priority(3)
->create();
}
}
If DISABLE_WP_CRON is set to true, you need to trigger job processing externally:
# Run every 5 minutes */5 * * * * curl -s "https://yoursite.com/?wpdm_cron=1&cronkey=YOUR_KEY" > /dev/null 2>&1
Copy the External Cron URL from Settings → Cron Jobs and add it to your cron service with a 5-minute interval.
Jobs are stored in the wp_ahm_cron_jobs table:
| Column | Type | Description |
|---|---|---|
| ID | bigint | Auto-increment primary key |
| code | varchar(255) | Unique job identifier |
| type | varchar(255) | Job class name |
| data | longtext | Serialized job payload |
| queue | varchar(100) | Queue name |
| priority | tinyint | 1-10 priority level |
| status | varchar(20) | pending/running/completed/failed |
| attempts | int | Current attempt count |
| max_attempts | int | Maximum retry attempts |
| execute_at | int | Unix timestamp for delayed execution |
| locked_at | int | Lock timestamp (prevents double processing) |
| created_at | datetime | Job creation time |
| updated_at | datetime | Last update time |
failed() method for error handling$this->log() for debugging and monitoringDISABLE_WP_CRON is set - you may need external cron__wpdm_process_jobs event is scheduledFor any technical issue, if you are already using pro version please post in pro forum and free version users please post in free forum. Otherwise, if you have any pre-sale or order related query please contact live chat support team. For technical support.