Tasks system
The tasks system in Burst Statistics surfaces actionable notices in the admin dashboard. Tasks notify site administrators about warnings, errors, plugin milestones, promotional offers, and configuration recommendations. Developers can register custom tasks using the burst_tasks filter.
Overview
Tasks are defined as PHP arrays in includes/Admin/App/config/tasks.php and merged at runtime via the burst_tasks filter. Each task has an ID, a message, an icon type, and an optional condition that controls when it appears.
Active task IDs are stored in the WordPress option burst_tasks. The admin UI reads this list and merges it with the full task definitions to determine what to display.
Task lifecycle
- Registration — Tasks are defined in the config file or added by the
burst_tasksfilter. - Activation — Tasks with
condition.type = activationare written toburst_taskson plugin activation. - Validation — A scheduled event (
burst_validate_tasks) runs every time task validation is triggered. It evaluates allserversideconditions and adds or removes task IDs fromburst_tasksaccordingly. - Display —
get_tasks()readsburst_tasks, merges active IDs with task definitions, filters out dismissed tasks, and sorts results (warnings first, then open, then other). - Dismissal — When a user dismisses a task, it is removed from
burst_tasks. If the task hasdismiss_permanently = true, its ID is also stored inburst_tasks_permanently_dismissedand will never be re-added.
Task definition fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the task. Sanitized with sanitize_title() when stored. |
msg | string | No | Translated message shown to the user. Supports HTML. |
icon | string | No | Icon type that controls the label and sort order. See Icon types. Defaults to 'open'. |
url | string | No | Link URL. Relative paths are prefixed with the Burst website URL and UTM parameters. Paths starting with # are treated as internal links. Full https:// URLs are passed through unchanged. |
condition | array | No | Controls when the task is active. See Condition types. |
dismissible | bool | No | Whether the user can dismiss the task. |
dismiss_permanently | bool | No | If true, dismissing the task stores it in burst_tasks_permanently_dismissed and it will never be shown again, even if the condition becomes true again. |
plusone | bool | No | If true, the task increments the admin-bar badge counter. |
fix | string | No | Identifier for a fix action available in the UI. Can be a WordPress option name (to toggle an option) or a Burst action name. |
Icon types
The icon field determines the badge label shown alongside the task and affects sort order.
| Icon value | Label | Sort priority |
|---|---|---|
warning | Warning | 1st (top) |
error | Error | 1st (top) |
open | Open | 2nd |
completed | Completed | 3rd |
new | New! | 3rd |
sale | Sale | 3rd |
offer | Offer | 3rd |
milestone | Milestone | 3rd |
insight | Update | 3rd |
pro | Pro | 3rd |
Tasks with icon = 'success' are given a status of 'completed'; all others receive 'open'.
If the site administrator has enabled the Dismiss non-error notices setting (dismiss_non_error_notices), only tasks with icon = 'error' will be displayed, regardless of their condition.
Condition types
The condition field is an array with a required type key.
activation
The task is added to burst_tasks once when the plugin activates. It has no server-side re-evaluation; it persists until dismissed.
'condition' => [
'type' => 'activation',
],
serverside
The task is evaluated on every task validation run. The condition resolves to a boolean via a function or constant key.
Show code
'condition' => [
'type' => 'serverside',
'function' => 'MyPlugin\MyClass::is_active()',
],
If the condition is true, the task is added. If false, the task is dismissed (unless it has dismiss_permanently).
Supported function formats:
| Format | Example | Description |
|---|---|---|
| WordPress option check | 'wp_option_burst_missing_tables' | Returns true if the option exists (is not false). Strip the wp_option_ prefix to get the option name. |
| Static method call | 'Burst\Admin\Admin::is_bf()' | Calls ClassName::methodName(). |
| Instantiated method call | '(new Burst\Admin\Milestones())->pageviews_milestone_reached()' | Instantiates the class, then calls the method. |
| Chained call | 'base()->class->method' | Calls a method on a chained object. |
| Inversion | Prefix any format with ! | Negates the result. |
Using a constant:
Show code
'condition' => [
'type' => 'serverside',
'constant' => 'MY_PLUGIN_CONSTANT',
],
Returns true if the constant is defined. Prefix with ! to invert.
clientside
The task is always included in the task list sent to the browser. The front-end JavaScript evaluates whether to display it. Client-side tasks bypass the burst_tasks option entirely — they are never filtered by has_task().
'condition' => [
'type' => 'clientside',
],
Built-in tasks
The following tasks ship with Burst Statistics v3.4.3.
| ID | Icon | Condition type | Dismissible | Permanent dismiss | plusone |
|---|---|---|---|---|---|
bf_notice | sale | serverside | Yes | Yes | Yes |
cm_notice | sale | serverside | Yes | Yes | Yes |
leave-feedback | completed | activation | Yes | No | — |
join-discord | completed | activation | Yes | No | — |
ecommerce_integration | new | — | Yes | No | No |
cron | warning | — | No | No | — |
malicious_data_removal | warning | serverside (wp_option_burst_cleanup_uid_visits) | Yes | No | — |
trial_offer_loyal_users | sale | — | Yes | No | Yes |
php_error_detected | warning | serverside (wp_option_burst_php_error_detected) | Yes | No | — |
missing_tables | warning | serverside (wp_option_burst_missing_tables) | Yes | No | — |
pageviews_milestone | milestone | serverside (Burst\Admin\Milestones::pageviews_milestone_reached()) | Yes | No | No |
live_visitors | insight | clientside | No | No | No |
multi_domain_setup_detected | warning | serverside (wp_option_burst_is_multi_domain) | Yes | Yes | No |
filters_in_url | new | — | Yes | No | No |
enable_ai_chat | new | serverside (Burst\Admin\Abilities_Api\Abilities_Api::should_show_enable_notice()) | Yes | Yes | Yes |
opt-in-sharing | new | — | Yes | No | No |
turbo_mode_recommended | warning | — | Yes | No | No |
mainwp_integration_disabled | warning | serverside (Burst\Admin\Tasks::should_show_mainwp_integration_task()) | Yes | Yes | No |
persistent_object_cache_recommended | warning | serverside (Burst\Admin\Statistics\Statistics::should_recommend_object_cache()) | Yes | Yes | No |
Tasks with no condition key have no automatic lifecycle management — they must be added and removed programmatically or they remain active once inserted into burst_tasks.
Changed in v3.4.0: The underlying detection for malicious_data_removal no longer runs directly on burst_daily. Instead, burst_daily schedules a single burst_detect_malicious_data event two minutes in the future, and that event performs the anomaly check and sets/clears the burst_cleanup_uid_visits option. The task's serverside condition (wp_option_burst_cleanup_uid_visits) is unchanged, but the option it reads may lag up to two minutes behind the burst_daily run before the next validation pass reflects it.
Added in v3.4.2: The enable_ai_chat task surfaces the Burst AI chat onboarding notice. Its serverside condition calls Burst\Admin\Abilities_Api\Abilities_Api::should_show_enable_notice(), which returns true only when wp_register_ability() is available and the enable_abilities_api option is not yet enabled. The fix value burst_option_enable_abilities_api toggles the enable_abilities_api option directly from the task UI.
Changed in v3.4.2.1: The enable_ai_chat task now includes a url pointing to the guides/ask-burst-anything-setting-up-the-ai-chat-for-your-analytics guide on the Burst website. The relative path is resolved against the Burst website URL with UTM parameters appended automatically.
Added in v3.4.2.1: The mainwp_integration_disabled task warns when the MainWP Child plugin is active but Burst's MainWP integration is still disabled. Its serverside condition calls Burst\Admin\Tasks::should_show_mainwp_integration_task(), which returns true only when mainwp-child/mainwp-child.php is installed and active (including network-active on multisite) and the enable_mainwp_integration option is empty. The fix value burst_option_enable_mainwp_integration flips the option from the task UI, and the task's url deep-links to the advanced settings tab.
Added in v3.4.2.1: The persistent_object_cache_recommended task warns when Burst detects very slow analytics queries on a site that is not yet running a persistent object cache. Its serverside condition calls Burst\Admin\Statistics\Statistics::should_recommend_object_cache(), which returns false when wp_using_ext_object_cache() reports an external cache is active, and otherwise reads MAX(max_execution_time) from the burst_query_stats table and returns true once the slowest recorded query crosses a threshold (default 10 seconds). The task uses dismiss_permanently = true, so once dismissed it will not be re-added even if slow queries persist. The threshold is filterable:
Show code
add_filter( 'burst_object_cache_recommendation_threshold_seconds', function( float $threshold ): float {
// Recommend a persistent object cache once any analytics query exceeds 5 seconds.
return 5.0;
} );
## WordPress options
| Option | Type | Description |
|--------|------|-------------|
| `burst_tasks` | array | Active task IDs. Each entry is a `sanitize_title()`-processed string. |
| `burst_tasks_permanently_dismissed` | array | Task IDs that have been permanently dismissed and will never be re-added. |
**Transient:**
| Transient | TTL | Description |
|-----------|-----|-------------|
| `burst_plusone_count` | 1 day | Cached count of active tasks that have `plusone = true`. Cleared on task validation and dismissal. |
---
## Cron events
| Hook | Schedule | Description |
|------|----------|-------------|
| `burst_validate_tasks` | Single event (30s) | Scheduled by `schedule_task_validation()`. Evaluates all `serverside` conditions and syncs `burst_tasks`. |
| `burst_detect_malicious_data` | Single event (2 min) | Added in v3.4.0. Scheduled from `burst_daily`. Runs the anomaly check that sets the `burst_cleanup_uid_visits` option feeding the `malicious_data_removal` task. |
---
## Hooks and filters
## burst_tasks
Filters the full array of task definitions before they are used anywhere. Use this filter to add, remove, or modify tasks.
**Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `$tasks` | array | Indexed array of task definition arrays as described in [Task definition fields](#task-definition-fields). |
**Example — adding a custom task:**
```php
add_filter( 'burst_tasks', function( array $tasks ): array {
$tasks[] = [
'id' => 'my_custom_task',
'msg' => __( 'Your custom notice message.', 'my-plugin' ),
'icon' => 'warning',
'dismissible' => true,
'condition' => [
'type' => 'serverside',
'function' => 'MyPlugin\Tasks::is_condition_met()',
],
];
return $tasks;
} );
Example — adding a task with a WordPress option condition:
Show code
add_filter( 'burst_tasks', function( array $tasks ): array {
$tasks[] = [
'id' => 'my_option_task',
'msg' => __( 'Something requires your attention.', 'my-plugin' ),
'icon' => 'warning',
'dismissible' => true,
'condition' => [
'type' => 'serverside',
// Active when get_option('my_plugin_error') !== false.
'function' => 'wp_option_my_plugin_error',
],
];
return $tasks;
} );
Example — removing a built-in task:
add_filter( 'burst_tasks', function( array $tasks ): array {
return array_filter( $tasks, fn( $t ) => $t['id'] !== 'ecommerce_integration' );
} );
burst_dismiss_task
Fires when a task is dismissed by the user, before it is removed from burst_tasks.
Parameters:
| Parameter | Type | Description |
|---|---|---|
$task_id | string | The ID of the task being dismissed. |
Example:
Show code
add_action( 'burst_dismiss_task', function( string $task_id ): void {
if ( $task_id === 'my_custom_task' ) {
// Run cleanup when user dismisses your task.
delete_option( 'my_plugin_error' );
}
} );
Developer API
The Tasks class (Burst\Admin\Tasks) is accessible via burst()->tasks.
get_raw_tasks(): array
Returns the complete task definitions array after applying the burst_tasks filter and resolving URLs. Does not filter by active status.
get_tasks(): array
Returns the filtered, sorted list of tasks for display. Removes tasks not in burst_tasks (except clientside tasks), applies the dismiss_non_error_notices setting, deduplicates by ID, and sorts warnings to the top.
add_task( string $task_id ): void
Inserts a task ID into burst_tasks. Has no effect if the task is permanently dismissed.
burst()->tasks->add_task( 'my_custom_task' );
dismiss_task( string $task_id ): void
Removes a task ID from burst_tasks and fires burst_dismiss_task. If the task has dismiss_permanently = true, also adds it to burst_tasks_permanently_dismissed. Clears the burst_plusone_count transient.
burst()->tasks->dismiss_task( 'my_custom_task' );
has_task( string $task_id ): bool
Returns true if the task ID is currently in burst_tasks.
if ( burst()->tasks->has_task( 'my_custom_task' ) ) {
// Task is active.
}
get_task_by_id( string $task_id ): ?array
Returns the task definition array for a given ID, or null if not found.
$task = burst()->tasks->get_task_by_id( 'cron' );
schedule_task_validation(): void
Schedules a single burst_validate_tasks cron event 30 seconds from now, if one is not already scheduled. Always use this instead of calling validate_tasks() directly.
burst()->tasks->schedule_task_validation();
add_initial_tasks(): void
Inserts all activation-type tasks into burst_tasks. Called automatically on plugin activation.
undismiss_task( string $task_id ): bool
Removes a task ID from burst_tasks_permanently_dismissed, allowing it to be re-added by a future validation run. Returns true if the task was found and removed.
burst()->tasks->undismiss_task( 'my_custom_task' );
plusone_count(): int
Returns the number of currently active tasks with plusone = true and icon !== 'success'. Result is cached in the burst_plusone_count transient for one day. Returns 0 if the current user cannot manage Burst.
Complete custom task example
Show code
/**
* Register a custom Burst task that warns when a specific option is set.
*/
add_filter( 'burst_tasks', function( array $tasks ): array {
$tasks[] = [
'id' => 'my_plugin_api_warning',
'msg' => __( 'My Plugin: API key is missing. Please configure it in the settings.', 'my-plugin' ),
'icon' => 'warning',
'url' => admin_url( 'options-general.php?page=my-plugin' ),
'dismissible' => true,
'plusone' => true,
'condition' => [
'type' => 'serverside',
// Active when get_option('my_plugin_api_missing') is not false.
'function' => 'wp_option_my_plugin_api_missing',
],
];
return $tasks;
} );
// Set the option to trigger the task, then schedule validation.
add_action( 'init', function(): void {
if ( get_option( 'my_plugin_api_key' ) === false ) {
update_option( 'my_plugin_api_missing', true );
if ( function_exists( 'burst' ) ) {
burst()->tasks->schedule_task_validation();
}
}
} );
// Clean up when the task is dismissed.
add_action( 'burst_dismiss_task', function( string $task_id ): void {
if ( $task_id === 'my_plugin_api_warning' ) {
delete_option( 'my_plugin_api_missing' );
}
} );