Home / Admin / GravityForms_DIR_AC_SYNC – Gravity Forms & Feeds Sync Engine
Duplicate Snippet

Embed Snippet on Your Site

GravityForms_DIR_AC_SYNC – Gravity Forms & Feeds Sync Engine

* Description: Manual sync functionality for forms and their feeds
* Location: Run Everywhere
* Priority: 20

ismail daugherty PRO
<10
Code Preview
php
<?php
/**
 * WPCode Snippet: Gravity Forms & Feeds Sync Engine
 * Description: Manual sync functionality for forms and their feeds
 * Location: Run Everywhere
 * Priority: 20
 */
defined( 'ABSPATH' ) || exit;
// Add a manual test button in admin bar for debugging
add_action( 'admin_bar_menu', function( $wp_admin_bar ) {
    if ( ! current_user_can( 'manage_options' ) ) return;
    
    $wp_admin_bar->add_node( [
        'id'    => 'gf-forms-sync-test',
        'title' => '🔄 Sync GF Forms & Feeds',
        'href'  => admin_url( 'admin.php?gf_forms_sync_test=1' ),
    ] );
}, 999 );
// Handle manual test trigger
add_action( 'admin_init', function() {
    if ( ! isset( $_GET['gf_forms_sync_test'] ) || ! current_user_can( 'manage_options' ) ) return;
    
    if ( ! class_exists( 'GFAPI' ) ) {
        wp_die( 'Gravity Forms not active!' );
    }
    
    // First, clean up orphaned forms
    gf_cleanup_orphaned_form_posts();
    
    // Then sync all existing forms
    $forms = GFAPI::get_forms();
    $count = 0;
    
    foreach ( $forms as $form ) {
        gf_mirror_form_to_cpt( $form );
        $count++;
    }
    
    wp_redirect( admin_url( 'edit.php?post_type=gf_form_feeds&synced=' . $count ) );
    exit;
} );
// Show success message
add_action( 'admin_notices', function() {
    if ( isset( $_GET['synced'] ) && $_GET['post_type'] === 'gf_form_feeds' ) {
        $count = intval( $_GET['synced'] );
        echo '<div class="notice notice-success"><p>✅ Synced ' . $count . ' forms to CPT!</p></div>';
    }
} );
/**
 * Clean up orphaned form posts
 */
function gf_cleanup_orphaned_form_posts() {
    if ( ! class_exists( 'GFAPI' ) ) {
        return;
    }
    
    // Get all active form IDs
    $forms = GFAPI::get_forms();
    $active_form_ids = array_map( function( $form ) {
        return absint( $form['id'] );
    }, $forms );
    
    error_log( 'GF_FORMS_SYNC: Active form IDs: ' . implode( ', ', $active_form_ids ) );
    
    // Query all gf_form_feeds posts
    $all_form_posts = new WP_Query( [
        'post_type'      => 'gf_form_feeds',
        'posts_per_page' => -1,
        'fields'         => 'ids',
    ] );
    
    $deleted_count = 0;
    
    foreach ( $all_form_posts->posts as $post_id ) {
        $form_id = intval( get_post_meta( $post_id, 'form_id', true ) );
        
        // If this post is for a form that no longer exists, delete it
        if ( $form_id && ! in_array( $form_id, $active_form_ids, true ) ) {
            wp_delete_post( $post_id, true );
            $deleted_count++;
            error_log( "GF_FORMS_SYNC: Deleted orphaned form post for non-existent form {$form_id} (post {$post_id})" );
        }
    }
    
    if ( $deleted_count > 0 ) {
        error_log( "GF_FORMS_SYNC: Cleaned up {$deleted_count} orphaned form posts" );
    }
}
/**
 * Main sync function
 */
function gf_mirror_form_to_cpt( $form ) {
    // Verify CPT exists
    if ( ! post_type_exists( 'gf_form_feeds' ) ) {
        error_log( 'GF_FORMS_SYNC: CPT gf_form_feeds does not exist!' );
        return;
    }
    
    // Validate form data
    if ( empty( $form ) || ! is_array( $form ) || empty( $form['id'] ) ) {
        error_log( 'GF_FORMS_SYNC: Invalid form data' );
        return;
    }
    
    $form_id = absint( $form['id'] );
    $form_title = isset( $form['title'] ) ? sanitize_text_field( $form['title'] ) : 'Form ' . $form_id;
    
    error_log( "GF_FORMS_SYNC: Processing form {$form_id} - {$form_title}" );
    
    // Get existing post for this form
    $existing_query = new WP_Query( [
        'post_type'      => 'gf_form_feeds',
        'posts_per_page' => 1,
        'fields'         => 'ids',
        'meta_query'     => [
            [
                'key'   => 'form_id',
                'value' => $form_id,
            ]
        ]
    ] );
    
    $existing_post_id = ! empty( $existing_query->posts ) ? $existing_query->posts[0] : false;
    
    // Get feed data
    $feed_data = gf_get_form_feed_data( $form_id );
    $entry_count = gf_get_form_entry_count( $form_id );
    
    $slug = sanitize_title( "gf-form-{$form_id}" );
    
    $post_data = [
        'post_type'   => 'gf_form_feeds',
        'post_status' => 'publish',
        'post_title'  => $form_title,
        'post_name'   => $slug,
    ];
    
    $meta_data = [
        'form_id'              => $form_id,
        'form_status'          => ! empty( $form['is_active'] ) ? 'active' : 'inactive',
        'entry_count'          => $entry_count,
        'field_count'          => ! empty( $form['fields'] ) ? count( $form['fields'] ) : 0,
        'feed_count_total'     => $feed_data['total'],
        'feed_count_active'    => $feed_data['active'],
        'feed_count_inactive'  => $feed_data['inactive'],
        'feeds_list'           => $feed_data['feeds'],
        'form_settings'        => [
            'ajax_enabled'      => ! empty( $form['enableAjax'] ) ? 1 : 0,
            'honeypot_enabled'  => ! empty( $form['enableHoneypot'] ) ? 1 : 0,
            'save_continue'     => ! empty( $form['save'] ) && ! empty( $form['save']['enabled'] ) ? 1 : 0,
            'limit_entries'     => ! empty( $form['limitEntries'] ) ? 1 : 0,
        ],
        'notification_count'   => ! empty( $form['notifications'] ) ? count( $form['notifications'] ) : 0,
        'confirmation_count'   => ! empty( $form['confirmations'] ) ? count( $form['confirmations'] ) : 0,
        'last_sync'           => current_time( 'mysql' ),
        'gf_form_edit_link'    => admin_url( 'admin.php?page=gf_edit_forms&id=' . $form_id ),
        'gf_form_entries_link' => admin_url( 'admin.php?page=gf_entries&id=' . $form_id ),
        'notifications_content' => gf_format_notifications_content( $form ),
        'confirmations_content' => gf_format_confirmations_content( $form ),
    ];
    
    if ( $existing_post_id ) {
        // Update existing
        $post_data['ID'] = $existing_post_id;
        $post_id = wp_update_post( $post_data );
        error_log( "GF_FORMS_SYNC: Updated form {$form_id} (post {$post_id})" );
    } else {
        // Create new
        $post_id = wp_insert_post( $post_data );
        error_log( "GF_FORMS_SYNC: Created form {$form_id} (post {$post_id})" );
    }
    
    // Update all meta
    if ( $post_id && ! is_wp_error( $post_id ) ) {
        foreach ( $meta_data as $key => $value ) {
            update_post_meta( $post_id, $key, $value );
        }
        
        // ✅ ADD ACF FIELD KEY REFERENCES FOR LINK FIELDS
        update_post_meta( $post_id, '_gf_form_edit_link', 'field_gf_form_edit_link' );
        update_post_meta( $post_id, '_gf_form_entries_link', 'field_gf_form_entries_link' );
        
        gf_populate_field_details( $post_id, $form_id, $form );
        
        // ✅ TRIGGER FIELD DETAILS POPULATION
        do_action( 'gf_form_feeds_sync_complete', $post_id, $form_id );
        error_log( "GF_FORMS_SYNC: Triggered field details sync for form {$form_id}" );
    }
    
    error_log( "GF_FORMS_SYNC: Completed form {$form_id}" );
}
function gf_format_notifications_content( $form ) {
    if ( empty( $form['notifications'] ) || ! is_array( $form['notifications'] ) ) {
        return "No notifications configured for this form.";
    }
    
    $output = [];
    $count = 1;
    
    foreach ( $form['notifications'] as $notification_id => $notification ) {
        $output[] = "═══════════════════════════════════════════════";
        $output[] = "NOTIFICATION #{$count}";
        $output[] = "═══════════════════════════════════════════════";
        $output[] = "";
        $output[] = "Name: " . ( ! empty( $notification['name'] ) ? $notification['name'] : 'Unnamed' );
        $output[] = "ID: {$notification_id}";
        $output[] = "Status: " . ( ! empty( $notification['isActive'] ) ? 'Active' : 'Inactive' );
        $output[] = "";
        $output[] = "TO: " . ( ! empty( $notification['to'] ) ? $notification['to'] : 'Not set' );
        if ( ! empty( $notification['cc'] ) ) {
            $output[] = "CC: " . $notification['cc'];
        }
        if ( ! empty( $notification['bcc'] ) ) {
            $output[] = "BCC: " . $notification['bcc'];
        }
        $output[] = "FROM: " . ( ! empty( $notification['from'] ) ? $notification['from'] : 'Not set' );
        $output[] = "FROM NAME: " . ( ! empty( $notification['fromName'] ) ? $notification['fromName'] : 'Not set' );
        $output[] = "";
        $output[] = "SUBJECT: " . ( ! empty( $notification['subject'] ) ? $notification['subject'] : 'No subject' );
        $output[] = "";
        if ( ! empty( $notification['message'] ) ) {
            $output[] = "MESSAGE:";
            $output[] = "---";
            $output[] = strip_tags( $notification['message'] );
            $output[] = "---";
        }
        $output[] = "";
        if ( ! empty( $notification['conditionalLogic'] ) ) {
            $output[] = "⚠️ Has Conditional Logic";
        }
        if ( ! empty( $notification['event'] ) ) {
            $output[] = "Trigger Event: " . $notification['event'];
        }
        $output[] = "";
        $count++;
    }
    
    return implode( "\n", $output );
}
function gf_format_confirmations_content( $form ) {
    if ( empty( $form['confirmations'] ) || ! is_array( $form['confirmations'] ) ) {
        return "No confirmations configured for this form.";
    }
    
    $output = [];
    $count = 1;
    
    foreach ( $form['confirmations'] as $confirmation_id => $confirmation ) {
        $output[] = "═══════════════════════════════════════════════";
        $output[] = "CONFIRMATION #{$count}";
        $output[] = "═══════════════════════════════════════════════";
        $output[] = "";
        $output[] = "Name: " . ( ! empty( $confirmation['name'] ) ? $confirmation['name'] : 'Unnamed' );
        $output[] = "ID: {$confirmation_id}";
        $output[] = "Status: " . ( ! empty( $confirmation['isActive'] ) ? 'Active' : 'Inactive' );
        $output[] = "Default: " . ( ! empty( $confirmation['isDefault'] ) ? 'Yes' : 'No' );
        $output[] = "";
        $type = ! empty( $confirmation['type'] ) ? $confirmation['type'] : 'message';
        $output[] = "TYPE: " . strtoupper( $type );
        $output[] = "";
        switch ( $type ) {
            case 'message':
                if ( ! empty( $confirmation['message'] ) ) {
                    $output[] = "MESSAGE:";
                    $output[] = "---";
                    $output[] = strip_tags( $confirmation['message'] );
                    $output[] = "---";
                }
                break;
            case 'redirect':
                $output[] = "REDIRECT URL: " . ( ! empty( $confirmation['url'] ) ? $confirmation['url'] : 'Not set' );
                if ( ! empty( $confirmation['queryString'] ) ) {
                    $output[] = "Query String: " . $confirmation['queryString'];
                }
                break;
            case 'page':
                $output[] = "PAGE ID: " . ( ! empty( $confirmation['pageId'] ) ? $confirmation['pageId'] : 'Not set' );
                if ( ! empty( $confirmation['queryString'] ) ) {
                    $output[] = "Query String: " . $confirmation['queryString'];
                }
                break;
        }
        $output[] = "";
        if ( ! empty( $confirmation['conditionalLogic'] ) ) {
            $output[] = "⚠️ Has Conditional Logic";
            $output[] = "";
        }
        $count++;
    }
    
    return implode( "\n", $output );
}
function gf_populate_field_details( $post_id, $form_id, $form ) {
    if ( empty( $form['fields'] ) || ! is_array( $form['fields'] ) ) {
        update_post_meta( $post_id, 'field_details_list', 'No fields in this form.' );
        update_post_meta( $post_id, 'field_details_last_sync', current_time( 'mysql' ) );
        return;
    }
    
    $output = [];
    $output[] = "═══════════════════════════════════════════════════════════════════";
    $output[] = "FORM: {$form['title']} (ID: {$form_id})";
    $output[] = "TOTAL FIELDS: " . count( $form['fields'] );
    $output[] = "SYNCED: " . current_time( 'F j, Y g:i a' );
    $output[] = "═══════════════════════════════════════════════════════════════════";
    $output[] = "";
    
    foreach ( $form['fields'] as $field ) {
        $output[] = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
        $output[] = "FIELD #{$field->id}";
        $output[] = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
        $output[] = "";
        $output[] = "Label: " . ( ! empty( $field->label ) ? $field->label : '[No Label]' );
        $output[] = "Type: " . $field->type;
        if ( ! empty( $field->adminLabel ) ) {
            $output[] = "Admin Label: " . $field->adminLabel;
        }
        if ( ! empty( $field->description ) ) {
            $output[] = "Description: " . $field->description;
        }
        $output[] = "Required: " . ( ! empty( $field->isRequired ) ? 'Yes' : 'No' );
        if ( isset( $field->visibility ) ) {
            $output[] = "Visibility: " . $field->visibility;
        }
        if ( ! empty( $field->cssClass ) ) {
            $output[] = "CSS Class: " . $field->cssClass;
        }
        if ( ! empty( $field->conditionalLogic ) ) {
            $output[] = "⚠️ Has Conditional Logic";
        }
        if ( ! empty( $field->allowsPrepopulate ) ) {
            $output[] = "✓ Allows Prepopulation";
            if ( ! empty( $field->inputName ) ) {
                $output[] = "  Parameter Name: " . $field->inputName;
            }
        }
        if ( ! empty( $field->gppa ) || ! empty( $field->gppaDynamicPopulation ) ) {
            $output[] = "✓ GPPA ENABLED";
            if ( ! empty( $field->choices ) && is_array( $field->choices ) ) {
                $output[] = "  GPPA Choices: " . count( $field->choices ) . " dynamically populated";
            }
        }
        if ( ! empty( $field->choices ) && is_array( $field->choices ) ) {
            $output[] = "";
            $output[] = "Choices:";
            foreach ( $field->choices as $choice ) {
                $choice_text = is_array( $choice ) ? $choice['text'] : $choice;
                $choice_value = is_array( $choice ) && isset( $choice['value'] ) ? $choice['value'] : $choice_text;
                $output[] = "  • {$choice_text}" . ( $choice_text !== $choice_value ? " (value: {$choice_value})" : '' );
            }
        }
        if ( ! empty( $field->inputs ) && is_array( $field->inputs ) ) {
            $output[] = "";
            $output[] = "Sub-fields:";
            foreach ( $field->inputs as $input ) {
                if ( is_array( $input ) && ! empty( $input['label'] ) ) {
                    $output[] = "  • {$input['id']}: {$input['label']}";
                }
            }
        }
        if ( $field->type === 'fileupload' ) {
            if ( ! empty( $field->maxFiles ) ) {
                $output[] = "Max Files: " . $field->maxFiles;
            }
            if ( ! empty( $field->allowedExtensions ) ) {
                $output[] = "Allowed Extensions: " . $field->allowedExtensions;
            }
        }
        if ( ! empty( $field->defaultValue ) ) {
            $output[] = "Default Value: " . $field->defaultValue;
        }
        if ( ! empty( $field->placeholder ) ) {
            $output[] = "Placeholder: " . $field->placeholder;
        }
        $output[] = "";
    }
    
    update_post_meta( $post_id, 'field_details_list', implode( "\n", $output ) );
    update_post_meta( $post_id, 'field_details_last_sync', current_time( 'mysql' ) );
}
/**
 * Get feed data for a form
 */
function gf_get_form_feed_data( $form_id ) {
    $feed_data = [
        'total' => 0,
        'active' => 0,
        'inactive' => 0,
        'feeds' => []
    ];
    
    // Check if GFAddOn exists
    if ( ! class_exists( 'GFAddOn' ) ) {
        return $feed_data;
    }
    
    // Get all registered add-ons
    $addons = GFAddOn::get_registered_addons();
    
    foreach ( $addons as $addon_class ) {
        if ( ! class_exists( $addon_class ) ) {
            continue;
        }
        
        try {
            $addon = call_user_func( [ $addon_class, 'get_instance' ] );
            if ( ! $addon || ! method_exists( $addon, 'get_feeds' ) ) {
                continue;
            }
            
            $feeds = $addon->get_feeds( $form_id );
            
            if ( ! empty( $feeds ) && is_array( $feeds ) ) {
                foreach ( $feeds as $feed ) {
                    $is_active = ! isset( $feed['is_active'] ) || $feed['is_active'] ? 1 : 0;
                    
                    $addon_name = 'Unknown';
                    if ( method_exists( $addon, 'get_short_title' ) ) {
                        $addon_name = $addon->get_short_title();
                    }
                    
                    $feed_name = 'Unnamed Feed';
                    if ( isset( $feed['meta']['feed_name'] ) ) {
                        $feed_name = $feed['meta']['feed_name'];
                    } elseif ( isset( $feed['meta']['feedName'] ) ) {
                        $feed_name = $feed['meta']['feedName'];
                    }
                    
                    $feed_type = '';
                    if ( isset( $feed['addon_slug'] ) ) {
                        $feed_type = $feed['addon_slug'];
                    } elseif ( method_exists( $addon, 'get_slug' ) ) {
                        $feed_type = $addon->get_slug();
                    }
                    
                    $feed_data['feeds'][] = [
                        'addon'     => sanitize_text_field( $addon_name ),
                        'name'      => sanitize_text_field( $feed_name ),
                        'type'      => sanitize_text_field( $feed_type ),
                        'is_active' => $is_active,
                    ];
                    
                    $feed_data['total']++;
                    if ( $is_active ) {
                        $feed_data['active']++;
                    } else {
                        $feed_data['inactive']++;
                    }
                }
            }
        } catch ( Exception $e ) {
            error_log( 'GF_FORMS_SYNC: Error getting feeds for addon ' . $addon_class . ': ' . $e->getMessage() );
        }
    }
    
    return $feed_data;
}
/**
 * Get form entry count
 */
function gf_get_form_entry_count( $form_id ) {
    // Use GFAPI if available
    if ( class_exists( 'GFAPI' ) ) {
        $search_criteria = [
            'status' => 'active',
            'form_id' => $form_id
        ];
        
        try {
            $count = GFAPI::count_entries( $form_id, $search_criteria );
            return intval( $count );
        } catch ( Exception $e ) {
            error_log( 'GF_FORMS_SYNC: Error counting entries: ' . $e->getMessage() );
            return 0;
        }
    }
    
    return 0;
}
// Hook 1: Form save in builder
add_action( 'gform_after_save_form', function( $form, $is_new ) {
    error_log( 'GF_FORMS_SYNC: gform_after_save_form fired' );
    gf_mirror_form_to_cpt( $form );
}, 20, 2 );
// Hook 2: JSON import (receives array)
add_action( 'gform_forms_post_import', function( $forms ) {
    error_log( 'GF_FORMS_SYNC: gform_forms_post_import fired with ' . count( $forms ) . ' forms' );
    if ( is_array( $forms ) ) {
        foreach ( $forms as $form ) {
            gf_mirror_form_to_cpt( $form );
        }
    }
}, 20, 1 );
// Hook 3: Form deletion - remove form post when form is deleted
add_action( 'gform_before_delete_form', function( $form_id ) {
    error_log( "GF_FORMS_SYNC: Form {$form_id} is being deleted - removing associated post" );
    
    // Find the post for this form
    $query = new WP_Query( [
        'post_type'      => 'gf_form_feeds',
        'posts_per_page' => 1,
        'fields'         => 'ids',
        'meta_query'     => [
            [
                'key'   => 'form_id',
                'value' => absint( $form_id ),
            ]
        ]
    ] );
    
    if ( ! empty( $query->posts ) ) {
        wp_delete_post( $query->posts[0], true );
        error_log( "GF_FORMS_SYNC: Deleted post for form {$form_id}" );
    }
}, 10, 1 );
// Hook 4: Periodic cleanup - runs when viewing the gf_form_feeds post list
add_action( 'load-edit.php', function() {
    if ( ! isset( $_GET['post_type'] ) || $_GET['post_type'] !== 'gf_form_feeds' ) {
        return;
    }
    
    // Only run cleanup occasionally (using transient to limit frequency)
    if ( get_transient( 'gf_forms_sync_cleanup_done' ) ) {
        return;
    }
    
    gf_cleanup_orphaned_form_posts();
    
    // Set transient to prevent running too often (once per hour)
    set_transient( 'gf_forms_sync_cleanup_done', true, HOUR_IN_SECONDS );
} );
// Verify Gravity Forms is loaded
add_action( 'init', function() {
    if ( ! class_exists( 'GFCommon' ) ) {
        error_log( 'GF_FORMS_SYNC: Gravity Forms not detected!' );
    } else {
        error_log( 'GF_FORMS_SYNC: Gravity Forms detected, version: ' . GFCommon::$version );
    }
}, 999 );

Comments

Add a Comment