rwsite / wp-queue
Background job processing and WP-Cron management for WordPress
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:wordpress-plugin
pkg:composer/rwsite/wp-queue
Requires
- php: >=8.3
Requires (Dev)
- brain/monkey: ^2.6
- laravel/pint: ^1.18
- mockery/mockery: ^1.6
- pestphp/pest: ^3.0
- yoast/phpunit-polyfills: ^3.0
README
WP Queue
Laravel Horizon-like queue manager for WordPress
Simple, powerful, and modern background job processing.
Features • Installation • Quick Start • Admin UI • REST API • Testing • RU version
Features
- 🚀 Laravel-style API — Clean, fluent job dispatching with PHP 8 attributes
- 📦 Multiple Drivers — Database, Redis, Memcached, Sync (auto-detection)
- 🔄 Auto Retries — Exponential backoff for failed jobs
- ⏰ Scheduling — Cron-like job scheduling
- 👁️ WP-Cron Monitor — View, run, pause, resume, edit cron events
- 📊 Dashboard — Beautiful admin UI with statistics
- 🔌 REST API — Full API for integrations
- 💻 WP-CLI — Complete command-line interface
- 🌍 i18n Ready — Translations included (Russian)
Requirements
- PHP 8.3+
- WordPress 6.0+
Installation
- Clone or download to
wp-content/plugins/wp-queue - Run
composer install - Activate the plugin
Quick Start
Create a Job
use WPQueue\Jobs\Job; use WPQueue\Attributes\{Schedule, Queue, Timeout, Retries}; #[Schedule('hourly')] #[Queue('imports')] #[Timeout(120)] #[Retries(5)] class ImportProductsJob extends Job { public function __construct( private array $productIds ) { parent::__construct(); } public function handle(): void { foreach ($this->productIds as $id) { // Import logic here } } public function failed(\Throwable $e): void { // Handle failure error_log('Import failed: ' . $e->getMessage()); } }
Dispatch Jobs
use WPQueue\WPQueue; // Dispatch to queue WPQueue::dispatch(new ImportProductsJob([1, 2, 3])); // With delay (seconds) WPQueue::dispatch(new ImportProductsJob($ids))->delay(60); // To specific queue WPQueue::dispatch(new ImportProductsJob($ids))->onQueue('high-priority'); // Synchronous (bypass queue) WPQueue::dispatchSync(new ImportProductsJob($ids)); // Chain jobs WPQueue::chain([ new FetchProductsJob(), new ImportProductsJob($ids), new NotifyAdminJob(), ])->dispatch(); // Batch jobs WPQueue::batch([ new ImportProductJob($id1), new ImportProductJob($id2), new ImportProductJob($id3), ])->dispatch();
Schedule Jobs
// In your plugin add_action('wp_queue_schedule', function ($scheduler) { // Using attributes (automatic) $scheduler->job(ImportProductsJob::class); // Manual scheduling $scheduler->job(CleanupJob::class)->daily(); // Custom interval $scheduler->job(CheckStopListJob::class)->everyMinutes(15); // Conditional $scheduler->job(SyncJob::class) ->hourly() ->when(fn() => get_option('sync_enabled')); // From settings $scheduler->job(BackupJob::class) ->interval(get_option('backup_interval', 'daily')); // One-time execution (at specific timestamp) $scheduler->job(OneTimeJob::class)->at(time() + 3600); });
PHP 8 Attributes
#[Schedule]
#[Schedule('hourly')] // Fixed interval #[Schedule('daily', setting: 'my_opt')] // From wp_options
Available intervals: min, 5min, 10min, 15min, 30min, hourly, 2hourly, 3hourly, 6hourly, 8hourly, 12hourly, daily, twicedaily, weekly
#[Queue]
#[Queue('default')] // Queue name #[Queue('high')] // Priority queue
#[Timeout]
#[Timeout(60)] // 60 seconds #[Timeout(300)] // 5 minutes
#[Retries]
#[Retries(3)] // Max 3 attempts #[Retries(5)] // Max 5 attempts
#[UniqueJob]
#[UniqueJob] // Prevent duplicate jobs #[UniqueJob(key: 'custom_key')]
Events (Hooks)
// Before job execution add_action('wp_queue_job_processing', function($event) { // $event->job, $event->queue }); // After successful execution add_action('wp_queue_job_processed', function($event) { // $event->job, $event->queue }); // On failure add_action('wp_queue_job_failed', function($event) { // $event->job, $event->queue, $event->exception }); // On retry add_action('wp_queue_job_retrying', function($event) { // $event->job, $event->queue, $event->attempt, $event->exception });
Queue Management
use WPQueue\WPQueue; // Check status WPQueue::isProcessing('default'); // bool WPQueue::isPaused('default'); // bool WPQueue::queueSize('default'); // int // Control WPQueue::pause('default'); WPQueue::resume('default'); WPQueue::cancel('default'); // Clear + pause WPQueue::clear('default'); // Remove all jobs // Logs WPQueue::logs()->recent(100); WPQueue::logs()->failed(); WPQueue::logs()->forJob(ImportProductsJob::class); WPQueue::logs()->metrics(); WPQueue::logs()->clearOld(7); // Clear logs older than 7 days
Admin UI
Access via WP Admin → WP Queue
Tabs
| Tab | Description |
|---|---|
| Dashboard | Stats (pending, running, completed, failed), queue management |
| Scheduled Jobs | WP Queue jobs with "Run Now" button |
| Logs | Execution history with filtering |
| WP-Cron | All WordPress cron events monitoring |
| System | Environment status and health check |
WP-Cron Monitor
View and manage all WordPress cron events:
- Filter by source (WordPress, WooCommerce, Plugins, WP Queue)
- See overdue events
- Run events manually
- Delete scheduled events
- View registered schedules
System Status
Health check and environment info:
- PHP/WordPress versions
- Memory limit and usage
- WP-Cron status (disabled/alternate)
- Loopback request check
- Action Scheduler stats (if installed)
- Timezone and time info
REST API
GET /wp-json/wp-queue/v1/queues POST /wp-json/wp-queue/v1/queues/{queue}/pause POST /wp-json/wp-queue/v1/queues/{queue}/resume POST /wp-json/wp-queue/v1/queues/{queue}/clear POST /wp-json/wp-queue/v1/jobs/{job}/run GET /wp-json/wp-queue/v1/logs POST /wp-json/wp-queue/v1/logs/clear GET /wp-json/wp-queue/v1/metrics # Cron & System GET /wp-json/wp-queue/v1/cron POST /wp-json/wp-queue/v1/cron/run POST /wp-json/wp-queue/v1/cron/delete GET /wp-json/wp-queue/v1/system
Queue Drivers
WP Queue supports multiple storage backends:
| Driver | Description | Requirements |
|---|---|---|
database |
Uses wp_options table (default) | None |
redis |
Redis server | phpredis extension |
memcached |
Memcached server | memcached extension |
sync |
Synchronous execution | None |
auto |
Auto-detect best available | None |
Configuration
Add to wp-config.php:
// Select queue driver define('WP_QUEUE_DRIVER', 'redis'); // or 'memcached', 'database', 'sync', 'auto' // Redis settings (compatible with redis-cache plugin) define('WP_REDIS_HOST', 'redis'); // or '127.0.0.1' define('WP_REDIS_PORT', '6379'); define('WP_REDIS_PREFIX', 'mysite_'); // optional define('WP_REDIS_PASSWORD', 'secret'); // optional define('WP_REDIS_DATABASE', 0); // optional, 0-15 // Memcached settings define('WP_MEMCACHED_HOST', '127.0.0.1'); define('WP_MEMCACHED_PORT', 11211);
Programmatic Configuration
use WPQueue\WPQueue; use WPQueue\Contracts\QueueInterface; // Set driver programmatically WPQueue::manager()->setDefaultDriver('redis'); // Check available drivers $drivers = WPQueue::manager()->getAvailableDrivers(); // ['database' => ['available' => true, 'info' => '...'], ...] // Check if specific driver is available if (WPQueue::manager()->isDriverAvailable('redis')) { WPQueue::manager()->setDefaultDriver('redis'); } // Register custom driver WPQueue::manager()->extend('sqs', function() { return new SqsQueue(['region' => 'us-east-1']); });
Redis with redis-cache Plugin
If you use Redis Object Cache plugin, WP Queue will automatically use the same Redis connection settings. No additional configuration needed!
// These constants from redis-cache are automatically used: // WP_REDIS_HOST, WP_REDIS_PORT, WP_REDIS_PASSWORD, WP_REDIS_DATABASE // WP_REDIS_PREFIX, WP_REDIS_SCHEME, WP_REDIS_PATH, WP_REDIS_TIMEOUT
Migration from Action Scheduler
Before (Action Scheduler)
as_schedule_recurring_action(time(), HOUR_IN_SECONDS, 'my_hourly_task'); add_action('my_hourly_task', function() { // task code });
After (WP Queue)
#[Schedule('hourly')] class MyHourlyTask extends Job { public function handle(): void { // task code } } // Register add_action('wp_queue_schedule', fn($s) => $s->job(MyHourlyTask::class));
Comparison with Action Scheduler
| Feature | Action Scheduler | WP Queue |
|---|---|---|
| Database | 2 custom tables | wp_options |
| API | 20+ functions | 1 facade |
| PHP version | 7.4+ | 8.3+ |
| Registration | Manual | Attributes |
| Retry logic | Complex | #[Retries(3)] |
| UI | Built-in | Built-in |
| File count | 50+ | ~15 |
Testing
WP Queue uses a CI-first testing approach with comprehensive test coverage.
Unit Tests (Local)
Fast isolated tests without WordPress environment:
composer test:unit
Results: 69 tests, 130 assertions ✅
E2E Tests (GitHub Actions)
Integration tests with real WordPress run automatically in CI:
- ✅ WordPress latest (6.7+) + PHP 8.3
- ✅ WordPress 6.7 + PHP 8.3
E2E tests run on every push to main/develop branches and in pull requests.
Code Quality
# Code style check composer lint # Run all tests composer test
Note: Code coverage requires PCOV or Xdebug extension. In Docker environments, use:
docker exec wp_site-php composer lint docker exec wp_site-php composer test:unit
See: tests/README.md
Example Plugin
See a complete working example: wp-queue-example-plugin
The example plugin demonstrates:
- ✅ Creating custom jobs with PHP 8 attributes
- ✅ Job scheduling with different intervals
- ✅ Error handling and retries
- ✅ Chain and batch processing
- ✅ Queue management and monitoring
- ✅ REST API integration
- ✅ WP-CLI commands
Perfect for learning how to integrate WP Queue into your WordPress plugins!
License
GPL-2.0-or-later