'Dashboard_Pages', 'form' => 'Form', 'steps' => 'Form_Steps', 'step' => 'Form_Step', /* 'repeater' => 'Repeater', 'repeater-item' => 'Repeater_Item', */ 'admin-form' => 'Form_Select', 'submissions' => 'Submissions_Select' // 'field' => 'field' ]; //enqueue frontend admin css wp_enqueue_style( 'fea-public' ); if( fea_instance()->is_license_active() ){ wp_enqueue_style( 'fea-public-pro' ); } foreach( $blocks as $block => $className ){ include_once( FEA_DIR . 'main/gutenberg/blocks/' . $block . '.php' ); $className = "\Frontend_Admin\Gutenberg\\".$className; $class = new $className; $name = str_replace( '_', '-', $block ); register_block_type( FEA_DIR . "/assets/build/blocks/$name", [ 'render_callback' => [ $class, 'render' ], ] ); } $field_types = fea_instance()->frontend->field_types; global $fea_field_types; if( $field_types ){ foreach( $field_types as $type ){ if ( $type instanceof Field_Types\Field_Base ) { $name = str_replace( '_', '-', $type->name ); $name = str_replace( '-input', '', $name ); $name = str_replace( '-area', 'area', $name ); if( ! empty( $name ) && file_exists( FEA_DIR . "/assets/build/$name/index.js" ) ){ register_block_type( FEA_DIR . "/assets/build/blocks/$name", [ 'render_callback' => [ $this, 'render_field_block' ], ] ); } } } } } public function render_field_block( $attr, $content, $block ) { global $fea_instance, $fea_form, $post; $form_display = $fea_instance->form_display; $render = ''; $field = acf_get_valid_field($attr); $field_key = $field['field_key'] ?? uniqid(); $field['key'] = !empty( $fea_form['id'] ) ? $fea_form['id'] . '_' . $field_key : $field_key; $field['builder'] = 'gutenberg'; $field['type'] = str_replace( array( 'frontend-admin/', '-field', '-' ), array( '', '', '_' ), $block->name ); $field['type'] = str_replace( '_area', 'area', $field['type'] ); $field['type'] = str_replace( '_input', '', $field['type'] ); do_action( 'frontend_admin/form_assets/type=' . $field['type'], $field ); $field['name'] = $attr['name'] ?? 'fea_' . $field['type']; $field = $form_display->get_field_data_type( $field, $fea_form ); if( ! $field ) return false; if ( ! isset( $field['value'] ) || $field['value'] === null ) { $field = $form_display->get_field_value( $field, $fea_form ); } //fix options. They have to be an array of key => values, not array of index => [key,label] if( isset( $field['choices'] ) && is_array( $field['choices'] ) ){ $choices = []; foreach( $field['choices'] as $key => $choice ){ if( is_array( $choice ) ){ $choices[ $choice['value'] ] = $choice['label']; }else{ $choices[ $key ] = $choice; } } $field['choices'] = $choices; } ob_start(); $field['builder'] = 'gutenberg'; $fea_instance->form_display->render_field_wrap( $field ); //$this->render_field_wrap( $field ); $render = ob_get_contents(); ob_end_clean(); return $render; } public function render_field_wrap( $attributes ) { $label = $attributes['label'] ?? ''; $field_name = $attributes['name'] ?? ''; $field_class = fea_instance()->frontend->field_types[ $attributes['type'] ] ?? null; if ( ! $field_class ) return; ?>
$field_name ]); ?>'> render_field_interactive( $field ); ?>
'frontend-admin', 'title' => 'Frontend Admin', 'icon' => 'feedback', ], ] ); } /** * enqueue_block_editor_assets * * Allows a safe way to customize Guten-only functionality. * * @date 14/11/22 * @since 5.8.0 * * @param void * @return void */ function enqueue_block_editor_assets() { // Load the compiled blocks into the editor. wp_enqueue_script( 'fea-block-settings', FEA_URL . '/assets/build/block-settings/index.js', ['wp-edit-post'], '1.0', true ); do_action( 'frontend_admin/enqueue_block_editor_assets' ); } function block_visibilty( $block_content, $block ) { // Fetch block attributes $attrs = $block['attrs'] ?? []; // If visibility isn't limited → always show if ( empty( $attrs['limitVisibility'] ) ) { return $block_content; } $rules_groups = $attrs['visibilityRules'] ?? []; // If there are no rules, hide nothing if ( empty( $rules_groups ) ) { return $block_content; } // Helper: check one rule $evaluate_rule = function( $rule ) { global $post; $user = wp_get_current_user(); $is_logged_in = is_user_logged_in(); $showFor = $rule['showFor'] ?? 'everyone'; $roles = $rule['showForRoles'] ?? []; $message = $rule['noPermissionsMessage'] ?? ''; $isPostAuthor = $rule['isPostAuthor '] ?? false; $field = $rule['field'] ?? ''; $operator = $rule['operator'] ?? 'equals'; $value = $rule['value'] ?? ''; // --- SHOW FOR LOGIC --------------------------------------- // Show for logged in users only if ( $showFor === 'logged_in' ) { if ( ! $is_logged_in ) { return [ false, $message ]; } // Role restriction if ( ! empty( $roles ) ) { $user_roles = (array) $user->roles; $intersect = array_intersect( $user_roles, $roles ); if ( empty( $intersect ) ) { return [ false, $message ]; } } if( $isPostAuthor ){ // If rule requires the current user to be the post author, check it. if ( empty( $post ) || ! isset( $post->post_author ) || (int) $post->post_author !== (int) $user->ID ) { return [ false, $message ]; } } } // Show for logged out users only if ( $showFor === 'logged_out' ) { if ( $is_logged_in ) { return [ false, $message ]; } } // Optional: If no field is set, rule passes if ( empty( $field ) ) { return [ true, '' ]; } // Fetch field value $field_val = get_post_meta( $post->ID, $field, true ); // ^ You must define this helper for your plugin. switch ( $operator ) { case 'equals': $pass = $field_val == $value; break; case 'not_equals': $pass = $field_val != $value; break; case 'contains': $pass = is_string( $field_val ) && strpos( $field_val, $value ) !== false; break; case 'greater_than': $pass = floatval( $field_val ) > floatval( $value ); break; case 'less_than': $pass = floatval( $field_val ) < floatval( $value ); break; default: $pass = true; } return [ $pass, $message ]; }; // --- OR GROUPS LOGIC ------------------------------------------------- $block_visible = false; $message_to_show = ''; foreach ( $rules_groups as $and_group ) { $and_pass = true; $group_message = ''; foreach ( $and_group as $rule ) { list( $pass, $msg ) = $evaluate_rule( $rule ); if ( ! $pass ) { $and_pass = false; $group_message = $msg; // Preserve message for failed rule break; } } // One group passing is enough to show the block if ( $and_pass ) { $block_visible = true; break; } // If this group failed and no group passed yet, store message if ( ! $block_visible && ! empty( $group_message ) ) { $message_to_show = $group_message; } } // --- FINAL OUTPUT ---------------------------------------------------- if ( $block_visible ) { return $block_content; } // If hidden: return ! empty( $message_to_show ) ? wp_kses_post( $message_to_show ) : ''; } function block_render( $block_content, $block ) { global $fea_form; // Get block attributes safely $attrs = $block['attrs'] ?? []; if ( 'core/button' === $block['blockName'] ) { $submit = $attrs['submitButton'] ?? false; if ( $submit ) { if ( ! $fea_form ) { return $block_content; } else { if ( ! empty( $block_content ) ) { $block_content = preg_replace( '/]*?)class="([^"]*)"/is', 'content; }else{ return null; } } if( 'field' == $type ){ $keys = explode( '_', $key ); $key = end( $keys ); } $blocks = parse_blocks( $post_content ); foreach ( $blocks as $block ) { $block = $this->recursive_block_search( $block, $key, $type ); if ( $block ) { return $block; } } return null; } public function recursive_block_search( $block, $key, $type = 'form' ) { global $post, $fea_block_visibility; if ( ! is_array( $block ) ) { $fea_block_visibility = null; // Reset global variable if block is not an array return null; } // Check if the block has the limitVisility attribute and if so, save it to the global variable if ( ! empty( $block['attrs']['limitVisibility'] ) && ! empty( $block['attrs']['visibilityRules'] ) ) { $fea_block_visibility = $block['attrs']['visibilityRules']; } if ( ! empty( $block['attrs'][$type.'_key'] ) && $block['attrs'][$type.'_key'] === $key ) { return $block; } if ( ! empty( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as $inner_block ) { $result = $this->recursive_block_search( $inner_block, $key, $type ); if ( $result ) { return $result; } } } $fea_block_visibility = null; // Reset global variable when going back up the recursion return null; } public function rest_pre_dispatch( $result, $server, $request ) { if ( strpos( $request->get_route(), '/wp/v2/block-renderer' ) !== false ) { $attributes_to_remove = [ 'limitVisibility', 'visibilityRules' ]; $attributes = $request['attributes'] ?? []; foreach ( $attributes_to_remove as $attr ) { if ( isset( $attributes[ $attr ] ) ) { unset( $attributes[ $attr ] ); } } $request['attributes'] = $attributes; } return $result; } public function __construct() { add_filter('block_categories_all', array( $this, 'add_block_categories' )); add_action('init', array( $this, 'register_blocks' ), 20); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); add_filter( 'render_block', [ $this, 'block_render' ], 10, 2 ); add_filter( 'render_block', [ $this, 'block_visibilty' ], 9, 2 ); add_filter( 'rest_pre_dispatch', array( $this, 'rest_pre_dispatch' ), 10, 3 ); } } fea_instance()->gutenberg = new Gutenberg(); endif;