Home / Admin / GravityView_DIR_RAPI -Expose GravityView ACF Fields to REST API
Duplicate Snippet

Embed Snippet on Your Site

GravityView_DIR_RAPI -Expose GravityView ACF Fields to REST API

* WPCode Snippet: Expose GravityView ACF Fields to REST API (MANUAL SYNC ONLY)
* Description: Makes ALL GravityView data accessible ONLY when manually synced
* Location: Run Everywhere
* Priority: 15

ismail daugherty PRO
<10
Code Preview
php
<?php
/**
 * WPCode Snippet: Expose GravityView ACF Fields to REST API (MANUAL SYNC ONLY)
 * Description: Makes ALL GravityView data accessible ONLY when manually synced
 * Location: Run Everywhere
 * Priority: 15
 */
defined( 'ABSPATH' ) || exit;
/**
 * ✅ CRITICAL FIX #1: Prevent ALL GravityView rendering in REST API context
 * This stops the infinite loop completely
 */
add_filter( 'gravityview/shortcode/should-render', function( $should_render ) {
    if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        return false;
    }
    return $should_render;
}, 5 );
add_filter( 'gravityview_render_view', function( $should_render ) {
    if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        return false;
    }
    return $should_render;
}, 5 );
/**
 * ✅ CRITICAL FIX #2: Remove post content from REST responses
 * Prevents any content rendering entirely
 */
add_filter( 'rest_prepare_gv_views_sync', function( $response, $post, $request ) {
    if ( isset( $response->data['content'] ) ) {
        $response->data['content']['rendered'] = '';
    }
    if ( isset( $response->data['excerpt'] ) ) {
        $response->data['excerpt']['rendered'] = '';
    }
    return $response;
}, 10, 3 );
/**
 * ✅ CRITICAL FIX #3: Disable Gravity Flow field registration in REST
 */
add_action( 'rest_api_init', function() {
    // Remove Gravity Flow search field hooks during REST requests
    if ( class_exists( 'GravityView_Plugin_Hooks_Gravity_Flow' ) ) {
        remove_all_filters( 'gk/gravityview/search/available-fields' );
    }
}, 1 ); // Priority 1 to run before GravityView
/**
 * Check if we're in a manual sync operation
 */
function is_manual_gv_sync() {
    // Check for admin sync trigger
    if ( isset( $_GET['sync_gravityview'] ) && current_user_can( 'manage_options' ) ) {
        return true;
    }
    
    // Check for REST API sync endpoint
    if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        $route = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
        if ( strpos( $route, '/gv-views-sync/v1/sync' ) !== false ) {
            return true;
        }
    }
    
    return false;
}
/**
 * Register ALL GravityView meta fields in REST API
 */
add_action( 'rest_api_init', function() {
    
    // ========================================
    // GRAVITYVIEW VIEWS SYNC CPT FIELDS
    // ========================================
    $gv_fields = array(
        // ==========================================
        // TAB 1: VIEW OVERVIEW & LINKS
        // ==========================================
        'view_id'                       => 'integer',
        'view_slug'                     => 'string',
        'view_status'                   => 'string',
        'view_type'                     => 'string',
        'entry_count'                   => 'integer',
        'date_created'                  => 'string',
        'date_modified'                 => 'string',
        
        // Edit Links
        'gv_view_edit_link'             => 'string',
        'gv_multiple_entries_edit_link' => 'string',
        'gv_single_entry_edit_link'     => 'string',
        'gv_edit_entry_edit_link'       => 'string',
        'gv_view_preview_link'          => 'string',
        'view_shortcode'                => 'string',
        
        // ==========================================
        // TAB 2: FORM CONNECTIONS
        // ==========================================
        'primary_form_id'               => 'integer',
        'primary_form_title'            => 'string',
        'primary_form_edit_link'        => 'string',
        'multiple_forms_enabled'        => 'boolean',
        'strict_entry_match'            => 'boolean',
        'connected_forms_list'          => 'string',
        'join_conditions_list'          => 'string',
        
        // ==========================================
        // TAB 3: LAYOUT & FIELDS CONFIGURATION
        // ==========================================
        'multiple_entries_fields_list'  => 'string',
        'single_entry_fields_list'      => 'string',
        'edit_entry_fields_list'        => 'string',
        'field_mappings_details'        => 'string',
        'custom_content_fields'         => 'string',
        'total_fields_count'            => 'integer',
        'widgets_top_list'              => 'string',
        'widgets_bottom_list'           => 'string',
        
        // ==========================================
        // TAB 4: FILTER & SORT SETTINGS
        // ==========================================
        'filter_enabled'                => 'boolean',
        'advanced_filter_enabled'       => 'boolean',
        'advanced_filter_rules_list'    => 'string',
        'filter_by_user'                => 'boolean',
        'filter_approval_status'        => 'string',
        'default_sort_field'            => 'string',
        'default_sort_direction'        => 'string',
        'search_enabled'                => 'boolean',
        'search_fields_list'            => 'string',
        'pagination_enabled'            => 'boolean',
        'entries_per_page'              => 'integer',
        
        // ==========================================
        // TAB 5: DISPLAY SETTINGS
        // ==========================================
        'show_only_approved'            => 'boolean',
        'hide_empty_fields'             => 'boolean',
        'hide_until_searched'           => 'boolean',
        'lightbox_enabled'              => 'boolean',
        'featured_entries_enabled'      => 'boolean',
        'ratings_enabled'               => 'boolean',
        'entry_link_type'               => 'string',
        'no_entries_message'            => 'string',
        'table_columns_config'          => 'string',
        'map_settings_details'          => 'string',
        'calendar_settings_details'     => 'string',
        
        // ==========================================
        // TAB 6: PERMISSIONS & CAPABILITIES
        // ==========================================
        'view_permissions'              => 'string',
        'edit_entry_permission'         => 'string',
        'delete_entry_permission'       => 'string',
        'user_edit_enabled'             => 'boolean',
        'user_delete_enabled'           => 'boolean',
        'moderate_entries'              => 'boolean',
        'magic_links_enabled'           => 'boolean',
        'magic_links_config'            => 'string',
        'allowed_user_roles_list'       => 'string',
        
        // ==========================================
        // TAB 7: EXPORT & OUTPUT SETTINGS
        // ==========================================
        'csv_export_enabled'            => 'boolean',
        'csv_export_fields_list'        => 'string',
        'print_enabled'                 => 'boolean',
        'print_layout_config'           => 'string',
        'pdf_export_enabled'            => 'boolean',
        'excel_export_enabled'          => 'boolean',
        'export_permissions'            => 'string',
        
        // ==========================================
        // TAB 8: INTEGRATIONS & EXTENSIONS
        // ==========================================
        'gravity_flow_enabled'          => 'boolean',
        'gravity_flow_settings'         => 'string',
        'gravity_pdf_enabled'           => 'boolean',
        'gravity_pdf_templates'         => 'string',
        'gravity_calendar_enabled'      => 'boolean',
        'gravity_calendar_settings'     => 'string',
        'gravity_charts_enabled'        => 'boolean',
        'gravity_charts_config'         => 'string',
        'gravity_boards_enabled'        => 'boolean',
        'gravity_boards_settings'       => 'string',
        'gravity_math_calculations'     => 'string',
        'connected_feeds_list'          => 'string',
        
        // ==========================================
        // TAB 9: CUSTOM CODE
        // ==========================================
        'custom_css'                    => 'string',
        'custom_javascript'             => 'string',
        'custom_php_hooks'              => 'string',
        'css_classes'                   => 'string',
        
        // ==========================================
        // TAB 10: REST API & SYNC
        // ==========================================
        'rest_api_enabled'              => 'boolean',
        'api_endpoints_list'            => 'string',
        'whalesync_status'              => 'string',
        'last_sync'                     => 'string',
        'airtable_record_id'            => 'string',
        'sync_errors'                   => 'string',
        
        // ==========================================
        // UTILITY FIELDS
        // ==========================================
        'embedded_pages_list'           => 'string',
        'view_notes'                    => 'string',
        'cache_enabled'                 => 'boolean',
        'cache_duration'                => 'integer',
        'view_template'                 => 'string',
        
        // ==========================================
        // ADDITIONAL FIELD DETAILS
        // ==========================================
        'field_details_comprehensive'   => 'string',
        'field_details_sync_timestamp'  => 'string',
        'gv_layout_builder_link'        => 'string',
        'gv_settings_link'              => 'string',
        'view_statistics'               => 'string',
    );
    
    // Register GravityView fields
    foreach ( $gv_fields as $field_name => $field_type ) {
        register_rest_field( 'gv_views_sync', $field_name, array(
            'get_callback' => function( $object ) use ( $field_name, $field_type ) {
                $value = get_post_meta( $object['id'], $field_name, true );
                
                // Handle empty values
                if ( $value === '' || $value === false ) {
                    return null;
                }
                
                // ✅ TYPE CONVERSION - Force correct types for Airtable/WhaleSync
                switch ( $field_type ) {
                    case 'integer':
                        return intval( $value );
                    case 'boolean':
                        // Handle various boolean representations
                        if ( is_string( $value ) ) {
                            return ( $value === '1' || $value === 'true' || $value === 'yes' );
                        }
                        return (bool) $value;
                    case 'array':
                        // Ensure arrays are properly formatted
                        if ( is_string( $value ) ) {
                            // Try to decode if it's JSON
                            $decoded = json_decode( $value, true );
                            if ( json_last_error() === JSON_ERROR_NONE ) {
                                return $decoded;
                            }
                        }
                        return is_array( $value ) ? $value : array();
                    case 'object':
                        // Ensure objects are properly formatted
                        if ( is_string( $value ) ) {
                            $decoded = json_decode( $value );
                            if ( json_last_error() === JSON_ERROR_NONE ) {
                                return $decoded;
                            }
                        }
                        return is_array( $value ) || is_object( $value ) ? $value : new stdClass();
                    default:
                        // Return string values as-is
                        return strval( $value );
                }
            },
            'update_callback' => function( $value, $object ) use ( $field_name ) {
                return update_post_meta( $object->ID, $field_name, $value );
            },
            'schema' => array(
                'description' => ucwords( str_replace( '_', ' ', $field_name ) ),
                'type'        => $field_type,
                'context'     => array( 'view', 'edit' ),
            ),
        ) );
    }
    
} );
/**
 * Ensure REST API is enabled for GravityView CPT
 */
add_filter( 'register_post_type_args', function( $args, $post_type ) {
    
    if ( $post_type === 'gv_views_sync' ) {
        $args['show_in_rest'] = true;
        $args['rest_base'] = 'gv-views-sync';
        $args['rest_controller_class'] = 'WP_REST_Posts_Controller';
        
        // Ensure custom fields support
        if ( ! in_array( 'custom-fields', $args['supports'] ) ) {
            $args['supports'][] = 'custom-fields';
        }
    }
    
    return $args;
}, 10, 2 );
/**
 * ✅ SECURITY: Block access unless using Application Password
 */
add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
    
    // Only protect GravityView CPT endpoints
    $route = $request->get_route();
    if ( strpos( $route, '/wp/v2/gv-views-sync' ) === false && 
         strpos( $route, '/gv-views-sync/v1' ) === false ) {
        return $result;
    }
    
    // Check if user is authenticated
    $user = wp_get_current_user();
    
    if ( ! $user || ! $user->exists() ) {
        return new WP_Error(
            'rest_forbidden',
            __( 'Authentication required. Please use Application Password credentials.' ),
            array( 'status' => 401 )
        );
    }
    
    // ✅ CRITICAL: Check if authenticated via Application Password
    $auth_header = $request->get_header( 'authorization' );
    
    // If no auth header, they're just logged in via browser - BLOCK IT
    if ( empty( $auth_header ) ) {
        return new WP_Error(
            'rest_forbidden',
            __( 'Application Password authentication required. Browser login not allowed.' ),
            array( 'status' => 403 )
        );
    }
    
    // If they have auth header, they're using Application Password - ALLOW IT
    return $result;
    
}, 10, 3 );
// ... (rest of the endpoints code stays the same)

Comments

Add a Comment