These hooks tell your code when HappenBoard and HappenBoard Pro can be used, and when they are being deleted. Use them to start a companion plugin at the right moment and to remove its data along with HappenBoard’s. Three Pro filters also change how Pro reaches its store for licences and updates. If you are new to the reference, start with Extending HappenBoard with hooks.
Load order on each request
- WordPress loads the main file of every active plugin. Your
add_action( 'happenboard_loaded', ... )line runs here. - On
plugins_loaded, HappenBoard attaches the hooks of all its services, then fireshappenboard_loaded. - HappenBoard Pro answers that action at priority 10. If the free plugin is version 0.2.0 or newer, Pro attaches its own services, then fires
happenboard_pro_loaded. - On
init, HappenBoard registers its post types, taxonomies and blocks. Both plugins add new capabilities at priority 1 and update their tables at priority 2.
So inside happenboard_loaded you can use HappenBoard’s classes and filters, but its content types do not exist yet.
Uninstalling needs a constant
Deleting HappenBoard from the Plugins screen keeps all its data unless wp-config.php contains define( 'HAPPENBOARD_UNINSTALL', true );. HappenBoard Pro has its own constant, HAPPENBOARD_PRO_UNINSTALL. Each uninstall action fires only when its constant is set. Each plugin also removes only its own data: Pro’s options, its tables and the meta it keeps on WooCommerce products and orders wait for Pro’s own uninstall. The guide GDPR, personal data and uninstalling explains this to site owners.
Pro licence and updates
HappenBoard Pro activates its licence and gets its updates from the HappenBoard store (see Installing HappenBoard Pro). Its licence client and updater start on plugins_loaded on their own, outside happenboard_loaded. That way a site whose free plugin is missing or too old still receives the Pro update that fixes it. Add the three store filters from your plugin’s main file, not from a happenboard_pro_loaded callback, which does not run in that case.
happenboard_loaded
Fires at the end of HappenBoard’s boot, on plugins_loaded, once every service of the free plugin has attached its hooks. Start a companion plugin here: your code then runs only when HappenBoard is active.
Signature
do_action( 'happenboard_loaded' )
Example
// my-happenboard-addon.php, the main file of your own plugin.
add_action(
'happenboard_loaded',
function (): void {
// HappenBoard is active: its classes and filters can be used.
add_filter( 'happenboard_schema_event', 'my_addon_schema', 10, 2 );
// Post types and blocks are registered later, on init.
add_action( 'init', 'my_addon_register_meta' );
}
);
Notes
- Use it instead of
plugins_loaded. Your callback never runs when HappenBoard is inactive, so you need noclass_exists()check. To test elsewhere, in a theme for example, usedid_action( 'happenboard_loaded' ). - It fires before
init. HappenBoard’s post types, taxonomies, meta fields and blocks are registered oninit, and its REST routes onrest_api_init. Defer that kind of work to aninitcallback. - HappenBoard Pro boots from this action at priority 10. Use a higher priority, or
happenboard_pro_loaded, to run after Pro’s services. - A theme’s
functions.phploads after this action has fired, so hooking it from a theme does nothing. In a theme, add your filters directly.
happenboard_pro_loaded
Fires at the end of HappenBoard Pro’s boot, once every Pro service has attached its hooks. Use it for add-ons that extend Pro features.
Signature
do_action( 'happenboard_pro_loaded' )
Example
add_action(
'happenboard_pro_loaded',
function (): void {
// HappenBoard and HappenBoard Pro are both active and booted.
add_filter( 'happenboard_pro_wc_pay_later_methods', 'my_addon_pay_later', 10, 2 );
// Pro adds its capabilities and tables on init (priorities 1 and 2):
// read its tables from priority 3 on.
add_action( 'init', 'my_addon_load_ticket_stats', 5 );
}
);
Notes
- It runs inside
happenboard_loaded, so also duringplugins_loadedand beforeinit. It never fires when the free plugin is inactive. - It does not fire when the installed HappenBoard is older than 0.2.0: Pro then stays off and says why in an admin notice.
HAPPENBOARD_PRO_VERSIONis defined even then, so test this action, not the constant, to know Pro is running. - Pro adds new capabilities on
initpriority 1 and creates or updates its tables on priority 2. Read Pro’s tables from priority 3 on. - Every filter Pro adds during its boot is already attached. Hooking the same filter here at priority 10 runs your callback after Pro’s.
happenboard_pro_store_url
Filters the address of the store HappenBoard Pro uses for its licence and updates. Licence and update calls go to {store}/?wc-api=wc-am-api, and the lookup of a key’s product to {store}/wp-json/license/v1/find.
Signature
apply_filters( 'happenboard_pro_store_url', string $store )
Parameters
-
$storestring - The
HAPPENBOARD_PRO_STORE_URLconstant when it is defined, otherwisehttps://happenboard.com/.
Return value
string
The store URL. Only an absolute https URL is used, with a trailing slash added. Any other value, an empty string included, switches licensing and updates off.
Example
add_filter(
'happenboard_pro_store_url',
function ( $store ) {
// The staging site talks to the staging store.
if ( 'staging' === wp_get_environment_type() ) {
return 'https://staging-store.example.com/';
}
return $store;
}
);
Notes
- For a fixed address, define
HAPPENBOARD_PRO_STORE_URLinwp-config.phpinstead. No code is needed. - A value that is not https switches the licence off rather than raising an error. Every licence action then fails with a message saying the licence server address is not a valid https URL, and no update is offered.
- The licence key travels in these requests, sent with
wp_safe_remote_post(). A store on a local or private address is refused unless you also allow it with core’shttp_request_host_is_externalfilter. - Update packages must come from the store’s host or one of its subdomains. If your store serves downloads from another host, add it with
happenboard_pro_update_package_hosts.
happenboard_pro_licence_request_args
Filters the arguments of each request HappenBoard Pro sends to its store, just before wp_safe_remote_post() runs. It covers licence calls, update checks and the product lookup.
Signature
apply_filters( 'happenboard_pro_licence_request_args', array $args, string $action, string $url )
Parameters
-
$argsarray<string,mixed> timeout15,redirection2, aHappenBoard-Pro/{version}user agent and anAccept: application/jsonheader. The product lookup also has abody.-
$actionstring findfor the product lookup, otherwise the store action:activate,deactivate,status,updateorplugininformation.-
$urlstring - The request URL. Except for
find, it carries the licence key and the site’s instance ID in its query string.
Return value
array<string,mixed>
The request arguments. A value that is not an array is replaced with an empty array, which drops the timeout and the headers.
Example
add_filter(
'happenboard_pro_licence_request_args',
function ( $args, $action, $url ) {
// Behind a slow outgoing proxy: give the store more time.
$args['timeout'] = 30;
return $args;
},
10,
3
);
Notes
- Three arguments:
add_filter( ..., 10, 3 ). - Never log
$urlas it is: itsapi_keyparameter is the licence key. Thefindrequest sends the key in its body instead. wp_safe_remote_post()always setsreject_unsafe_urls, so turning it off here has no effect.- Requests go out only when someone clicks Activate, Deactivate on this site or Check now under HappenBoard → Settings → Licence. The daily licence check and WordPress update checks also send them, once a key is active.
happenboard_pro_update_package_hosts
Filters the hosts allowed to serve HappenBoard Pro update packages. WordPress receives the package URL the store names only if it uses https, has no user name, password or port, and sits on one of these hosts or a subdomain.
Signature
apply_filters( 'happenboard_pro_update_package_hosts', array $hosts, string $url )
Parameters
-
$hostsarray<int,string> - The store’s host (
happenboard.comby default), or an empty array when the store is switched off. -
$urlstring - The package URL being checked.
Return value
array<int,string>
The allowed hosts. Each one also allows its subdomains, compared without regard to case. A value that is not an array allows nothing.
Example
add_filter(
'happenboard_pro_update_package_hosts',
function ( $hosts, $url ) {
// The store serves its downloads from a CDN.
$hosts[] = 'downloads.example-cdn.com';
return $hosts;
},
10,
2
);
Notes
- Two arguments:
add_filter( ..., 10, 2 )to receive$url. - A package on any other host, or over plain http, makes Pro reject the whole answer and offer no update. The failure is cached for an hour, a good answer for 12 hours. After adding a host, click Check again under Dashboard → Updates: Pro then asks the store again.
- It runs only while a licence is active on the site, and never on a source checkout whose version is still the
{VERSION}placeholder. - WordPress downloads and installs Pro from every host you add. Add only hosts your store really serves packages from.
happenboard_uninstall
Fires when WordPress deletes the free HappenBoard plugin with HAPPENBOARD_UNINSTALL set, once per site, before HappenBoard removes any of its own data. Hook it to delete your add-on’s options, tables, scheduled events and capabilities in the same pass.
Signature
do_action( 'happenboard_uninstall' )
Example
// In your plugin's main file, outside any HappenBoard hook.
add_action(
'happenboard_uninstall',
function (): void {
global $wpdb;
// HappenBoard has deleted nothing yet: its events are still readable.
delete_option( 'my_addon_settings' );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}my_addon_log" );
wp_clear_scheduled_hook( 'my_addon_cron' );
foreach ( wp_roles()->role_objects as $role ) {
$role->remove_cap( 'my_addon_manage' );
}
}
);
Notes
- Nothing happens without the opt-in. Unless
define( 'HAPPENBOARD_UNINSTALL', true );is inwp-config.php, the uninstaller stops at once, this action never fires and every event, attendee and setting stays. - Add it from your plugin’s main file, not from a
happenboard_loadedcallback. HappenBoard is inactive when WordPress runs itsuninstall.php, sohappenboard_loadeddoes not fire in that request. Your plugin must still be active. - After your callback, HappenBoard deletes its posts, terms, transients, five tables, scheduled events, capabilities and user meta, and every option whose name starts with
happenboard_orwidget_happenboard_. HappenBoard Pro’shappenboard_pro_options and transients stay. Give your own options another prefix, or they go too. - On multisite it fires once for each site of the network, inside
switch_to_blog(), so$wpdb->prefixalready points at that site.
happenboard_pro_uninstall
Fires when WordPress deletes HappenBoard Pro with HAPPENBOARD_PRO_UNINSTALL set, once per site, before Pro removes any of its own data. Pro add-ons hook it to clean up in the same pass.
Signature
do_action( 'happenboard_pro_uninstall' )
Example
// In your add-on's main file, outside any HappenBoard hook.
add_action(
'happenboard_pro_uninstall',
function (): void {
global $wpdb;
// Runs once per site on multisite, with $wpdb->prefix set for that site.
delete_option( 'my_addon_ticket_report' );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}my_addon_sales" );
foreach ( wp_roles()->role_objects as $role ) {
$role->remove_cap( 'my_addon_view_sales' );
}
}
);
Notes
- It needs Pro’s own opt-in,
define( 'HAPPENBOARD_PRO_UNINSTALL', true );inwp-config.php. Without it, the action never fires and no Pro data is removed, apart from the ticket PDFs older versions left inuploads/happenboard-tickets/, which are always deleted. - Add it from your plugin’s main file, not from a
happenboard_pro_loadedcallback: Pro is inactive in the uninstall request, so that action does not fire. - After your callback, Pro deletes every option and transient whose name starts with
happenboard_pro_, its Stripe webhook transients, thirteen tables, six capabilities, scheduled events and post meta. It also sets its WooCommerce ticket products back to draft, and deletes the licence once, after the loop over sites. - On multisite it fires once per site, with
$wpdbpointed at that site. It never touches the free plugin’s data, whichhappenboard_uninstallcovers.
Next steps
- GDPR, personal data and uninstalling: what deleting each plugin removes, from the site owner’s side.
- Installing HappenBoard Pro: the licence the store filters talk to.
- Admin, roles and capability hooks: choose which roles get the capabilities installed on
init.