📁 File Manager Pro
v10.0.3 | PHP: 8.1.34
Server: LiteSpeed
2026-06-29 01:08:37
📂
/ (Root)
/
home
/
apkbfjox
/
2jbet.net.pk
/
wp-content
/
plugins
/
generateblocks-pro
/
includes
/
extend
📍 /home/apkbfjox/2jbet.net.pk/wp-content/plugins/generateblocks-pro/includes/extend
🔄 Refresh
✏️
Editing: menu-item-conditions.php
Writable
<?php /** * Menu Item Conditions functionality. * * @package GenerateBlocksPro */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Class GenerateBlocks_Pro_Menu_Item_Conditions */ class GenerateBlocks_Pro_Menu_Item_Conditions extends GenerateBlocks_Pro_Singleton { /** * Cache for evaluated conditions to avoid repeated checks. * * @var array */ private $condition_cache = []; /** * Initialize the class. */ public function init() { // Don't initialize if block conditions are disabled. if ( ! generateblocks_pro_block_conditions_enabled() ) { return; } // Register post meta for menu items. add_action( 'init', [ $this, 'register_post_meta' ] ); // Add fields to menu item editor. add_action( 'wp_nav_menu_item_custom_fields', [ $this, 'add_condition_fields' ], 20, 5 ); // Save menu item conditions. add_action( 'wp_update_nav_menu_item', [ $this, 'save_menu_item_conditions' ], 10, 2 ); // Filter menu items based on conditions. add_filter( 'wp_nav_menu_objects', [ $this, 'filter_menu_items_by_conditions' ], 10, 2 ); // Add to condition usage tracking. add_filter( 'generateblocks_condition_usage_handlers', [ $this, 'add_menu_usage_handler' ], 10, 2 ); // Add admin scripts for dynamic UI. add_action( 'admin_enqueue_scripts', [ $this, 'add_admin_scripts' ] ); // AJAX handler for condition search. add_action( 'wp_ajax_gb_search_conditions', [ $this, 'ajax_search_conditions' ] ); // AJAX handler for loading more conditions. add_action( 'wp_ajax_gb_load_more_conditions', [ $this, 'ajax_load_more_conditions' ] ); } /** * Register the post meta. */ public function register_post_meta() { register_post_meta( 'nav_menu_item', '_gb_menu_condition', [ 'show_in_rest' => true, 'single' => true, 'type' => 'string', ] ); register_post_meta( 'nav_menu_item', '_gb_menu_condition_invert', [ 'show_in_rest' => true, 'single' => true, 'type' => 'boolean', ] ); } /** * Get the conditions limit per page. */ private function get_conditions_limit() { return apply_filters( 'generateblocks_menu_conditions_limit', 100 ); } /** * Add condition fields to menu items. * * @param string $item_id Menu item ID as a numeric string. * @param WP_Post $menu_item Menu item data object. * @param int $depth Depth of menu item. Used for padding. * @param stdClass|null $args An object of menu item arguments. * @param int $current_object_id Nav menu ID. */ public function add_condition_fields( $item_id, $menu_item, $depth, $args, $current_object_id ) { $condition_id = get_post_meta( $item_id, '_gb_menu_condition', true ); $invert = get_post_meta( $item_id, '_gb_menu_condition_invert', true ); // Get conditions for dropdown. static $conditions_cache = null; if ( null === $conditions_cache ) { // Get the most recent conditions. $conditions_cache = get_posts( [ 'post_type' => 'gblocks_condition', 'posts_per_page' => $this->get_conditions_limit(), 'orderby' => 'date', 'order' => 'DESC', 'post_status' => 'publish', 'suppress_filters' => false, 'no_found_rows' => true, ] ); } $conditions = $conditions_cache; // Always include the currently selected condition if it's not in the list. if ( $condition_id && 'gblocks_condition' === get_post_type( $condition_id ) ) { $found = false; foreach ( $conditions as $condition ) { if ( $condition->ID === $condition_id ) { $found = true; break; } } if ( ! $found ) { $selected_condition = get_post( $condition_id ); if ( $selected_condition ) { // Add it to the list for this menu item only. $conditions = array_merge( [ $selected_condition ], $conditions ); } } } // Check if there are more conditions than we're showing. $total_conditions = wp_count_posts( 'gblocks_condition' )->publish; $has_more = $total_conditions > count( $conditions_cache ); ?> <p class="field-gb-menu-condition description description-wide"> <label for="gb-menu-condition-<?php echo esc_attr( $item_id ); ?>"> <?php esc_html_e( 'Display Condition', 'generateblocks-pro' ); ?> </label> <div class="gb-menu-condition-wrapper" style="display: flex; align-items: center; gap: 10px;"> <select name="gb-menu-condition[<?php echo esc_attr( $item_id ); ?>]" id="gb-menu-condition-<?php echo esc_attr( $item_id ); ?>" class="gb-menu-condition-select" style="flex: 1;" data-item-id="<?php echo esc_attr( $item_id ); ?>" data-page="1" > <option value=""><?php esc_html_e( 'No condition', 'generateblocks-pro' ); ?></option> <?php foreach ( $conditions as $condition ) : ?> <option value="<?php echo esc_attr( $condition->ID ); ?>" <?php selected( $condition_id, $condition->ID ); ?>> <?php echo esc_html( $condition->post_title ); ?> </option> <?php endforeach; ?> </select> <?php if ( $has_more ) : ?> <button type="button" class="button gb-load-more-conditions" data-item-id="<?php echo esc_attr( $item_id ); ?>" > <?php esc_html_e( 'Load More', 'generateblocks-pro' ); ?> </button> <?php endif; ?> </div> <span class="description" style="display: block; margin-top: 5px;"> <?php esc_html_e( 'Choose a condition to control when this menu item appears.', 'generateblocks-pro' ); ?> </span> </p> <p class="field-gb-menu-condition-invert description description-wide" style="<?php echo $condition_id ? '' : 'display: none;'; ?>"> <label> <input type="checkbox" name="gb-menu-condition-invert[<?php echo esc_attr( $item_id ); ?>]" value="1" <?php checked( $invert, '1' ); ?> /> <?php esc_html_e( 'Invert condition', 'generateblocks-pro' ); ?> </label> <span class="description" style="display: block"><?php esc_html_e( 'Hide the menu item when the condition is true instead of false.', 'generateblocks-pro' ); ?></span> </p> <?php wp_nonce_field( 'update-menu-item-condition', 'menu-item-condition-nonce' ); ?> <?php } /** * Save the menu item conditions. * * @param int $menu_id The menu ID. * @param int $menu_item_id The menu item ID. * @return mixed */ public function save_menu_item_conditions( $menu_id, $menu_item_id ) { // Verify nonce. if ( ! isset( $_POST['menu-item-condition-nonce'] ) || ! wp_verify_nonce( $_POST['menu-item-condition-nonce'], 'update-menu-item-condition' ) ) { return $menu_id; } // Save condition from dropdown. $condition_id = isset( $_POST['gb-menu-condition'][ $menu_item_id ] ) ? sanitize_text_field( $_POST['gb-menu-condition'][ $menu_item_id ] ) : ''; if ( $condition_id ) { update_post_meta( $menu_item_id, '_gb_menu_condition', $condition_id ); } else { delete_post_meta( $menu_item_id, '_gb_menu_condition' ); } // Save invert setting. $invert = isset( $_POST['gb-menu-condition-invert'][ $menu_item_id ] ) ? '1' : '0'; if ( $condition_id && '1' === $invert ) { update_post_meta( $menu_item_id, '_gb_menu_condition_invert', '1' ); } else { delete_post_meta( $menu_item_id, '_gb_menu_condition_invert' ); } return $menu_id; } /** * Filter menu items based on conditions. * * @param array $sorted_menu_items The menu items, sorted by menu order. * @param stdClass $args The menu arguments. * @return array Filtered menu items. */ public function filter_menu_items_by_conditions( $sorted_menu_items, $args ) { if ( empty( $sorted_menu_items ) ) { return $sorted_menu_items; } $removed_items = []; // Build list of all items that should be removed (condition fails or parent removed). // Note: WordPress guarantees menu items are in hierarchical order (parents before children). foreach ( $sorted_menu_items as $item ) { $item_id = (int) $item->ID; // Skip if already marked for removal. if ( in_array( $item_id, $removed_items, true ) ) { continue; } // Check if parent was removed. $parent_id = ! empty( $item->menu_item_parent ) ? (int) $item->menu_item_parent : 0; if ( $parent_id && in_array( $parent_id, $removed_items, true ) ) { $removed_items[] = $item_id; continue; } // Check condition. $condition_id = get_post_meta( $item_id, '_gb_menu_condition', true ); if ( $condition_id && ! $this->should_show_menu_item( $item_id, $condition_id ) ) { $removed_items[] = $item_id; } } // If no items were removed, return the original array. if ( empty( $removed_items ) ) { return $sorted_menu_items; } // Filter out removed items. $final_items = []; foreach ( $sorted_menu_items as $item ) { if ( ! in_array( (int) $item->ID, $removed_items, true ) ) { $final_items[] = $item; } } return $final_items; } /** * Check if a menu item should be shown based on its condition. * * @param int $menu_item_id The menu item ID. * @param string $condition_id The condition ID. * @return bool Whether to show the menu item. */ private function should_show_menu_item( $menu_item_id, $condition_id ) { $condition_id = absint( $condition_id ); if ( ! $condition_id ) { return true; } $invert_condition = get_post_meta( $menu_item_id, '_gb_menu_condition_invert', true ) === '1'; // Check cache first to avoid repeated evaluations. $cache_key = $condition_id . '_' . ( $invert_condition ? '1' : '0' ); if ( isset( $this->condition_cache[ $cache_key ] ) ) { return $this->condition_cache[ $cache_key ]; } // Default to showing the menu item. $show = true; // Check if the condition post exists and is published. $condition_post = get_post( $condition_id ); if ( $condition_post && 'publish' === $condition_post->post_status ) { // Get the condition data. $display_conditions = get_post_meta( $condition_id, '_gb_conditions', true ); if ( ! empty( $display_conditions ) ) { // Use the existing conditions system to evaluate. $show = GenerateBlocks_Pro_Conditions::show( $display_conditions ); // If invert is enabled, flip the result. if ( $invert_condition ) { $show = ! $show; } } } // Cache the result. $this->condition_cache[ $cache_key ] = $show; return $show; } /** * Add menu item conditions handler to usage search. * * @param array $handlers Existing handlers. * @param int $condition_id The condition ID. * @return array Modified handlers. */ public function add_menu_usage_handler( $handlers, $condition_id ) { $handlers['menu_item_conditions'] = [ 'method' => 'search_menu_item_conditions_usage', 'label' => __( 'Menu Item Conditions', 'generateblocks-pro' ), ]; return $handlers; } /** * AJAX handler for searching conditions. */ public function ajax_search_conditions() { // Verify nonce. if ( ! wp_verify_nonce( $_GET['_ajax_nonce'], 'gb_search_conditions' ) ) { wp_die(); } $search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : ''; $page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1; $per_page = $this->get_conditions_limit(); $args = [ 'post_type' => 'gblocks_condition', 'posts_per_page' => $per_page, 'paged' => $page, 'orderby' => 'date', 'order' => 'DESC', 'post_status' => 'publish', ]; if ( $search ) { $args['s'] = $search; $args['orderby'] = 'relevance'; } $conditions = get_posts( $args ); $total = wp_count_posts( 'gblocks_condition' )->publish; $results = []; foreach ( $conditions as $condition ) { $results[] = [ 'id' => $condition->ID, 'text' => $condition->post_title ? $condition->post_title : __( 'Untitled Condition', 'generateblocks-pro' ), ]; } wp_send_json( [ 'results' => $results, 'pagination' => [ 'more' => ( $page * $per_page ) < $total, ], ] ); } /** * AJAX handler for loading more conditions. */ public function ajax_load_more_conditions() { // Verify nonce. if ( ! wp_verify_nonce( $_GET['_ajax_nonce'], 'gb_load_more_conditions' ) ) { wp_die(); } $page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 2; $limit = $this->get_conditions_limit(); $offset = ( $page - 1 ) * $limit; $conditions = get_posts( [ 'post_type' => 'gblocks_condition', 'posts_per_page' => $limit, 'offset' => $offset, 'orderby' => 'date', 'order' => 'DESC', 'post_status' => 'publish', 'suppress_filters' => false, 'no_found_rows' => false, ] ); $formatted_conditions = []; foreach ( $conditions as $condition ) { $formatted_conditions[] = [ 'id' => $condition->ID, 'title' => $condition->post_title ? $condition->post_title : __( 'Untitled Condition', 'generateblocks-pro' ), ]; } $total = wp_count_posts( 'gblocks_condition' )->publish; $has_more = ( $page * $limit ) < $total; wp_send_json_success( [ 'conditions' => $formatted_conditions, 'has_more' => $has_more, ] ); } /** * Add admin scripts for dynamic UI behavior. * * @param string $hook_suffix The current admin page. */ public function add_admin_scripts( $hook_suffix ) { // Only load on nav-menus.php page. if ( 'nav-menus.php' !== $hook_suffix ) { return; } wp_enqueue_script( 'gb-menu-item-conditions', GENERATEBLOCKS_PRO_DIR_URL . 'dist/menu-item-conditions.js', array(), GENERATEBLOCKS_PRO_VERSION, true ); wp_localize_script( 'gb-menu-item-conditions', 'gbMenuConditions', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonces' => array( 'loadMore' => wp_create_nonce( 'gb_load_more_conditions' ), 'search' => wp_create_nonce( 'gb_search_conditions' ), ), 'strings' => array( 'loading' => __( 'Loading...', 'generateblocks-pro' ), 'loadMore' => __( 'Load More', 'generateblocks-pro' ), ), ) ); } } // Initialize the class. GenerateBlocks_Pro_Menu_Item_Conditions::get_instance()->init();
💾 Save Changes
❌ Cancel