Fluent Forms uses its own custom database tables (like wp_fluentform_forms, wp_fluentform_submissions, etc.) which are completely separate from the standard WordPress posts/meta tables that our plugin currently handles.
DB Version Control would NOT work out of the box for Fluent Forms data because it only exports:
- WordPress posts (wp_posts)
- Post meta (wp_postmeta)
- WordPress options (wp_options)
- Navigation menus
Here's how you can add Fluent Forms support using our plugin's extensible filter system:
// Add this to your theme's functions.php or a custom plugin
/**
 * Export Fluent Forms data after post export
 */
add_action( 'dbvc_after_export_options', 'export_fluent_forms_data' );
function export_fluent_forms_data( $file_path, $options_data ) {
    global $wpdb;
    
    // Get the sync path
    $sync_path = dbvc_get_sync_path();
    
    // Export Fluent Forms
    $forms_table = $wpdb->prefix . 'fluentform_forms';
    if ( $wpdb->get_var( "SHOW TABLES LIKE '$forms_table'" ) === $forms_table ) {
        $forms = $wpdb->get_results( "SELECT * FROM $forms_table", ARRAY_A );
        
        if ( ! empty( $forms ) ) {
            file_put_contents(
                $sync_path . 'fluent-forms.json',
                wp_json_encode( $forms, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES )
            );
        }
    }
    
    // Export Fluent Forms Submissions
    $submissions_table = $wpdb->prefix . 'fluentform_submissions';
    if ( $wpdb->get_var( "SHOW TABLES LIKE '$submissions_table'" ) === $submissions_table ) {
        $submissions = $wpdb->get_results( "SELECT * FROM $submissions_table", ARRAY_A );
        
        if ( ! empty( $submissions ) ) {
            file_put_contents(
                $sync_path . 'fluent-form-submissions.json',
                wp_json_encode( $submissions, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES )
            );
        }
    }
    
    // Export Fluent Forms Entry Details
    $entry_details_table = $wpdb->prefix . 'fluentform_entry_details';
    if ( $wpdb->get_var( "SHOW TABLES LIKE '$entry_details_table'" ) === $entry_details_table ) {
        $entry_details = $wpdb->get_results( "SELECT * FROM $entry_details_table", ARRAY_A );
        
        if ( ! empty( $entry_details ) ) {
            file_put_contents(
                $sync_path . 'fluent-form-entry-details.json',
                wp_json_encode( $entry_details, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES )
            );
        }
    }
}
/**
 * Import Fluent Forms data after options import
 */
add_action( 'wp_loaded', function() {
    if ( defined( 'WP_CLI' ) && WP_CLI ) {
        add_action( 'dbvc_after_import_options', 'import_fluent_forms_data' );
    }
});
function import_fluent_forms_data() {
    global $wpdb;
    
    $sync_path = dbvc_get_sync_path();
    
    // Import Fluent Forms
    $forms_file = $sync_path . 'fluent-forms.json';
    if ( file_exists( $forms_file ) ) {
        $forms = json_decode( file_get_contents( $forms_file ), true );
        
        if ( ! empty( $forms ) ) {
            $forms_table = $wpdb->prefix . 'fluentform_forms';
            
            foreach ( $forms as $form ) {
                $wpdb->replace( $forms_table, $form );
            }
        }
    }
    
    // Import Fluent Forms Submissions
    $submissions_file = $sync_path . 'fluent-form-submissions.json';
    if ( file_exists( $submissions_file ) ) {
        $submissions = json_decode( file_get_contents( $submissions_file ), true );
        
        if ( ! empty( $submissions ) ) {
            $submissions_table = $wpdb->prefix . 'fluentform_submissions';
            
            foreach ( $submissions as $submission ) {
                $wpdb->replace( $submissions_table, $submission );
            }
        }
    }
    
    // Import Fluent Forms Entry Details
    $entry_details_file = $sync_path . 'fluent-form-entry-details.json';
    if ( file_exists( $entry_details_file ) ) {
        $entry_details = json_decode( file_get_contents( $entry_details_file ), true );
        
        if ( ! empty( $entry_details ) ) {
            $entry_details_table = $wpdb->prefix . 'fluentform_entry_details';
            
            foreach ( $entry_details as $detail ) {
                $wpdb->replace( $entry_details_table, $detail );
            }
        }
    }
}- Export: Hooks into dbvc_after_export_optionsto export all Fluent Forms tables as separate JSON files
- Import: Hooks into a custom action to import the Fluent Forms data back
- Tables Covered: Forms definitions, submissions, and entry details
- Safety: Checks if tables exist before attempting to query them
- File uploads: Fluent Forms file uploads stored in /wp-content/uploads/won't be synced
- Large datasets: Form submissions could be massive - you might want to add date filters
- Primary keys: Auto-increment IDs might cause conflicts between environments
sync-folder/
├── options.json
├── menus.json
├── fluent-forms.json              # Form definitions
├── fluent-form-submissions.json   # Form submissions
├── fluent-form-entry-details.json # Entry details
└── post/
    └── ...
This is exactly why our plugin's extensible architecture with filters and actions is so powerful - it can be extended to handle any WordPress data structure, not just the core WordPress tables.
The same pattern can be applied to:
- Contact Form 7 data
- Gravity Forms entries
- WooCommerce order data
- Custom plugin tables
- Any database table your site uses
The plugin provides the foundation and workflow, while filters let you customize exactly what data gets synchronized for your specific use case.