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_options
to 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.