0 Day Analytics – Crons Module Developer Documentation

Table of Contents

1. Overview & Architecture

The Crons Module provides a complete management interface for WordPress cron events. It extends the built-in WordPress cron system with a WP_List_Table-based UI that allows administrators to view, search, filter, execute, edit, delete, and create cron events from the WordPress admin.

Key Capabilities

  • List all registered WordPress cron events with search, pagination, and sorting
  • Filter by event type (WordPress core vs plugin crons)
  • Filter by originating plugin (identifies which plugin registered each cron)
  • Filter by site (multisite networks)
  • Instantly execute any cron event via AJAX or REST API
  • Edit cron hook name, next run date/time, arguments, and schedule
  • Add new cron events with custom hooks, schedules, and arguments
  • Delete individual or bulk cron events
  • Test the WP-Cron spawn mechanism
  • Globally enable/disable WordPress cron (modifies wp-config.php)
  • CLI support via WP-CLI commands

Technology Stack

  • PHP 7.4+ (strict types)
  • WordPress WP_List_Table API
  • WordPress wp-api-fetch for REST interactions
  • Vanilla JavaScript for AJAX operations
  • WP_Config_Transformer for wp-config.php modifications

2. File Map

advanced-analytics/
├── classes/
│   └── vendor/
│       ├── helpers/
│       │   ├── class-crons-helper.php     — Core cron manipulation service
│       │   ├── class-cron-jobs.php        — Plugin's own cron jobs definitions
│       │   └── class-ajax-helper.php       — AJAX endpoints (delete, run)
│       ├── lists/
│       │   ├── class-crons-list.php       — WP_List_Table for cron display
│       │   └── views/
│       │       └── class-crons-view.php   — Page rendering & form handlers
│       ├── controllers/
│       │   └── api/
│       │       └── class-endpoints.php     — REST API registration
│       ├── settings/
│       │   └── settings-options/
│       │       └── cron-list.php          — Settings form fields
│       └── checks/
│           └── speed/
│               └── class-cron-jobs-check.php — Performance audit
├── assets/
│   ├── css/                                — Stylesheets
│   └── js/                                 — JavaScript files
└── cli-commands.php                        — WP-CLI integration

3. Admin Screens

3.1 Cron Jobs List

URL wp-admin/admin.php?page=advan_cron_jobs
Menu Position Sub-menu under “Error Logs” (position 2)
Capability manage_options (or read if menu_admins_only is disabled)
Controller Crons_View::analytics_cron_page()
List Table Crons_List (extends WP_List_Table)

UI Components

  • “Add New Cron” button in page header
  • Cron spawn status notice – shows whether WP-Cron can be spawned
  • Filter views – All | WordPress Core | Plugin-registered (via views())
  • Plugin/Site filter dropdowns – post-based filter forms
  • Search box – searches hook names (input name: sgp)
  • Sortable columns – Hook, Next Run, Interval
  • Pagination – configurable via screen options
  • Row actions – Edit | Run | Delete (per row)
  • Bulk actions – Delete | Run (for selected rows)
Screen layout:
┌─────────────────────────────────────────────────────────┐
│  Cron Jobs                              [Add New Cron]  │
│─────────────────────────────────────────────────────────│
│  ⚠ Cron spawn status notice (if applicable)             │
│─────────────────────────────────────────────────────────│
│  All (42) | WordPress (15) | Plugin (27)                │
│  [Plugin ▼] [Site ▼]                     [🔍 Search]    │
│─────────────────────────────────────────────────────────│
│  ☐ Hook ↕     | Site | Next Run ↕ | Interval | Args     │
│  ☐ wp_cron_ev | —    | 10 min     | hourly   | []       │
│     Edit | Run | Delete                                 │
│  ☐ my_hook    | —    | 2 hrs      | daily    | [1]      │
│     Edit | Run | Delete                                 │
│─────────────────────────────────────────────────────────│
│  Bulk Actions [▼] [Apply]          ‹ 1 of 3 ›           │
└─────────────────────────────────────────────────────────┘

3.2 Edit Cron

URL wp-admin/admin.php?page=advan_cron_jobs&action=edit_cron&hash={hash}&_wpnonce={nonce}
Form Action admin_post_advan_crons_update
Handler Crons_View::update_cron()
Nonce advana_crons_manager

Form Fields

Field Type Name Description
Hook text name The WordPress action hook name
Next Run Date date cron_next_run_custom_date Local date (yyyy-mm-dd)
Next Run Time time cron_next_run_custom_time Local time (hh:mm:ss)
Arguments textarea cron_args JSON-encoded array, e.g. [25]
Schedule select schedule Dropdown of WP schedules + “Once”
Hash hidden hash The cron event hash (8 char md5)
Note: If the cron event has already executed or expired before the edit page loads, a notice is displayed and the form is not shown.

3.3 Add New Cron

URL wp-admin/admin.php?page=advan_cron_jobs&action=new_cron&_wpnonce={nonce}
Form Action admin_post_advan_crons_new
Handler Crons_View::new_cron()
Nonce advana_crons_manager

Same form fields as Edit, except the hook name is empty by default and arguments field name is value instead of cron_args. The next run defaults to the current date/time.

3.4 Module Settings

URL wp-admin/admin.php?page=advan_logs_settings#aadvana-options-tab-cron-list
Settings File classes/vendor/settings/settings-options/cron-list.php

Available Settings

Setting ID Type Description
Enable cron module cron_module_enabled checkbox Enables/disables the plugin’s cron management module. This only controls the plugin’s UI, not WordPress crons themselves.
Global WP Cron disabled wp_cron_disable checkbox Sets/unsets DISABLE_WP_CRON in wp-config.php. Only available when wp-config.php is writable. Uses WP_Config_Transformer.
Warning: If wp-config.php is not writable, the “Global WP Cron disabled” option will show an error message and cannot be changed from the UI.

4. Core Classes

4.1 ADVAN\Helpers\Crons_Helper

Main service class for all cron event operations. All methods are public static.

Constants

PHP
<?php
public const TRANSIENT_NAME = 'advana_cron_test_ok';

public const WP_CORE_CRONS = array(
    'recovery_mode_clean_expired_keys',
    'wp_delete_temp_updater_backups',
    'wp_privacy_delete_old_export_files',
    'wp_update_user_counts',
    'wp_version_check',
    'wp_update_plugins',
    'wp_update_themes',
    'wp_scheduled_delete',
    'delete_expired_transients',
    // ... 20+ WordPress core hook names
);

Schedule Management

Method Return Description
schedule_event($hook, $recurrence, $first_run, $args) void Schedule a new cron event
unschedule_event($hook, $args) void Remove a scheduled event
is_scheduled($hook, $args) bool Check if an event is scheduled

Execution

Method Return Description
run_event($event) bool Execute a cron event by event array
execute_event($hash) bool Execute a cron event by its hash
delete_event($hash) bool|WP_Error Delete a cron event by hash

Data Retrieval

Method Return Description
get_events() array All cron events for current site
get_events_for_site(int $blog_id) array Cron events for a specific site (multisite)
get_event($hash) array|bool Single event by hash, or false
get_cron_callbacks($name) array Callbacks attached to a hook name

Utilities

Method Return Description
update_cron($hash) void|WP_Error Update cron from POST data
add_cron() void|WP_Error Add new cron from POST data
test_cron_spawn($cache) bool|WP_Error Test if WP-Cron can be spawned
schedule_drop_down($current) void Render schedule <select> dropdown
run_cron_api($request) WP_Error|WP_REST_Response REST API callback to execute cron

Example: Schedule a Custom Cron Event

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

// Schedule a daily cron event starting in 1 hour
Crons_Helper::schedule_event(
    'my_custom_daily_task',   // hook name
    'daily',                  // recurrence
    time() + 3600,            // first run timestamp
    array( 'arg1', 42 )      // arguments
);

// Check if scheduled
if ( Crons_Helper::is_scheduled( 'my_custom_daily_task' ) ) {
    // It is scheduled!
}

// Unschedule
Crons_Helper::unschedule_event( 'my_custom_daily_task' );

4.2 ADVAN\Lists\Crons_List

Extends WP_List_Table (via an Abstract_List intermediary). Handles the cron jobs admin list table rendering, column management, sorting, searching, and bulk operations.

Constants

PHP
<?php
const CRON_MENU_SLUG   = 'advan_cron_jobs';
const PAGE_SLUG        = '0-day_page_advan_cron_jobs';
const UPDATE_ACTION    = 'advan_crons_update';
const NEW_ACTION       = 'advan_crons_new';
const NONCE_NAME       = 'advana_crons_manager';
const SEARCH_INPUT     = 'sgp';
const PLUGIN_FILTER_ACTION = self::PAGE_SLUG . '_filter_plugin';
const SITE_FILTER_ACTION   = self::PAGE_SLUG . '_filter_site';

Key Methods

Method Description
menu_add() Registers the admin submenu page
hooks_init() Initializes WordPress hooks (screen options, columns)
process_actions_load() Processes bulk actions on load-{page}
prepare_items() Populates the table with data
fetch_table_data($args) Retrieves and filters cron events array
get_cron_items($no_filter) Static method to get all cron items
get_bulk_actions() Returns available bulk actions
handle_table_actions() Executes selected bulk action
manage_columns($columns) Defines visible columns
format_column_value($item, $column) Formats cell value for display

4.3 ADVAN\Lists\Views\Crons_View

Handles page rendering for all cron screens (list, edit, add) and processes form submissions.

Key Methods

Method Description
analytics_cron_page() Main page router – renders list, edit, or add form based on $_REQUEST['action']
update_cron() Handles edit form submission via admin_post
new_cron() Handles add form submission via admin_post
plugin_filter_action() Processes plugin filter dropdown selection
site_filter_action() Processes site filter dropdown selection (multisite)
add_help_content_crons() Returns help tab content string

4.4 ADVAN\Helpers\Cron_Jobs

Defines and manages the plugin’s own internal cron jobs. These are the crons that the Advanced Analytics plugin itself uses for background tasks.

PHP
<?php
// Hook to register custom cron jobs
\add_action( 'after_setup_theme', [ Cron_Jobs::class, 'initialize_hooks' ], 30000 );

// Use the filter to add plugin-specific cron jobs
\add_filter( 'advan_cron_hooks', function( $hooks ) {
    $hooks[] = array(
        'hook'       => 'my_plugin_cleanup',
        'recurrence' => 'daily',
        'callback'   => 'my_cleanup_function',
    );
    return $hooks;
});

5. Data Model & Event Structure

Each cron event is represented as an associative array with the following keys:

PHP
<?php
$event = array(
    'hash'         => 'a1b2c3d4',           // md5 hash (first 8 chars)
    'hook'         => 'my_custom_hook',     // WordPress action hook name
    'schedule'     => 1711360000,           // Unix timestamp (next run, UTC)
    'recurrence'   => 'daily',              // Schedule name or empty for one-time
    'args'         => array( 1, 'arg2' ),  // Arguments passed to the hook
    'site_id'      => 1,                    // Blog ID (multisite)
    'site_name'    => 'My Site',            // Blog name (multisite)
    'plugin_slug'  => 'my-plugin',          // Originating plugin (backward compat)
    'plugin_slugs' => array( 'my-plugin' ), // Array of plugins (new format)
);

Hash Calculation

The hash is used as a unique identifier for each cron event. It is computed as:

PHP
<?php
$hash = substr(
    md5(
        $hook .
        $recurrence .
        $schedule .
        wp_json_encode( $args )
    ),
    0,
    8
);

The hash changes when the hook name, schedule, timestamp, or arguments change. This means editing a cron event may generate a different hash.

6. AJAX Handlers

AJAX endpoints are registered in Ajax_Helper and require admin capabilities and nonce verification.

Delete Cron AJAX

Action wp_ajax_aadvana_delete_cron
Handler Ajax_Helper::delete_cron()
Nonce bulk-custom-delete (via _wpnonce POST param)
Parameters hash (string) – cron event hash
Success { "success": true, "data": 2 }
Error { "success": false, "data": "error message" }

JavaScript Example

JavaScript
const formData = new FormData();
formData.append('action', 'aadvana_delete_cron');
formData.append('hash', 'a1b2c3d4');
formData.append('_wpnonce', wpNonce);

fetch(ajaxurl, {
    method: 'POST',
    body: formData,
})
.then(r => r.json())
.then(data => {
    if (data.success) {
        console.log('Cron deleted');
    }
});

Run Cron AJAX

Action wp_ajax_aadvana_run_cron
Handler Ajax_Helper::run_cron()
Nonce bulk-custom-delete (via _wpnonce POST param)
Parameters hash (string) – cron event hash
Success { "success": true }
Note: Running a cron via AJAX sets define('DOING_CRON', true) before execution to emulate the native cron environment.

7. REST API Endpoints

Run Cron Event GET

Endpoint /wp-json/0-day/v1/cron_run/{cron_hash}/
Method GET (WP_REST_Server::READABLE)
Permission manage_options capability
Parameter cron_hash (required, string) – the 8-character event hash

Success Response

JSON
{
    "success": true
}

Error Response

JSON
{
    "code": "cron_execute",
    "message": "Can not execute, cron not found...",
    "data": {
        "status": 400
    }
}

cURL Example

HASH
curl -X GET \
  "https://example.com/wp-json/0-day/v1/cron_run/a1b2c3d4/" \
  -H "X-WP-Nonce: <nonce>" \
  --cookie "wordpress_logged_in_xxx=..."

JavaScript (wp-api-fetch) Example

JavaScript
wp.apiFetch({
    path: '/0-day/v1/cron_run/a1b2c3d4/',
}).then(response => {
    if (response.success) {
        console.log('Cron executed successfully');
    }
}).catch(err => {
    console.error('Cron execution failed:', err.message);
});

8. Hooks & Filters

Filters FILTER

Filter Parameters Description
advan_cron_hooks array $hooks Allows plugins to register their own cron job definitions. Return modified array.
cron_schedules array $schedules WordPress core filter to add custom schedules (e.g. “every_5_minutes”).
cron_request array $request, string $doing_wp_cron WordPress core filter to modify the cron spawn request.

Actions ACTION

Action When Description
load-{page_slug} Admin page load Fires when the cron list page loads – used to process bulk actions early.
admin_post_advan_crons_update Edit form submit Handles the cron edit form POST.
admin_post_advan_crons_new Add form submit Handles the new cron form POST.
admin_post_{PAGE_SLUG}_filter_plugin Plugin filter submit Processes plugin filter dropdown form.
admin_post_{PAGE_SLUG}_filter_site Site filter submit Processes site filter dropdown form (multisite).
after_setup_theme (priority 30000) Theme setup Plugin registers its own internal cron hooks.

Example: Add a Custom Cron Schedule

PHP
<?php
\add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['every_five_minutes'] = array(
        'interval' => 300,
        'display'  => __( 'Every 5 Minutes' ),
    );
    return $schedules;
});

// This new schedule will automatically appear in the
// schedule dropdown on Edit/Add Cron screens.

Example: Register Plugin Cron Jobs

PHP
<?php
\add_filter( 'advan_cron_hooks', function( $hooks ) {
    $hooks[] = array(
        'hook'       => 'my_plugin_daily_cleanup',
        'recurrence' => 'daily',
        'callback'   => 'my_cleanup_callback',
    );
    return $hooks;
});

function my_cleanup_callback() {
    // Your daily cleanup logic here
}

9. Settings Reference

Settings are rendered using the plugin’s Settings::build_option() builder. The cron settings are on the Cron Options tab within the main settings page.

PHP
<?php
// Check if cron module is enabled
$enabled = Settings::get_option( 'cron_module_enabled' );

// Check if WP Cron is disabled globally
$wp_cron_disabled = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON;

Settings Builder Usage

PHP
<?php
// How the settings are defined in cron-list.php
Settings::build_option(
    array(
        'title' => esc_html__( 'Cron Options', '0-day-analytics' ),
        'id'    => 'options-settings-tab',
        'type'  => 'tab-title',
    )
);

Settings::build_option(
    array(
        'name'    => esc_html__( 'Enable cron module', '0-day-analytics' ),
        'id'      => 'cron_module_enabled',
        'type'    => 'checkbox',
        'hint'    => esc_html__( 'Disables plugin cron module only.', '0-day-analytics' ),
        'default' => Settings::get_option( 'cron_module_enabled' ),
    )
);

10. List Table Columns & Sorting

Columns

Key Header Sortable Description
cb No Bulk selection checkbox
hook Hook Yes ↑ Cron hook name. WP core crons show a yellow WordPress icon.
site Site No Blog ID + name (multisite only)
schedule Next Run Yes ↑ (default) Next execution timestamp with timezone offset
recurrence Interval Yes ↑ Schedule name (hourly, daily, twicedaily) or “Once”
args Args No JSON-encoded arguments array
actions Actions No Callback info with error highlighting for missing callbacks

The search box filters by hook name. The query parameter is sgp (Search Global Parameter).

Filter Views

Three filter tabs appear above the table:

  • All – all registered cron events
  • WordPress – events matching WP_CORE_CRONS list
  • Plugin – events NOT in the WP core list

11. Bulk & Row Actions

Row Actions (per cron event)

Action Method Description
Edit Page redirect Opens the Edit Cron form with the event’s data pre-filled
Run AJAX (aadvana_run_cron) Executes the cron event immediately. Sets DOING_CRON constant.
Delete AJAX (aadvana_delete_cron) Removes the cron event from the WP cron schedule

Bulk Actions

Action Description
Delete Delete all selected cron events
Run Execute all selected cron events

Processing Flow

  1. Bulk actions are detected in handle_table_actions()
  2. Called from process_actions_load() on the load-{page_slug} hook
  3. Nonce verification: bulk-generated-crons (auto-generated by WP_List_Table)
  4. Capability check: manage_options required

12. Code Examples

Example 1: Test Cron Spawn Programmatically

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

// Test whether WP-Cron can be spawned (cached by default)
$status = Crons_Helper::test_cron_spawn();

if ( is_wp_error( $status ) ) {
    error_log( 'WP-Cron spawn failed: ' . $status->get_error_message() );
} else {
    error_log( 'WP-Cron spawn is working correctly.' );
}

Example 2: Get All Cron Events and Filter by Plugin

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

$all_events = Crons_Helper::get_events();

// Filter to only events from 'woocommerce' plugin
$woo_events = array_filter( $all_events, function( $event ) {
    return isset( $event['plugin_slugs'] )
        && in_array( 'woocommerce', $event['plugin_slugs'], true );
});

foreach ( $woo_events as $event ) {
    printf(
        "Hook: %s | Next: %s | Interval: %s\n",
        $event['hook'],
        date( 'Y-m-d H:i:s', $event['schedule'] ),
        $event['recurrence'] ?: 'once'
    );
}

Example 3: Execute a Cron Event via REST API (PHP)

PHP
<?php
// Programmatic REST API call within WordPress
$request = new \WP_REST_Request( 'GET', '/0-day/v1/cron_run/a1b2c3d4/' );
$response = rest_do_request( $request );

if ( $response->is_error() ) {
    $error = $response->as_error();
    error_log( 'Cron execution failed: ' . $error->get_error_message() );
} else {
    $data = $response->get_data();
    error_log( 'Cron executed: ' . print_r( $data, true ) );
}

Example 4: Check if a Custom Hook Exists

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

if ( Crons_Helper::is_scheduled( 'my_plugin_sync_task' ) ) {
    // Already scheduled – skip registration
    return;
}

// Schedule it now
Crons_Helper::schedule_event(
    'my_plugin_sync_task',
    'hourly'
);

Example 5: Multisite – Get Cron Events for a Specific Site

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

// Get crons for blog ID 3
$site_events = Crons_Helper::get_events_for_site( 3 );

echo count( $site_events ) . ' cron events on site #3';

Example 6: Delete a Cron by Hash

PHP
<?php
use ADVAN\Helpers\Crons_Helper;

$result = Crons_Helper::delete_event( 'a1b2c3d4' );

if ( is_wp_error( $result ) ) {
    error_log( 'Failed to delete: ' . $result->get_error_message() );
} elseif ( $result ) {
    error_log( 'Cron deleted successfully' );
} else {
    error_log( 'Cron not found' );
}
Need User Guide documentation?
See Crons Module User Guide for more details about configuration, practical usage and information.
← Crons Module — User Guide Hardening WordPress Beyond Plugins: OS-Level & Server-Level Techniques →
Share this page
Back to top