Developers¶
The plugin is plain PHP 8.1 with vanilla JavaScript; there is no build step. Classes live in the CFBE\ namespace and are autoloaded from includes/, admin/, public/ and modules/.
| Page | Contents |
|---|---|
| Hooks | Every filter and action, with parameters |
| Shortcodes and block | [cfbe_form], [cfbe_promo], [cfbe_thankyou], [cfbe_preferences] and the cfbe/signup-form block |
| Email template data | Handlebars variables passed to your bluefox emails |
| REST API | The cfbe/v1 endpoints |
| WP-CLI | wp cfbe commands |
Bootstrap¶
CFBE\Plugin::boot() runs on plugins_loaded. It creates the core services, then the modules that are switched on, then fires two actions:
cfbe_init– after the core services exist.CFBE\Plugin::instance()then gives yousettings(),repository(),logger(),jobs(),subscription(),rewards()andclient()(the bluefox API client,nullwhile the connection is not configured).cfbe_register_modules– after the built-in modules are registered. Add-ons hook in here.
The module system¶
Every optional feature is a module with a switch on the General tab. The switches are stored together in the option cfbe_modules (slug => bool).
CFBE\Modules::FLAGS defines the built-in modules as slug => [ needs WooCommerce, default, group ]:
| Slug | Needs | Default | Group |
|---|---|---|---|
forms |
– | on | – |
checkout |
WooCommerce | off | – |
coupon |
WooCommerce | off | – |
sync |
– | off | – |
mailer |
– | off | – |
order_emails |
WooCommerce | off | woo_events |
abandoned_cart |
WooCommerce | off | woo_events |
integration_cf7 |
Contact Form 7 | off | integrations |
integration_wpforms |
WPForms | off | integrations |
integration_fluentforms |
Fluent Forms | off | integrations |
integration_gravityforms |
Gravity Forms | off | integrations |
integration_elementor |
Elementor Pro | off | integrations |
preferences |
– | on | – |
webhooks |
– | on | – |
abilities |
WordPress 6.9 (wp_register_ability) |
off | – |
Third-party requirements are listed in Modules::REQUIRES (any one of a constant, class or function is enough).
Switches in one group load the same code module. Plugin::FEATURE_MODULES maps a slug or group to the entry class in modules/<slug>/:
| Slug / group | Entry class |
|---|---|
sync |
CFBE\Sync\Module |
mailer |
CFBE\Mailer\Module |
woo_events |
CFBE\Woo_Events\Module |
integrations |
CFBE\Integrations\Module |
webhooks |
CFBE\Webhooks\Module |
An entry class takes the Plugin instance in its constructor and hooks itself (frontend, jobs, admin tab) in register(). It is only instantiated when its switch, or any switch of its group, is on. The other modules (forms, checkout, coupon, preferences, abilities) are wired directly in Plugin.
Checking a module¶
use CFBE\Modules;
if ( Modules::enabled( 'coupon' ) ) {
// Switched on and WooCommerce is active.
}
Modules::group_enabled( 'woo_events' ); // Any switch of the group is on.
Modules::available( 'integration_cf7' ); // Its dependencies are active, whatever the switch.
Modules::states(); // All switches, stored values merged over the defaults.
Modules::enabled() is true only when the switch is on and the module is available. A switch whose dependency is missing keeps its stored value and comes back when the dependency returns.
Filter cfbe_modules to change labels, descriptions or defaults of the module definitions.
Settings areas¶
Settings are stored as one array option per area, cfbe_{area}. The built-in areas are api, form, popup, checkout, coupon and emails. Modules add their own:
| Area | Option | Added by |
|---|---|---|
sync |
cfbe_sync |
Contact sync |
mailer |
cfbe_mailer |
Email delivery |
woo_events |
cfbe_woo_events |
Order and abandoned cart emails |
integrations |
cfbe_integrations |
Form plugin integrations |
webhooks |
cfbe_webhooks |
Inbound webhooks |
A module registers an area with three filters:
add_filter( 'cfbe_settings_areas', function ( array $areas ) {
$areas[] = 'my_area';
return $areas;
} );
add_filter( 'cfbe_settings_defaults_my_area', function ( array $defaults ) {
return $defaults + array( 'enabled' => false, 'label' => 'Hello' );
} );
add_filter( 'cfbe_sanitize_settings_my_area', function ( array $clean, array $input, array $previous ) {
$clean['label'] = sanitize_text_field( $input['label'] ?? '' );
return $clean;
}, 10, 3 );
The defaults define the allowed keys: anything not in the defaults is dropped after sanitizing. Without a sanitizer, values are cleaned by the type of their default (bool, int, string).
Read settings with CFBE\Settings::get( 'popup' ) (all values merged over the defaults) or Settings::get( 'popup', 'scroll_percent' ) (one value). See the Settings reference for every key.
Adding a settings tab¶
Tabs are registered with the cfbe_settings_tabs filter:
add_filter( 'cfbe_settings_tabs', function ( array $tabs ) {
$tabs['my_tab'] = array(
'label' => __( 'My tab', 'my-plugin' ),
'render' => 'my_render_callback',
'position' => 80, // General is 10, Subscribers 100, Logs 110.
);
return $tabs;
} );
Logging and background jobs¶
- The plugin logs to the Logs tab (and to the WooCommerce logger with source
cfbewhen WooCommerce is active). Email addresses are masked anywhere inside log context values, also inside bluefox error messages. - Background work runs through Action Scheduler when it is available (WooCommerce bundles it) and WP-Cron otherwise. See Troubleshooting.