Handler Registration Trait
Standardized handler registration trait introduced in v0.2.2 that eliminates ~70% of boilerplate code across all handlers.
Overview
HandlerRegistrationTrait (/inc/Core/Steps/HandlerRegistrationTrait.php) provides a single registerHandler() method that automatically registers handlers with all required WordPress filters.
Architecture
- Location:
/inc/Core/Steps/HandlerRegistrationTrait.php - Purpose: Centralize handler registration logic
- Benefits:
- Reduces code duplication by ~70%
- Ensures consistent registration patterns
- Centralizes filter registration logic
- Auto-handles conditional registration
Method Signature
protected static function registerHandler(
string $handler_slug,
string $handler_type,
string $handler_class,
string $label,
string $description,
bool $requires_auth = false,
?string $auth_class = null,
?string $settings_class = null,
?callable $tools_callback = null,
?string $authProviderKey = null
): voidParameters
- Reduces code duplication by ~70%
- Ensures consistent registration patterns
- Centralizes filter registration logic
- Auto-handles conditional registration
Filters Registered
The trait automatically registers handlers with the following WordPress filters:
1. datamachine_handlers
Handler metadata registration (always registered).
add_filter('datamachine_handlers', function($handlers) {
$handlers[$handler_slug] = [
'type' => $handler_type,
'class' => $handler_class,
'label' => $label,
'description' => $description,
'requires_auth' => $requires_auth
];
return $handlers;
});2. datamachine_auth_providers
Authentication provider registration (conditional on requires_auth=true).
Auth providers are keyed by provider key, not necessarily the handler slug.
- Reduces code duplication by ~70%
- Ensures consistent registration patterns
- Centralizes filter registration logic
- Auto-handles conditional registration
// Only registered if requires_auth is true
add_filter('datamachine_auth_providers', function($providers) use ($provider_key) {
$providers[$provider_key] = new $auth_class();
return $providers;
});3. datamachine_handler_settings
Settings class registration (always registered if settings_class provided).
add_filter('datamachine_handler_settings', function($settings, $handler_slug_param) {
if ($handler_slug_param === $handler_slug) {
return $settings_class;
}
return $settings;
}, 10, 2);4. chubes_ai_tools
AI tool registration via callback (conditional on tools_callback provided).
// Only registered if tools_callback is provided
add_filter('chubes_ai_tools', $tools_callback, 10, 3);Usage Example
Basic Usage (Publish Handler)
use DataMachineCoreStepsHandlerRegistrationTrait;
class TwitterFilters {
use HandlerRegistrationTrait;
public static function register(): void {
self::registerHandler(
'twitter',
'publish',
Twitter::class,
__('Twitter', 'datamachine'),
__('Post content to Twitter with media support', 'datamachine'),
true, // Requires OAuth
TwitterAuth::class,
TwitterSettings::class,
function($tools, $handler_slug, $handler_config) {
if ($handler_slug === 'twitter') {
$tools['twitter_publish'] = datamachine_get_twitter_tool($handler_config);
}
return $tools;
}
);
}
}
// Auto-execute at file load
function datamachine_register_twitter_filters() {
TwitterFilters::register();
}
datamachine_register_twitter_filters();Fetch Handler Example
use DataMachineCoreStepsHandlerRegistrationTrait;
class RSSFilters {
use HandlerRegistrationTrait;
public static function register(): void {
self::registerHandler(
'rss',
'fetch',
RSS::class,
__('RSS Feed', 'datamachine'),
__('Fetch content from RSS/Atom feeds', 'datamachine'),
false, // No auth required
null,
RSSSettings::class,
null // No AI tools for fetch handlers
);
}
}
function datamachine_register_rss_filters() {
RSSFilters::register();
}
datamachine_register_rss_filters();Update Handler Example
use DataMachineCoreStepsHandlerRegistrationTrait;
class WordPressUpdateFilters {
use HandlerRegistrationTrait;
public static function register(): void {
self::registerHandler(
'wordpress_update',
'update',
WordPressUpdate::class,
__('WordPress Update', 'datamachine'),
__('Update existing WordPress content', 'datamachine'),
false,
null,
WordPressUpdateSettings::class,
function($tools, $handler_slug, $handler_config) {
if ($handler_slug === 'wordpress_update') {
$tools['wordpress_update'] = datamachine_get_wordpress_update_tool($handler_config);
}
return $tools;
}
);
}
}
function datamachine_register_wordpress_update_filters() {
WordPressUpdateFilters::register();
}
datamachine_register_wordpress_update_filters();Migration Guide
Custom handlers should adopt this pattern by:
*Add trait to Filters class:
phpuse DataMachineCoreStepsHandlerRegistrationTrait; class MyHandlerFilters { use HandlerRegistrationTrait; }Replace manual filter calls with single
registerHandler()call:php// Before (manual registration) add_filter('datamachine_handlers', function($handlers) { /* ... */ }); add_filter('datamachine_auth_providers', function($providers) { /* ... */ }); add_filter('datamachine_handler_settings', function($settings) { /* ... */ }); add_filter('chubes_ai_tools', function($tools) { /* ... */ }); // After (trait registration) self::registerHandler( 'my_handler', 'publish', MyHandler::class, __('My Handler', 'textdomain'), __('Handler description', 'textdomain'), true, MyHandlerAuth::class, MyHandlerSettings::class, $tools_callback );Move tool registration to callback parameter:
phpfunction($tools, $handler_slug, $handler_config) { if ($handler_slug === 'my_handler') { $tools['my_tool'] = [ 'class' => MyHandler::class, 'method' => 'handle_tool_call', 'handler' => 'my_handler', 'description' => 'Tool description', 'parameters' => [/* ... */] ]; } return $tools; }Remove redundant filter registration code from *Filters.php file.
File Organization
*Add trait to Filters class:
use DataMachineCoreStepsHandlerRegistrationTrait;
class MyHandlerFilters {
use HandlerRegistrationTrait;
}Benefits
Code Reduction
Replace manual filter calls with single registerHandler() call:
// Before (manual registration)
add_filter('datamachine_handlers', function($handlers) { /* ... */ });
add_filter('datamachine_auth_providers', function($providers) { /* ... */ });
add_filter('datamachine_handler_settings', function($settings) { /* ... */ });
add_filter('chubes_ai_tools', function($tools) { /* ... */ });
// After (trait registration)
self::registerHandler(
'my_handler',
'publish',
MyHandler::class,
__('My Handler', 'textdomain'),
__('Handler description', 'textdomain'),
true,
MyHandlerAuth::class,
MyHandlerSettings::class,
$tools_callback
);Move tool registration to callback parameter:
function($tools, $handler_slug, $handler_config) {
if ($handler_slug === 'my_handler') {
$tools['my_tool'] = [
'class' => MyHandler::class,
'method' => 'handle_tool_call',
'handler' => 'my_handler',
'description' => 'Tool description',
'parameters' => [/* ... */]
];
}
return $tools;
}Consistency
- $handler_slug: Unique identifier for the handler (e.g., ‘twitter’, ‘rss’)
- $handler_type: Handler type (‘fetch’, ‘publish’, ‘update’)
- $handler_class: Fully qualified class name for the handler
- $label: Display name for admin interface (translatable)
- $description: Handler description for admin interface (translatable)
- $requires_auth: Whether handler requires OAuth authentication
- $auth_class: Fully qualified auth class name (required if requires_auth=true)
- $settings_class: Fully qualified settings class name
- $tools_callback: Callback for AI tool registration
- $authProviderKey: Optional auth provider key override for shared authentication. When set, the handler metadata includes
auth_provider_key, and the auth provider is registered under this key.
Maintainability
- Default:
provider_key === handler_slug - Shared auth: pass
$authProviderKeytoregisterHandler()and use that as the provider key
Type Safety
- Ensures all handlers follow identical registration patterns
- Prevents missing or incorrectly configured filters
- Centralizes validation logic for handler metadata
See Also
- Single location for registration logic updates
- Easy to add new registration requirements
- Simplified debugging of handler registration issues
Related Documentation
- Method signature provides clear parameter requirements
- IDE autocomplete support for all parameters
- PHP type hints prevent registration errors