Skip to main content

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

  1. Registration — Tasks are defined in the config file or added by the burst_tasks filter.
  2. Activation — Tasks with condition.type = activation are written to burst_tasks on plugin activation.
  3. Validation — A scheduled event (burst_validate_tasks) runs every time task validation is triggered. It evaluates all serverside conditions and adds or removes task IDs from burst_tasks accordingly.
  4. Displayget_tasks() reads burst_tasks, merges active IDs with task definitions, filters out dismissed tasks, and sorts results (warnings first, then open, then other).
  5. Dismissal — When a user dismisses a task, it is removed from burst_tasks. If the task has dismiss_permanently = true, its ID is also stored in burst_tasks_permanently_dismissed and will never be re-added.

Task definition fields

FieldTypeRequiredDescription
idstringYesUnique identifier for the task. Sanitized with sanitize_title() when stored.
msgstringNoTranslated message shown to the user. Supports HTML.
iconstringNoIcon type that controls the label and sort order. See Icon types. Defaults to 'open'.
urlstringNoLink 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.
conditionarrayNoControls when the task is active. See Condition types.
dismissibleboolNoWhether the user can dismiss the task.
dismiss_permanentlyboolNoIf 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.
plusoneboolNoIf true, the task increments the admin-bar badge counter.
fixstringNoIdentifier 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 valueLabelSort priority
warningWarning1st (top)
errorError1st (top)
openOpen2nd
completedCompleted3rd
newNew!3rd
saleSale3rd
offerOffer3rd
milestoneMilestone3rd
insightUpdate3rd
proPro3rd

Tasks with icon = 'success' are given a status of 'completed'; all others receive 'open'.

caution

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:

FormatExampleDescription
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.
InversionPrefix 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.

IDIconCondition typeDismissiblePermanent dismissplusone
bf_noticesaleserversideYesYesYes
cm_noticesaleserversideYesYesYes
leave-feedbackcompletedactivationYesNo
join-discordcompletedactivationYesNo
ecommerce_integrationnewYesNoNo
search_console_integrationnewYesNoYes
cronwarningNoNo
malicious_data_removalwarningserverside (wp_option_burst_cleanup_uid_visits)YesNo
php_error_detectedwarningserverside (wp_option_burst_php_error_detected)YesNo
missing_tableswarningserverside (wp_option_burst_missing_tables)YesNo
pageviews_milestonemilestoneserverside (Burst\Admin\Milestones::pageviews_milestone_reached())YesNoNo
live_visitorsinsightclientsideNoNoNo
multi_domain_setup_detectedwarningserverside (wp_option_burst_is_multi_domain)YesYesNo
filters_in_urlnewYesNoNo
external_links_trackingnewYesNoNo
enable_ai_chatnewserverside (Burst\Admin\Abilities_Api\Abilities_Api::should_show_enable_notice())YesYesYes
opt-in-sharingnewYesNoNo
turbo_mode_recommendedwarningYesNoNo
mainwp_integration_disabledwarningserverside (Burst\Admin\Tasks::should_show_mainwp_integration_task())YesYesYes
persistent_object_cache_recommendedwarningserverside (Burst\Admin\Statistics\Statistics::should_recommend_object_cache())YesYesNo
wp_consent_api_noticewarningserverside (Burst\Admin\Tasks::is_wp_consent_api_active())YesYesYes
burst_geo_ip_import_errorwarningserverside (wp_option_burst_geo_ip_import_error)YesNoYes

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.

The external_links_tracking task notifies administrators that external link click tracking is available and points them to Settings > General to manage it. It has no condition key, so it is not added by add_initial_tasks(); instead it is inserted programmatically with add_task( 'external_links_tracking' ) when the plugin is upgraded. Once inserted it stays active until dismissed.

The search_console_integration task notifies administrators that they can connect Google Search Console to Burst and see which search queries bring visitors to their site, directly in the dashboard. It has no condition key, so it is not added by add_initial_tasks(); instead it is inserted programmatically with add_task( 'search_console_integration' ) when the plugin is upgraded. Its url is the internal hash link #/settings/integrations, and it increments the admin-bar badge counter (plusone). Once inserted it stays active until dismissed.

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.

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.

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.

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, the task increments the admin-bar badge counter (plusone), and its url points to the guides/manage-burst-statistics-across-all-your-sites-with-mainwp guide on the Burst website. The relative path is resolved against the Burst website URL with UTM parameters appended automatically.

Pro - AgencyAvailable in the Agency tier

The MainWP integration is an Agency-tier feature. See MainWP integration.

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;
} );

The wp_consent_api_notice task warns that a configured cookie banner may suppress tracking. Its serverside condition calls Burst\Admin\Tasks::is_wp_consent_api_active(), which returns true when the WP_Consent_API class exists or when Complianz is active (CMPLZ_VERSION or cmplz_version defined). When statistics consent is required by such a banner, Burst will not track any visitor the banner has not flagged as having consented. The task's url deep-links to the wp-consent-api-integration guide.

The burst_geo_ip_import_error task warns that the GeoIP database could not be downloaded, which is required for tracking country information. It is registered on the burst_tasks filter by Burst\Admin\Geo_Ip\Geo_Ip::add_burst_geo_ip_import_error(), which appends the actual error message from the failed import (read from the burst_geo_ip_import_error option) to the message. Its serverside condition (wp_option_burst_geo_ip_import_error) is true only while that option is set. The task is suppressed while the burst_recently_activated transient is present, so a freshly activated site that may still be downloading does not show the notice prematurely. The task's url points to the instructions/geo-ip-error/ guide.

The enable_ai_chat task surfaces the Burst AI chat onboarding notice.

WordPress options

OptionTypeDescription
burst_tasksarrayActive task IDs. Each entry is a sanitize_title()-processed string.
burst_tasks_permanently_dismissedarrayTask IDs that have been permanently dismissed and will never be re-added.

Transient:

TransientTTLDescription
burst_plusone_count1 dayCached count of active tasks that have plusone = true. Cleared whenever a task is added, on task validation and on dismissal.

Cron events

HookScheduleDescription
burst_validate_tasksSingle event (30s)Scheduled by schedule_task_validation(). Evaluates all serverside conditions and syncs burst_tasks.
burst_detect_malicious_dataSingle event (2 min)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:

ParameterTypeDescription
$tasksarrayIndexed array of task definition arrays as described in Task definition fields.

Example — adding a custom task:

Show code
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:

ParameterTypeDescription
$task_idstringThe 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 and clears the burst_plusone_count transient so the badge counter is recalculated on the next read. 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.

Returns true when the WP Consent API or Complianz is active — that is, when the WP_Consent_API class exists or the CMPLZ_VERSION or cmplz_version constant is defined. Used as the serverside condition for the wp_consent_api_notice task.

if ( Burst\Admin\Tasks::is_wp_consent_api_active() ) {
// A consent integration is present.
}

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' );
}
} );