Skip to content

WordPress Filters

Flowguard provides filter hooks that allow developers to modify data and behavior before it's processed.

Overview

Filters are WordPress hooks that let you modify data as it passes through Flowguard. Unlike actions (which execute code), filters transform data and return modified values.

Use filters to:

  • Modify flow data before execution
  • Customize default settings
  • Transform step configurations
  • Add custom validation
  • Integrate with other systems

Available Filters

flowguard_flow_data

Modifies flow data before it's sent for execution.

Hook Name: flowguard_flow_data

Parameters:

ParameterTypeDescription
$flow_dataarrayComplete flow data
$flow_idintThe flow post ID

Flow Data Structure:

php
$flow_data = [
    'id'       => 123,
    'title'    => 'Login Test Flow',
    'steps'    => [
        [
            'id'     => 'step_1',
            'type'   => 'navigate',
            'config' => [
                'url' => 'https://yoursite.com/login'
            ]
        ],
        // ... more steps
    ],
    'settings' => [
        'timeout'    => 30000,
        'retries'    => 0,
        'screenshot' => true,
    ],
    'siteUrl'  => 'https://yoursite.com',
];

Return Value: Modified $flow_data array

Example Usage:

php
/**
 * Add custom headers to all flows
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['headers'] = [
        'X-Flow-ID' => $flow_id,
        'X-Site-ID' => get_current_blog_id(),
    ];
    
    return $flow_data;
}, 10, 2);

Use Cases:

1. Add Authentication Tokens

php
/**
 * Add auth token to flows that need it
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Only for flows with "API" in the title
    if (strpos($flow_data['title'], 'API') !== false) {
        $flow_data['authToken'] = get_option('my_api_token');
    }
    
    return $flow_data;
}, 10, 2);

2. Modify Timeouts Dynamically

php
/**
 * Increase timeout for slow pages
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    foreach ($flow_data['steps'] as &$step) {
        if ($step['type'] === 'navigate') {
            // Double timeout for navigation steps
            if (!isset($step['timeout'])) {
                $step['timeout'] = $flow_data['settings']['timeout'] * 2;
            }
        }
    }
    
    return $flow_data;
}, 10, 2);

3. Add Custom Step Data

php
/**
 * Add metadata to steps
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    foreach ($flow_data['steps'] as &$step) {
        $step['metadata'] = [
            'flow_id'   => $flow_id,
            'timestamp' => current_time('c'),
            'user_id'   => get_current_user_id(),
        ];
    }
    
    return $flow_data;
}, 10, 2);

4. Replace URLs for Staging

php
/**
 * Replace production URLs with staging URLs
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $is_staging = defined('WP_ENVIRONMENT_TYPE') && WP_ENVIRONMENT_TYPE === 'staging';
    
    if ($is_staging) {
        foreach ($flow_data['steps'] as &$step) {
            if ($step['type'] === 'navigate' && isset($step['config']['url'])) {
                $step['config']['url'] = str_replace(
                    'https://production.com',
                    'https://staging.com',
                    $step['config']['url']
                );
            }
        }
    }
    
    return $flow_data;
}, 10, 2);

5. Add Performance Monitoring

php
/**
 * Add performance markers
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['performance'] = [
        'enabled'     => true,
        'track_steps' => true,
        'report_url'  => 'https://monitor.example.com/api/report',
    ];
    
    return $flow_data;
}, 10, 2);

6. Inject Test Data

php
/**
 * Add test user credentials dynamically
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Find fill steps for username/password
    foreach ($flow_data['steps'] as &$step) {
        if ($step['type'] === 'fill') {
            // Replace placeholder with actual test credentials
            if (isset($step['config']['text'])) {
                $step['config']['text'] = str_replace(
                    '{{TEST_USER}}',
                    get_option('flowguard_test_username'),
                    $step['config']['text']
                );
                
                $step['config']['text'] = str_replace(
                    '{{TEST_PASS}}',
                    get_option('flowguard_test_password'),
                    $step['config']['text']
                );
            }
        }
    }
    
    return $flow_data;
}, 10, 2);

7. Add Conditional Logic

php
/**
 * Skip certain steps based on conditions
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Skip login steps if already logged in
    $is_logged_in = is_user_logged_in();
    
    if ($is_logged_in) {
        $flow_data['steps'] = array_filter($flow_data['steps'], function($step) {
            return !isset($step['tags']) || !in_array('login', $step['tags']);
        });
        
        // Re-index array
        $flow_data['steps'] = array_values($flow_data['steps']);
    }
    
    return $flow_data;
}, 10, 2);

8. Add Custom Validation

php
/**
 * Validate flow data before execution
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Ensure all navigate steps have valid URLs
    foreach ($flow_data['steps'] as $step) {
        if ($step['type'] === 'navigate') {
            $url = $step['config']['url'] ?? '';
            
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
                // Log error
                error_log("Flowguard: Invalid URL in flow {$flow_id}: {$url}");
                
                // Fix it
                $step['config']['url'] = home_url();
            }
        }
    }
    
    return $flow_data;
}, 10, 2);

9. Add Environment Variables

php
/**
 * Inject environment-specific configuration
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['environment'] = [
        'name'     => wp_get_environment_type(),
        'debug'    => WP_DEBUG,
        'multisite' => is_multisite(),
        'locale'   => get_locale(),
    ];
    
    return $flow_data;
}, 10, 2);

10. Modify Settings Based on Flow Type

php
/**
 * Adjust settings for different flow types
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Critical flows get more retries
    if (strpos(strtolower($flow_data['title']), 'critical') !== false) {
        $flow_data['settings']['retries'] = 3;
        $flow_data['settings']['timeout'] = 60000;
    }
    
    // Quick smoke tests run fast
    if (strpos(strtolower($flow_data['title']), 'smoke') !== false) {
        $flow_data['settings']['timeout'] = 10000;
        $flow_data['settings']['screenshot'] = false;
    }
    
    return $flow_data;
}, 10, 2);

Filter Priority

Filters accept priority and argument count parameters:

php
add_filter('flowguard_flow_data', 'your_function', $priority, $accepted_args);

Default priority: 10

Lower numbers = Earlier execution Higher numbers = Later execution

Example with priority:

php
// Run first (priority 5) - Set defaults
add_filter('flowguard_flow_data', 'set_flow_defaults', 5, 2);

// Run second (priority 10) - Modify URLs
add_filter('flowguard_flow_data', 'replace_urls', 10, 2);

// Run last (priority 20) - Final validation
add_filter('flowguard_flow_data', 'validate_flow_data', 20, 2);

Removing Filters

To remove a previously added filter:

php
remove_filter('flowguard_flow_data', 'your_function', $priority);

Example:

php
// Add filter
add_filter('flowguard_flow_data', 'modify_data', 10, 2);

// Remove filter later
remove_filter('flowguard_flow_data', 'modify_data', 10);

Best Practices

1. Always Return the Data

Filters must return the modified data:

php
// ✅ Good - Returns modified data
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['custom'] = 'value';
    return $flow_data;
}, 10, 2);

// ❌ Bad - Doesn't return anything
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['custom'] = 'value';
    // Missing return statement!
}, 10, 2);

2. Preserve Data Structure

Don't break the expected data structure:

php
// ✅ Good - Adds new fields, keeps structure
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    $flow_data['custom_field'] = 'value';
    return $flow_data;
}, 10, 2);

// ❌ Bad - Replaces entire array
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    return ['completely' => 'different'];
}, 10, 2);

3. Check Existence Before Modifying

Verify data exists before accessing it:

php
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Check if steps array exists
    if (isset($flow_data['steps']) && is_array($flow_data['steps'])) {
        foreach ($flow_data['steps'] as &$step) {
            // Modify steps safely
        }
    }
    
    return $flow_data;
}, 10, 2);

4. Use Type Checking

Ensure data types are correct:

php
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Ensure timeout is an integer
    if (isset($flow_data['settings']['timeout'])) {
        $flow_data['settings']['timeout'] = absint($flow_data['settings']['timeout']);
    }
    
    return $flow_data;
}, 10, 2);

5. Handle Errors Gracefully

Don't let filters break execution:

php
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    try {
        // Your modifications
        $flow_data = apply_custom_logic($flow_data);
    } catch (Exception $e) {
        error_log('Flowguard filter error: ' . $e->getMessage());
        // Return original data on error
    }
    
    return $flow_data;
}, 10, 2);

6. Document Your Filters

Comment complex filter logic:

php
/**
 * Inject environment-specific URLs into flow navigation steps
 *
 * Replaces placeholder URLs like {{BASE_URL}} with the actual
 * WordPress site URL based on the current environment.
 *
 * @param array $flow_data Complete flow data
 * @param int   $flow_id   Flow post ID
 * @return array Modified flow data
 */
add_filter('flowguard_flow_data', function($flow_data, $flow_id) {
    // Implementation
    return $flow_data;
}, 10, 2);

7. Use Appropriate Priority

Order filters logically based on dependencies:

php
// Priority 5: Set base configuration
add_filter('flowguard_flow_data', 'set_defaults', 5, 2);

// Priority 10: Apply modifications
add_filter('flowguard_flow_data', 'apply_customizations', 10, 2);

// Priority 15: Final adjustments
add_filter('flowguard_flow_data', 'finalize_data', 15, 2);

Complete Example: Dynamic Flow Configuration

Here's a complete example that implements dynamic flow configuration:

php
<?php
/**
 * Flowguard Dynamic Configuration
 */

class Flowguard_Config {
    
    private $config;
    
    public function __construct() {
        // Load configuration
        $this->config = $this->load_config();
        
        // Add filter
        add_filter('flowguard_flow_data', [$this, 'modify_flow_data'], 10, 2);
    }
    
    /**
     * Load configuration from options
     */
    private function load_config() {
        return [
            'environments' => [
                'production' => [
                    'base_url' => 'https://production.com',
                    'timeout'  => 30000,
                ],
                'staging' => [
                    'base_url' => 'https://staging.com',
                    'timeout'  => 60000,
                ],
            ],
            'test_users' => [
                'admin' => [
                    'username' => 'test_admin',
                    'password' => 'test_pass_123',
                ],
                'customer' => [
                    'username' => 'test_customer',
                    'password' => 'test_pass_456',
                ],
            ],
        ];
    }
    
    /**
     * Modify flow data based on configuration
     */
    public function modify_flow_data($flow_data, $flow_id) {
        // 1. Replace environment placeholders
        $flow_data = $this->replace_placeholders($flow_data);
        
        // 2. Inject test credentials
        $flow_data = $this->inject_credentials($flow_data);
        
        // 3. Adjust timeouts
        $flow_data = $this->adjust_timeouts($flow_data);
        
        // 4. Add tracking
        $flow_data = $this->add_tracking($flow_data, $flow_id);
        
        // 5. Validate
        $flow_data = $this->validate($flow_data);
        
        return $flow_data;
    }
    
    /**
     * Replace environment placeholders
     */
    private function replace_placeholders($flow_data) {
        $environment = wp_get_environment_type();
        $base_url = $this->config['environments'][$environment]['base_url'] ?? home_url();
        
        foreach ($flow_data['steps'] as &$step) {
            if ($step['type'] === 'navigate' && isset($step['config']['url'])) {
                $step['config']['url'] = str_replace(
                    '{{BASE_URL}}',
                    $base_url,
                    $step['config']['url']
                );
            }
        }
        
        return $flow_data;
    }
    
    /**
     * Inject test user credentials
     */
    private function inject_credentials($flow_data) {
        // Detect which user type based on flow title
        $user_type = 'customer'; // default
        
        if (stripos($flow_data['title'], 'admin') !== false) {
            $user_type = 'admin';
        }
        
        $credentials = $this->config['test_users'][$user_type] ?? null;
        
        if (!$credentials) {
            return $flow_data;
        }
        
        foreach ($flow_data['steps'] as &$step) {
            if ($step['type'] === 'fill' && isset($step['config']['text'])) {
                $text = $step['config']['text'];
                
                if (strpos($text, '{{USERNAME}}') !== false) {
                    $step['config']['text'] = $credentials['username'];
                }
                
                if (strpos($text, '{{PASSWORD}}') !== false) {
                    $step['config']['text'] = $credentials['password'];
                }
            }
        }
        
        return $flow_data;
    }
    
    /**
     * Adjust timeouts based on environment
     */
    private function adjust_timeouts($flow_data) {
        $environment = wp_get_environment_type();
        $timeout = $this->config['environments'][$environment]['timeout'] ?? 30000;
        
        $flow_data['settings']['timeout'] = $timeout;
        
        return $flow_data;
    }
    
    /**
     * Add tracking information
     */
    private function add_tracking($flow_data, $flow_id) {
        $flow_data['tracking'] = [
            'flow_id'     => $flow_id,
            'environment' => wp_get_environment_type(),
            'timestamp'   => current_time('c'),
            'user_id'     => get_current_user_id(),
            'site_id'     => get_current_blog_id(),
        ];
        
        return $flow_data;
    }
    
    /**
     * Validate flow data
     */
    private function validate($flow_data) {
        // Ensure all URLs are absolute
        foreach ($flow_data['steps'] as &$step) {
            if ($step['type'] === 'navigate') {
                $url = $step['config']['url'] ?? '';
                
                if ($url && !filter_var($url, FILTER_VALIDATE_URL)) {
                    error_log("Flowguard: Invalid URL detected: {$url}");
                    $step['config']['url'] = home_url();
                }
            }
        }
        
        // Ensure timeout is reasonable
        $timeout = $flow_data['settings']['timeout'] ?? 30000;
        
        if ($timeout < 1000 || $timeout > 300000) {
            error_log('Flowguard: Timeout out of range, using default');
            $flow_data['settings']['timeout'] = 30000;
        }
        
        return $flow_data;
    }
}

// Initialize
new Flowguard_Config();

Future Filters

Additional filters planned for future versions:

  • flowguard_step_config - Modify individual step configuration
  • flowguard_flow_results - Transform results before saving
  • flowguard_settings_defaults - Change default settings
  • flowguard_validation_rules - Add custom validation
  • flowguard_timeout_value - Dynamic timeout calculation

Support

For questions about filters:

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