Skip to content

WordPress Actions ​

Flowguard provides action hooks that allow developers to execute custom code at specific points during flow execution.

Overview ​

Actions are WordPress hooks that let you run custom functions when certain events occur. Flowguard fires actions before and after flow execution, enabling you to:

  • Log execution events
  • Send notifications
  • Trigger external systems
  • Update custom data
  • Integrate with other plugins

Available Actions ​

flowguard_before_flow_run ​

Fires immediately before a flow begins execution.

Hook Name: flowguard_before_flow_run

Parameters:

ParameterTypeDescription
$flow_idintThe flow post ID
$flow_dataarrayComplete flow data being executed

Flow Data Structure:

php
$flow_data = [
    'id'       => 123,                // Flow post ID
    'title'    => 'Login Test Flow',  // Flow title
    'steps'    => [...],              // Array of step objects
    'settings' => [                   // Flow settings
        'timeout'    => 30000,
        'retries'    => 0,
        'screenshot' => true,
    ],
    'siteUrl'  => 'https://yoursite.com',
];

Example Usage:

php
/**
 * Log flow execution start
 */
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    error_log(sprintf(
        'Flowguard: Starting flow #%d "%s" with %d steps',
        $flow_id,
        $flow_data['title'],
        count($flow_data['steps'])
    ));
}, 10, 2);

Use Cases:

  1. Logging:
php
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    // Log to custom table
    global $wpdb;
    $wpdb->insert('flow_execution_log', [
        'flow_id'    => $flow_id,
        'started_at' => current_time('mysql'),
        'status'     => 'started',
    ]);
}, 10, 2);
  1. Notifications:
php
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    // Send Slack notification
    wp_remote_post('https://hooks.slack.com/services/YOUR/WEBHOOK/URL', [
        'body' => json_encode([
            'text' => "Flow '{$flow_data['title']}' started execution",
        ]),
    ]);
}, 10, 2);
  1. Prepare Environment:
php
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    // Clear caches before testing
    wp_cache_flush();
    
    // Set up test data
    if (strpos($flow_data['title'], 'Cart Test') !== false) {
        // Ensure cart is empty
        WC()->cart->empty_cart();
    }
}, 10, 2);
  1. Integration with Other Plugins:
php
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    // Pause maintenance mode during tests
    if (function_exists('wp_maintenance_mode')) {
        update_option('wp_maintenance_mode', false);
    }
}, 10, 2);

flowguard_after_flow_run ​

Fires after a flow completes execution (whether successful or failed).

Hook Name: flowguard_after_flow_run

Parameters:

ParameterTypeDescription
$flow_idintThe flow post ID
$last_runarrayExecution results

Last Run Structure:

php
$last_run = [
    'timestamp' => '2024-12-06T15:30:00',  // ISO 8601 format
    'status'    => 'passed',               // passed, failed, or running
    'duration'  => 3450,                   // Execution time in milliseconds
    'error'     => '',                     // Error message (if failed)
    'results'   => [                       // Step-by-step results
        [
            'step'     => 1,
            'type'     => 'navigate',
            'status'   => 'passed',
            'duration' => 1200,
            'error'    => '',
        ],
        // ... more step results
    ],
];

Example Usage:

php
/**
 * Log flow execution completion
 */
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    error_log(sprintf(
        'Flowguard: Flow #%d completed with status "%s" in %dms',
        $flow_id,
        $last_run['status'],
        $last_run['duration']
    ));
}, 10, 2);

Use Cases:

  1. Email Notifications for Failures:
php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    if ($last_run['status'] === 'failed') {
        $flow = get_post($flow_id);
        
        wp_mail(
            'admin@yoursite.com',
            'Flowguard: Flow Failed',
            sprintf(
                "Flow '%s' failed:\n\n%s",
                $flow->post_title,
                $last_run['error']
            )
        );
    }
}, 10, 2);
  1. Track Statistics:
php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    // Store execution history
    $history = get_option('flowguard_execution_history', []);
    $history[] = [
        'flow_id'   => $flow_id,
        'timestamp' => $last_run['timestamp'],
        'status'    => $last_run['status'],
        'duration'  => $last_run['duration'],
    ];
    
    // Keep last 100 executions
    if (count($history) > 100) {
        $history = array_slice($history, -100);
    }
    
    update_option('flowguard_execution_history', $history);
}, 10, 2);
  1. Slack Integration:
php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    $flow = get_post($flow_id);
    $emoji = $last_run['status'] === 'passed' ? ':white_check_mark:' : ':x:';
    
    wp_remote_post('https://hooks.slack.com/services/YOUR/WEBHOOK/URL', [
        'body' => json_encode([
            'text' => sprintf(
                "%s Flow '%s' %s in %.2fs",
                $emoji,
                $flow->post_title,
                $last_run['status'],
                $last_run['duration'] / 1000
            ),
        ]),
    ]);
}, 10, 2);
  1. Trigger Remediation:
php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    if ($last_run['status'] === 'failed') {
        // Attempt automatic fix
        $flow = get_post($flow_id);
        
        if (strpos($flow->post_title, 'Cache') !== false) {
            // Clear all caches if cache-related test failed
            wp_cache_flush();
            
            // Optionally re-run the flow
            do_action('flowguard_rerun_flow', $flow_id);
        }
    }
}, 10, 2);
  1. Update External Monitoring:
php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    // Send to monitoring service (e.g., Datadog, New Relic)
    wp_remote_post('https://monitoring-service.com/api/events', [
        'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'],
        'body'    => json_encode([
            'event_type' => 'flowguard.execution',
            'flow_id'    => $flow_id,
            'status'     => $last_run['status'],
            'duration'   => $last_run['duration'],
            'timestamp'  => strtotime($last_run['timestamp']),
        ]),
    ]);
}, 10, 2);

flowguard_after_flow_timeout ​

Fires when a flow execution is marked as timed out.

Hook Name: flowguard_after_flow_timeout

Parameters:

ParameterTypeDescription
$flow_idintThe flow post ID
$last_runarrayTimeout results (same structure as flowguard_after_flow_run)

Example Usage:

php
add_action('flowguard_after_flow_timeout', function($flow_id, $last_run) {
    $flow = get_post($flow_id);
    error_log(sprintf(
        'Flowguard: Flow "%s" timed out after %dms',
        $flow->post_title,
        $last_run['duration']
    ));
}, 10, 2);

flowguard_after_flow_cancel ​

Fires when a running flow is cancelled by the user.

Hook Name: flowguard_after_flow_cancel

Parameters:

ParameterTypeDescription
$flow_idintThe flow post ID

Example Usage:

php
add_action('flowguard_after_flow_cancel', function($flow_id) {
    $flow = get_post($flow_id);
    error_log(sprintf('Flowguard: Flow "%s" was cancelled', $flow->post_title));
}, 10, 1);

Action Priority ​

All Flowguard actions accept priority and argument count parameters:

php
add_action('flowguard_before_flow_run', 'your_function', $priority, $accepted_args);

Default priority: 10

Lower numbers = Earlier execution Higher numbers = Later execution

Example with priority:

php
// Run this first (priority 5)
add_action('flowguard_before_flow_run', 'setup_test_environment', 5, 2);

// Run this second (priority 10, default)
add_action('flowguard_before_flow_run', 'log_execution', 10, 2);

// Run this last (priority 20)
add_action('flowguard_before_flow_run', 'notify_team', 20, 2);

Removing Actions ​

To remove a previously added action:

php
remove_action('flowguard_before_flow_run', 'your_function', $priority);

Example:

php
// Add action
add_action('flowguard_after_flow_run', 'send_notification', 10, 2);

// Remove action later
remove_action('flowguard_after_flow_run', 'send_notification', 10);

Best Practices ​

1. Check Flow Context ​

Filter actions based on flow properties:

php
add_action('flowguard_before_flow_run', function($flow_id, $flow_data) {
    // Only run for production flows
    if (strpos($flow_data['title'], '[Production]') !== false) {
        // Special handling for production tests
    }
}, 10, 2);

2. Handle Errors Gracefully ​

Don't let your action callbacks break flow execution:

php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    try {
        // Your code here
        send_notification($flow_id, $last_run);
    } catch (Exception $e) {
        error_log('Flowguard notification failed: ' . $e->getMessage());
        // Don't re-throw - let flow complete
    }
}, 10, 2);

3. Use Appropriate Priority ​

Order your actions logically:

  • Low priority (5-9): Setup and preparation
  • Default priority (10): Main operations
  • High priority (11-20): Cleanup and notifications

4. Avoid Heavy Operations ​

Keep action callbacks fast to not delay execution:

php
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    // Good: Queue notification for async processing
    wp_schedule_single_event(time(), 'send_flow_notification', [$flow_id, $last_run]);
    
    // Bad: Send email synchronously (slow)
    // wp_mail('admin@example.com', 'Flow Complete', '...');
}, 10, 2);

5. Document Your Hooks ​

Comment your action callbacks:

php
/**
 * Send Slack notification when critical flows fail
 *
 * @param int   $flow_id   Flow post ID
 * @param array $last_run  Execution results
 */
add_action('flowguard_after_flow_run', function($flow_id, $last_run) {
    // Implementation
}, 10, 2);

Complete Example: Flow Monitoring System ​

Here's a complete example that implements comprehensive flow monitoring:

php
<?php
/**
 * Flowguard Custom Monitoring
 */

class Flowguard_Monitor {
    
    public function __construct() {
        add_action('flowguard_before_flow_run', [$this, 'before_run'], 10, 2);
        add_action('flowguard_after_flow_run', [$this, 'after_run'], 10, 2);
    }
    
    /**
     * Log flow start
     */
    public function before_run($flow_id, $flow_data) {
        // Log to database
        global $wpdb;
        $wpdb->insert('flow_executions', [
            'flow_id'    => $flow_id,
            'flow_title' => $flow_data['title'],
            'started_at' => current_time('mysql'),
            'status'     => 'running',
        ]);
        
        // Store execution ID for later use
        $execution_id = $wpdb->insert_id;
        update_post_meta($flow_id, '_current_execution_id', $execution_id);
        
        // Notify team for critical flows
        if ($this->is_critical_flow($flow_data)) {
            $this->notify_slack("🔄 Critical flow '{$flow_data['title']}' started");
        }
    }
    
    /**
     * Log flow completion
     */
    public function after_run($flow_id, $last_run) {
        global $wpdb;
        
        // Get execution ID
        $execution_id = get_post_meta($flow_id, '_current_execution_id', true);
        
        // Update database
        $wpdb->update(
            'flow_executions',
            [
                'status'       => $last_run['status'],
                'duration'     => $last_run['duration'],
                'error'        => $last_run['error'],
                'completed_at' => current_time('mysql'),
            ],
            ['id' => $execution_id]
        );
        
        // Handle failures
        if ($last_run['status'] === 'failed') {
            $this->handle_failure($flow_id, $last_run);
        }
        
        // Send statistics
        $this->update_statistics($flow_id, $last_run);
        
        // Clean up
        delete_post_meta($flow_id, '_current_execution_id');
    }
    
    /**
     * Handle flow failures
     */
    private function handle_failure($flow_id, $last_run) {
        $flow = get_post($flow_id);
        
        // Email admin
        wp_mail(
            get_option('admin_email'),
            'Flowguard: Flow Failed',
            $this->format_failure_email($flow, $last_run)
        );
        
        // Notify Slack
        $this->notify_slack("❌ Flow '{$flow->post_title}' failed: {$last_run['error']}");
        
        // Increment failure count
        $failures = (int) get_post_meta($flow_id, '_failure_count', true);
        update_post_meta($flow_id, '_failure_count', $failures + 1);
    }
    
    /**
     * Update statistics
     */
    private function update_statistics($flow_id, $last_run) {
        $stats = get_option('flowguard_statistics', [
            'total_executions' => 0,
            'total_passed'     => 0,
            'total_failed'     => 0,
            'total_duration'   => 0,
        ]);
        
        $stats['total_executions']++;
        $stats['total_' . $last_run['status']]++;
        $stats['total_duration'] += $last_run['duration'];
        
        update_option('flowguard_statistics', $stats);
    }
    
    /**
     * Check if flow is critical
     */
    private function is_critical_flow($flow_data) {
        $critical_keywords = ['checkout', 'payment', 'login', 'critical'];
        $title_lower = strtolower($flow_data['title']);
        
        foreach ($critical_keywords as $keyword) {
            if (strpos($title_lower, $keyword) !== false) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Send Slack notification
     */
    private function notify_slack($message) {
        $webhook_url = get_option('flowguard_slack_webhook');
        
        if (!$webhook_url) {
            return;
        }
        
        wp_remote_post($webhook_url, [
            'body' => json_encode(['text' => $message]),
            'headers' => ['Content-Type' => 'application/json'],
        ]);
    }
    
    /**
     * Format failure email
     */
    private function format_failure_email($flow, $last_run) {
        return sprintf(
            "Flow: %s\n" .
            "Status: Failed\n" .
            "Duration: %dms\n" .
            "Error: %s\n\n" .
            "View flow: %s",
            $flow->post_title,
            $last_run['duration'],
            $last_run['error'],
            admin_url('admin.php?page=flowguard#/flows/' . $flow->ID)
        );
    }
}

// Initialize
new Flowguard_Monitor();

Future Actions ​

Additional actions planned for future versions:

  • flowguard_flow_created - When a flow is created
  • flowguard_flow_updated - When a flow is updated
  • flowguard_flow_deleted - When a flow is deleted
  • flowguard_step_executed - After each step executes
  • flowguard_flow_scheduled - When a flow is scheduled

Support ​

For questions about actions:

  1. Review WordPress Plugin API documentation
  2. Check the Flowguard source code
  3. Contact support for assistance