Admin, roles and capability hooks

Available in:Free

These hooks change the HappenBoard admin and who may use it. They cover the screens in its menu, the start-up data of its admin app, the capabilities each role receives, and the per-visitor limit on public booking lookups. Reach for them when you add a screen for your own add-on, set up a custom role, or tune a busy booking page. The Roles and permissions guide explains each capability in plain words, and Extending HappenBoard with hooks covers the basics of the reference.

How capabilities are granted

HappenBoard checks its own capabilities, such as happenboard_manage_events or happenboard_view_attendees, rather than WordPress roles. The free plugin and HappenBoard Pro each add theirs to the Administrator and Editor roles when they install them. Two details matter when you change them in code:

  • The role filters below run only when the capabilities are installed: at activation, or once after an update that adds new ones. They change what is written then, not what roles have today.
  • HappenBoard’s REST routes and admin menu also let any user with manage_options through. Removing a HappenBoard capability from administrators does not lock them out.

Pro roles and permissions lists the six capabilities HappenBoard Pro adds.

happenboard_admin_submenus

Filter Free src/Admin/Menu.php

Filters the list of HappenBoard admin screens. The same list builds the submenu under HappenBoard in the WordPress menu and the sidebar of the HappenBoard admin app.

Signature

apply_filters( 'happenboard_admin_submenus', array $default )

Parameters

$default array<int,array{path:string,label:string,capability:string,parent:string,external?:bool}>
The eleven built-in rows, from Dashboard to Settings. Each has path (the app route, / for the dashboard), label (already translated), capability, and parent: empty for a top-level item, or the path of the row it sits under, such as /bookings.

Return value

array<int,array{path:string,label:string,capability:string,parent:string,external?:bool}> The rows, in menu order.

Example

add_filter(
    'happenboard_admin_submenus',
    function ( $submenus ) {
        // Append: returning a new array would drop the built-in screens
        // and the ones HappenBoard Pro adds.
        $submenus[] = array(
            'path'       => 'options-general.php?page=my-addon',
            'label'      => __( 'My add-on', 'my-addon' ),
            'capability' => 'manage_options',
            'parent'     => '',
            'external'   => true, // A classic admin page, not an app route.
        );

        return $submenus;
    },
    20
);

Notes

  • Append to the array you receive. HappenBoard Pro adds Orders, after Organizers, and Resources, under Bookings, at priority 10. Returning a new array removes them along with the built-in screens.
  • Each row needs path, label and capability. The menu and the app sidebar show a row to users with its capability, and to every user with manage_options. The sidebar leaves out rows with an empty capability.
  • A new app route such as /reports only adds a link: the app shows its not-found screen unless your script fills window.happenBoard.screens['/reports'] before the app bundle runs. Pro enqueues its screens on admin_enqueue_scripts at priority 5 for that reason.
  • The label is printed as given, so translate it yourself with __(). The filter runs on admin_menu and again when the app’s start-up data is built: keep the callback free of side effects.

happenboard_screen_context

Filter Free src/Admin/ScreenContext.php

Filters the start-up data of the HappenBoard admin app, printed in the page as window.happenBoardVars. Add your own keys, or change built-in ones.

Signature

apply_filters( 'happenboard_screen_context', array $context )

Parameters

$context array<string,mixed>
The data: pluginVersion, nonce (a wp_rest nonce), restBase, wpRestBase, siteUrl, siteName, adminEmail, adminUrl, pluginUrl, nav, currentUser, locale, timezone, dateFormat, timeFormat, startOfWeek, integrations, onboarded, general, colorPresets and languages.

Return value

array<string,mixed> The data, passed to wp_localize_script().

Example

add_filter(
    'happenboard_screen_context',
    function ( $context ) {
        // Your own settings, nested so booleans stay booleans in JavaScript.
        $context['myAddon'] = array(
            'enabled'  => true,
            'endpoint' => rest_url( 'my-addon/v1/' ),
        );

        return $context;
    },
    20
);

Notes

  • It runs only on HappenBoard admin screens, whose screen ID contains happenboard. The block editor gets a separate, unfiltered object with the same happenBoardVars name.
  • Add to the array, do not replace it. HappenBoard Pro adds a pro key at priority 10, and without it the app hides Pro features such as attendee import. The free plugin does not set pro: read it with $context['pro'] ?? null.
  • wp_localize_script() turns top-level scalar values into strings, so true reaches JavaScript as "1". Nest your values in an array to keep real booleans and numbers.
  • Every user who can open a HappenBoard screen gets this data in the page source. Never add secrets such as API keys or licence keys.

happenboard_capabilities_role_defaults

Filter Free src/Capabilities/Capabilities.php

Filters which WordPress roles receive which HappenBoard capabilities. It runs only when HappenBoard installs its capabilities, not on every request.

Signature

apply_filters( 'happenboard_capabilities_role_defaults', array $mapping )

Parameters

$mapping array<string,array<int,string>>
Role slug to capability list. administrator gets eleven capabilities, all except happenboard_host. editor gets eight: the same without happenboard_export_attendees, happenboard_manage_settings and happenboard_manage_integrations. happenboard_host is meant for individual users, never a role.

Return value

array<string,array<int,string>> The mapping. Each capability is added with WP_Role::add_cap(), and roles that do not exist are skipped.

Example

// In an mu-plugin or your plugin's main file, so it is in place before init.
add_filter(
    'happenboard_capabilities_role_defaults',
    function ( $mapping ) {
        // Let WooCommerce shop managers see attendees and bookings.
        $mapping['shop_manager'] = array(
            'happenboard_view_attendees',
            'happenboard_view_bookings',
        );

        return $mapping;
    }
);
// Then deactivate and reactivate HappenBoard once to apply it.

Notes

  • It runs when HappenBoard is activated, when a site is added to a network where it is network-active, and once after an update that adds capabilities. That last check reads the happenboard_caps_version option on init priority 1.
  • Changing the mapping later grants nothing by itself: deactivate and reactivate HappenBoard to apply it. Register the callback before init priority 1, for example in your plugin’s main file.
  • It only adds. Removing a capability from the mapping does not take it away from a role that has it: call WP_Role::remove_cap() yourself.
  • Uninstalling HappenBoard removes its own twelve capabilities from every role and user, but not other capabilities you add through this filter.

happenboard_pro_capabilities_role_defaults

Filter Pro src/Capabilities/Capabilities.php

Filters which WordPress roles receive HappenBoard Pro’s six capabilities. It runs only when Pro installs its capabilities.

Signature

apply_filters( 'happenboard_pro_capabilities_role_defaults', array $mapping )

Parameters

$mapping array<string,array<int,string>>
administrator gets all six: happenboard_manage_tickets, happenboard_view_orders, happenboard_export_orders, happenboard_refund_orders, happenboard_run_checkin and happenboard_manage_resources. editor gets four, without export and refund.

Return value

array<string,array<int,string>> The mapping, written with WP_Role::add_cap(). Roles that do not exist are skipped.

Example

add_filter(
    'happenboard_pro_capabilities_role_defaults',
    function ( $mapping ) {
        // WooCommerce shop managers handle ticket orders and refunds.
        $mapping['shop_manager'] = array(
            'happenboard_view_orders',
            'happenboard_export_orders',
            'happenboard_refund_orders',
        );

        return $mapping;
    }
);
// Then deactivate and reactivate HappenBoard Pro once to apply it.

Notes

  • It runs at the same moments as the free filter. Those are Pro’s activation, a site added to a network where Pro is network-active, and an update that adds capabilities, detected through the happenboard_pro_caps_version option on init priority 1.
  • It only adds, and an edit applies only after Pro is deactivated and reactivated.
  • happenboard_manage_integrations belongs to the free plugin, even though Pro’s integration screens use it. Grant it with happenboard_capabilities_role_defaults.
  • Uninstalling Pro with HAPPENBOARD_PRO_UNINSTALL set removes its six capabilities from every role and user, not other capabilities you add here.

happenboard_me_capabilities

Filter Free src/REST/Me.php

Filters the capability map returned by GET /happenboard/v1/me/capabilities. The admin app and headless front ends read it to decide which buttons to show.

Signature

apply_filters( 'happenboard_me_capabilities', array $caps, WP_User $user )

Parameters

$caps array<string,bool>
Eight free capabilities, each set to the check its REST routes run, fallback included: manage events, venues and organizers, view, manage and export attendees, manage settings and integrations. Venues and organizers fall back to edit_posts, the others to manage_options. The booking capabilities and happenboard_host are not included.
$user WP_User
The current user. Always logged in: the route refuses anonymous requests.

Return value

array<string,bool> The map, sent as the capabilities key of the response.

Example

add_filter(
    'happenboard_me_capabilities',
    function ( $caps, $user ) {
        // A custom front end also needs the booking capabilities.
        $extra = array( 'happenboard_view_bookings', 'happenboard_manage_booking_types', 'happenboard_host' );

        foreach ( $extra as $cap ) {
            $caps[ $cap ] = user_can( $user, $cap );
        }

        return $caps;
    },
    10,
    2
);

Notes

  • Two arguments: add_filter( ..., 10, 2 ).
  • It only reports. Setting a value to true shows a button, but the REST route behind it still checks the real capability and refuses the request.
  • HappenBoard Pro adds its six capabilities at priority 10, with the same manage_options fallback its routes accept. Append to the array: returning a new one drops the free and Pro entries.
  • Any logged-in user, a Subscriber included, can call this route. Keep the values booleans and add nothing you would not show to every account.

happenboard_throttle_public_reads

Filter Free src/Service/Security/ReadThrottle.php

Filters whether HappenBoard counts the public booking lookups per visitor address and refuses more than 60 a minute. The lookups are the list of free times and the price quote of a booking type.

Signature

apply_filters( 'happenboard_throttle_public_reads', bool $counts )

Parameters

$counts bool
true when the site uses a persistent object cache such as Redis or Memcached (wp_using_ext_object_cache()), false otherwise.

Return value

bool true to count and limit the lookups, false to let them all through.

Example

add_filter(
    'happenboard_throttle_public_reads',
    function ( $counts ) {
        // No Redis or Memcached here, but a bot keeps scraping the booking
        // page: count the lookups anyway.
        return true;
    }
);

Notes

  • Three routes are counted. GET /happenboard/v1/booking-types/{id}/slots and the reschedule list GET /happenboard/v1/bookings/{token}/slots share one count, and GET /happenboard/v1/booking-types/{id}/quote has its own. Past 60 in a clock minute, the address gets an HTTP 429 answer.
  • Without a persistent object cache, each counter is a transient: two rows in the options table per address and minute, left for WordPress’s daily cleanup. That cost is why counting is off by default there.
  • The address is REMOTE_ADDR, passed through happenboard_booking_client_ip. Behind a proxy or a CDN, filter it to the real visitor address, or every visitor shares one count.
  • It does not affect RSVP and booking submissions, which keep their own limits, nor the HappenBoard Pro booking search.

Next steps