Server IP : 172.67.157.199 / Your IP : 3.133.143.36 [ Web Server : Apache System : Linux b70eb322-3aee-0c53-7c82-0db91281f2c6.secureserver.net 6.1.90-1.el9.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 2 12:09:22 EDT 2024 x86_64 User : root ( 0) PHP Version : 8.0.30.2 Disable Function : NONE Domains : 0 Domains MySQL : ON | cURL : ON | WGET : ON | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/chroot/var/www/wp-content/plugins/ultimate-dashboard/modules/admin-bar/ |
Upload File : |
<?php /** * Admin Bar module. * * @package Ultimate_Dashboard */ namespace Udb\AdminBar; defined( 'ABSPATH' ) || die( "Can't access directly" ); use Udb\Vars; use Udb\Helpers\Array_Helper; use Udb\Base\Base_Module; /** * Class to setup admin menu module. */ class Admin_Bar_Module extends Base_Module { /** * The class instance. * * @var object */ public static $instance; /** * The current module url. * * @var string */ public $url; /** * Frontend admin bar menu items. * * @var array */ public $frontend_items = array(); /** * Frontend admin bar menu in udb expected format. * * @var array */ public $frontend_menu = array(); /** * Module constructor. */ public function __construct() { $this->url = ULTIMATE_DASHBOARD_PLUGIN_URL . '/modules/admin-bar'; /** * This was created by looking at wp-toolbar-editor plugin's code. * These items can be checked in wp-includes/admdin-bar.php file. */ $this->frontend_items = array( array( 'parent' => 'top-secondary', 'id' => 'search', 'title' => '', 'meta' => array( 'class' => 'admin-bar-search', 'tabindex' => -1, ), ), array( 'parent' => false, 'after' => 'site-name', 'id' => 'customize', 'title' => __( 'Customize' ), 'href' => '', 'meta' => array( 'class' => 'hide-if-no-customize', ), ), array( 'parent' => false, 'after' => 'new-content', 'id' => 'edit', 'title' => __( 'Edit' ) . ' {post_type}', 'href' => '', ), array( 'parent' => 'site-name', 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => admin_url(), ), array( 'parent' => 'site-name', 'after' => 'dashboard', 'id' => 'appearance', 'title' => '', 'href' => '', 'group' => true, ), array( 'parent' => 'appearance', 'id' => 'themes', 'title' => __( 'Themes' ), 'href' => admin_url( 'themes.php' ), ), array( 'parent' => 'appearance', 'after' => 'themes', 'id' => 'widgets', 'title' => __( 'Widgets' ), 'href' => admin_url( 'widgets.php' ), ), array( 'parent' => 'appearance', 'after' => 'widgets', 'id' => 'menus', 'title' => __( 'Menus' ), 'href' => admin_url( 'nav-menus.php' ), ), ); $this->frontend_menu = $this->frontend_items_to_array(); } /** * Get instance of the class. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Setup admin menu module. */ public function setup() { add_action( 'admin_menu', array( self::get_instance(), 'submenu_page' ) ); add_action( 'wp_before_admin_bar_render', array( self::get_instance(), 'get_existing_menu' ), 999999 ); add_action( 'admin_enqueue_scripts', array( self::get_instance(), 'admin_styles' ) ); add_action( 'admin_enqueue_scripts', array( self::get_instance(), 'admin_scripts' ) ); $this->setup_ajax(); } /** * Setup ajax. */ public function setup_ajax() { require_once __DIR__ . '/ajax/class-get-users.php'; $get_users = new Ajax\Get_Users(); add_action( 'wp_ajax_udb_admin_bar_get_users', array( $get_users, 'ajax' ) ); } /** * Add submenu page. */ public function submenu_page() { add_submenu_page( 'edit.php?post_type=udb_widgets', __( 'Admin Bar Editor', 'ultimate-dashboard' ), __( 'Admin Bar Editor', 'ultimate-dashboard' ), apply_filters( 'udb_settings_capability', 'manage_options' ), 'udb_admin_bar', array( $this, 'submenu_page_content' ) ); // are we using this filter everywhere? } /** * Submenu page content. */ public function submenu_page_content() { require __DIR__ . '/templates/template.php'; } /** * Enqueue admin styles. */ public function admin_styles() { $enqueue = require __DIR__ . '/inc/css-enqueue.php'; $enqueue( $this ); } /** * Enqueue admin scripts. */ public function admin_scripts() { $enqueue = require __DIR__ . '/inc/js-enqueue.php'; $enqueue( $this ); } /** * Get existing admin bar menu. */ public function get_existing_menu() { global $wp_admin_bar; Vars::set( 'existing_admin_bar_menu', $wp_admin_bar->get_nodes() ); } /** * Turn flat admin bar menu array to a nested format (parent -> submenu). * * @param array $nodes The existing admin bar menu. * @return array Array in expected format. */ public function nodes_to_array( $nodes ) { $udb_array = array(); foreach ( $nodes as $node_id => $node ) { $udb_array[ $node_id ] = array( 'title' => '', 'title_default' => $node->title, 'id' => $node->id, 'id_default' => $node->id, 'parent' => $node->parent, 'parent_default' => $node->parent, 'href' => '', 'href_default' => $node->href, 'group' => $node->group, 'group_default' => $node->group, 'meta' => $node->meta, 'meta_default' => $node->meta, 'was_added' => 0, 'is_hidden' => 0, /** * These properties are not being used currently. * But leave it here because in the future, if requested, it would be used for * "hide menu item for specific role(s) & user(s)" functionality (inside dropdowns). */ // 'disallowed_roles' => array(), // 'disallowed_users' => array(), ); } return $udb_array; } /** * Turn frontend items array to expected UDB array. * Like what we have in nodes_to_array above. * * @return array Array in expected format. */ public function frontend_items_to_array() { $udb_array = array(); foreach ( $this->frontend_items as $item_data ) { $item_id = $item_data['id']; $udb_array[ $item_id ] = array( 'title' => '', 'title_default' => $item_data['title'], 'id' => $item_data['id'], 'id_default' => $item_data['id'], 'parent' => $item_data['parent'], 'parent_default' => $item_data['parent'], 'href' => '', 'href_default' => isset( $item_data['href'] ) ? $item_data['href'] : '', 'group' => isset( $item_data['group'] ) ? $item_data['group'] : false, 'group_default' => isset( $item_data['group'] ) ? $item_data['group'] : false, 'meta' => isset( $item_data['meta'] ) ? $item_data['meta'] : array(), 'meta_default' => isset( $item_data['meta'] ) ? $item_data['meta'] : array(), 'was_added' => 0, 'is_hidden' => 0, 'frontend_only' => 1, /** * These properties are not being used currently. * But leave it here because in the future, if requested, it would be used for * "hide menu item for specific role(s) & user(s)" functionality (inside dropdowns). */ // 'disallowed_roles' => array(), // 'disallowed_users' => array(), ); if ( isset( $item_data['after'] ) ) { $udb_array[ $item_id ]['after'] = $item_data['after']; } } return $udb_array; } /** * Parse saved menu with existing menu. * * @param array $saved_menu The saved menu. * @param array $existing_menu The nested-formatted existing menu. * @param bool $target This function is being called either for the builder or the output. * Possible vaule is 'builder' and 'output'. * * @return array The parsed menu. */ public function parse_menu( $saved_menu, $existing_menu, $target = 'builder' ) { $non_udb_items_id = $this->get_non_udb_items_id( $saved_menu ); $prev_id = ''; // Get new items from $existing_menu which are not inside $saved_menu. foreach ( $existing_menu as $menu_id => $menu ) { if ( ! in_array( $menu_id, $non_udb_items_id, true ) ) { $new_item = array( 'id' => $menu_id, 'id_default' => $menu_id, 'title' => $menu['title'], 'title_default' => $menu['title'], 'parent' => $menu['parent'], 'parent_default' => $menu['parent'], 'href' => $menu['href'], 'href_default' => $menu['href'], 'group' => $menu['group'], 'group_default' => $menu['group'], 'meta' => $menu['meta'], 'meta_default' => $menu['meta'], 'was_added' => 0, 'is_hidden' => 0, /** * These properties are not being used currently. * But leave it here because in the future, if requested, it would be used for * "hide menu item for specific role(s) & user(s)" functionality (inside dropdowns). */ // 'disallowed_roles' => array(), // 'disallowed_users' => array(), ); if ( empty( $prev_id ) ) { $saved_menu = array( $menu_id => $new_item ) + $saved_menu; } else { $pos = array_search( $prev_id, array_keys( $saved_menu ), true ); $saved_menu = array_slice( $saved_menu, 0, $pos, true ) + array( $menu_id => $new_item ) + array_slice( $saved_menu, $pos, count( $saved_menu ) - 1, true ); } } $prev_id = $menu_id; } // Exclude non-udb items from $saved_menu which are no longer exist in $existing_menu. foreach ( $non_udb_items_id as $menu_id ) { if ( 'output' === $target ) { if ( ! isset( $existing_menu[ $menu_id ] ) ) { unset( $saved_menu[ $menu_id ] ); } } else { if ( ! isset( $existing_menu[ $menu_id ] ) && ! isset( $this->frontend_menu[ $menu_id ] ) ) { unset( $saved_menu[ $menu_id ] ); } } } // Reset some item's property's value (such as title) so that it will use the existing item's value. if ( 'output' === $target ) { if ( isset( $saved_menu['edit'] ) ) { $saved_menu['edit']['title'] = ''; $saved_menu['edit']['title_default'] = ''; } } // Bring some defaults from $existing_menu to $saved_menu. foreach ( $saved_menu as $menu_id => $menu ) { if ( isset( $existing_menu[ $menu_id ] ) ) { // Loop over matched $existing_menu item. foreach ( $existing_menu[ $menu_id ] as $field_key => $field_value ) { if ( ! isset( $menu[ $field_key ] ) ) { $saved_menu[ $menu_id ][ $field_key ] = $field_value; } else { if ( 'output' === $target ) { if ( empty( $menu[ $field_key ] ) && ! empty( $field_value ) ) { $saved_menu[ $menu_id ][ $field_key ] = $field_value; } } } } } } // Compare saved menu's default values to existing menu's default values. foreach ( $saved_menu as $menu_id => $menu ) { if ( isset( $existing_menu[ $menu_id ] ) ) { // Loop over matched $saved_menu item. foreach ( $menu as $field_key => $field_value ) { if ( false !== stripos( $field_key, '_default' ) ) { if ( isset( $existing_menu[ $menu_id ][ $field_key ] ) && $field_value !== $existing_menu[ $menu_id ][ $field_key ] ) { $saved_menu[ $menu_id ][ $field_key ] = $existing_menu[ $menu_id ][ $field_key ]; } } } } } /** * The "menu-toggle" has been removed from the admin bar buider. * Now after parsing it, its position is not at the beginning of the array. * Let's bring it back to the correct position (as first item of the array). */ if ( isset( $saved_menu['menu-toggle'] ) ) { unset( $saved_menu['menu-toggle'] ); } if ( isset( $existing_menu['menu-toggle'] ) ) { $saved_menu = array( 'menu-toggle' => $existing_menu['menu-toggle'] ) + $saved_menu; } return $saved_menu; } /** * Loop over $saved_menu and collect the id of menu items which are not added by UDB builder. * * @param array $saved_menu The saved menu. * @return array The non udb menu items. */ public function get_non_udb_items_id( $saved_menu ) { // Id of menu items which are not added by UDB. $non_udb_items_id = array(); foreach ( $saved_menu as $menu_id => $menu_array ) { if ( ! $menu_array['was_added'] ) { array_push( $non_udb_items_id, $menu_id ); } } return $non_udb_items_id; } /** * Loop over $saved_menu and collect the id of menu items * which are not added by UDB builder and frontend only. * * @param array $saved_menu The saved menu. * @return array The non udb menu items. */ public function get_non_udb_items_id_fontend_only( $saved_menu ) { // Id of menu items which are not added by UDB & frontend only. $non_udb_items_id = array(); foreach ( $saved_menu as $menu_id => $menu_array ) { if ( ! $menu_array['was_added'] && isset( $menu_array['frontend_only'] ) && $menu_array['frontend_only'] ) { array_push( $non_udb_items_id, $menu_id ); } } return $non_udb_items_id; } /** * Parse frontend items with saved menu. * * @param array $saved_menu The saved menu. * @return array */ public function parse_frontend_items( $saved_menu ) { $non_udb_items_id = $this->get_non_udb_items_id_fontend_only( $saved_menu ); $prev_id = ''; $uninserted_items = array(); // Get new items from $this->frontend_menu which are not inside $saved_menu. foreach ( $this->frontend_menu as $menu_id => $menu ) { if ( ! in_array( $menu_id, $non_udb_items_id, true ) ) { $new_item = $menu; if ( isset( $new_item['after'] ) ) { unset( $new_item['after'] ); } if ( isset( $menu['after'] ) && $menu['after'] ) { if ( isset( $saved_menu[ $menu['after'] ] ) ) { $pos = array_search( $menu['after'], array_keys( $saved_menu ), true ); $pos += 1; $saved_menu = array_slice( $saved_menu, 0, $pos, true ) + array( $menu_id => $new_item ) + array_slice( $saved_menu, $pos, count( $saved_menu ) - 1, true ); } else { $uninserted_items[ $menu_id ] = $new_item; } } else { if ( empty( $prev_id ) ) { $saved_menu = array( $menu_id => $new_item ) + $saved_menu; } else { $pos = array_search( $prev_id, array_keys( $saved_menu ), true ); $saved_menu = array_slice( $saved_menu, 0, $pos, true ) + array( $menu_id => $new_item ) + array_slice( $saved_menu, $pos, count( $saved_menu ) - 1, true ); } } } $prev_id = $menu_id; } $saved_menu = $this->insert_uninserted_items( $saved_menu, $uninserted_items, 10 ); return $saved_menu; } /** * Insert un-inserted items to saved menu. * * @param array $saved_menu The saved menu. * @param array $uninserted_items The uninserted items. * @param int $total_loop Max number of the the loop. * * @return array */ public function insert_uninserted_items( $saved_menu, $uninserted_items, $total_loop = 1 ) { for ( $i = 0; $i < $total_loop; $i++ ) { $remaining_items = array(); // Get new items from $uninserted_items which are not inside $saved_menu. foreach ( $uninserted_items as $menu_id => $menu ) { $new_item = $menu; if ( isset( $saved_menu[ $menu['after'] ] ) ) { $pos = array_search( $menu['after'], array_keys( $saved_menu ), true ); $pos += 1; $saved_menu = array_slice( $saved_menu, 0, $pos, true ) + array( $menu_id => $new_item ) + array_slice( $saved_menu, $pos, count( $saved_menu ) - 1, true ); } else { $remaining_items[ $menu_id ] = $new_item; } } if ( empty( $remaining_items ) ) { break; } else { $saved_menu = $this->insert_uninserted_items( $saved_menu, $remaining_items ); } } return $saved_menu; } /** * Turn flat admin bar array to a nested format as needed in menu builder. * * @param array $flat_array The flat array format of admin bar menu. * @return array The nested format as needed in menu builder. */ public function to_builder_format( $flat_array ) { if ( ! $flat_array ) { return array(); } if ( isset( $flat_array['menu-toggle'] ) ) { unset( $flat_array['menu-toggle'] ); } // First, create new site-name item for frontend as "site-name-frontend". $site_name_frontend = array( 'title' => '', 'title_default' => $flat_array['site-name']['title_default'], 'id' => 'site-name-frontend', 'id_default' => 'site-name-frontend', 'parent' => false, 'parent_default' => false, 'href' => '', 'href_default' => admin_url(), 'group' => false, 'group_default' => false, 'meta' => array(), 'meta_default' => array(), 'was_added' => 0, 'is_hidden' => 0, 'frontend_only' => 1, /** * These properties are not being used currently. * But leave it here because in the future, if requested, it would be used for * "hide menu item for specific role(s) & user(s)" functionality (inside dropdowns). */ // 'disallowed_roles' => array(), // 'disallowed_users' => array(), ); $pos = array_search( 'site-name', array_keys( $flat_array ), true ); $pos += 1; // Then place "site-name-frontend" after "site-name". $flat_array = array_slice( $flat_array, 0, $pos, true ) + array( 'site-name-frontend' => $site_name_frontend ) + array_slice( $flat_array, $pos, count( $flat_array ) - 1, true ); $nested_array = array(); /** * Second, collect frontend only items which have "site-name" as the default parent, * change their parent to "site-name-frontend". */ foreach ( $flat_array as $menu_id => $menu ) { if ( isset( $menu['frontend_only'] ) && $menu['frontend_only'] && isset( $menu['parent'] ) && $menu['parent'] && 'site-name' === $menu['parent_default'] ) { $flat_array[ $menu_id ]['parent'] = 'site-name-frontend'; } } // Third, get the parent menu items. foreach ( $flat_array as $menu_id => $menu ) { if ( ! isset( $menu['parent'] ) || ! $menu['parent'] || ! isset( $flat_array[ $menu['parent'] ] ) ) { $nested_array[ $menu_id ] = $menu; $additional = array( 'title_encoded' => htmlentities2( $menu['title'] ), 'title_clean' => wp_strip_all_tags( $menu['title'] ), 'title_default_encoded' => htmlentities2( $menu['title_default'] ), 'title_default_clean' => wp_strip_all_tags( $menu['title_default'] ), 'submenu' => array(), ); $nested_array[ $menu_id ] = array_merge( $nested_array[ $menu_id ], $additional ); } } // Fourth, remove collected parent array from $flat_array. foreach ( $nested_array as $key => $value ) { if ( isset( $flat_array[ $key ] ) ) { unset( $flat_array[ $key ] ); } } // Fifth, get the 1st level submenu items. foreach ( $flat_array as $menu_id => $menu ) { if ( isset( $nested_array[ $menu['parent'] ] ) ) { $nested_array[ $menu['parent'] ]['submenu'][ $menu['id'] ] = $menu; $additional = array( 'title_encoded' => htmlentities2( $menu['title'] ), 'title_clean' => wp_strip_all_tags( $menu['title'] ), 'title_default_encoded' => htmlentities2( $menu['title_default'] ), 'title_default_clean' => wp_strip_all_tags( $menu['title_default'] ), 'submenu' => array(), ); $nested_array[ $menu['parent'] ]['submenu'][ $menu['id'] ] = array_merge( $nested_array[ $menu['parent'] ]['submenu'][ $menu['id'] ], $additional ); unset( $flat_array[ $menu_id ] ); } } // Sixth, get the 2nd level submenu items. if ( ! empty( $flat_array ) ) { // Loop over flat_array. foreach ( $flat_array as $menu_id => $menu ) { // Loop over nested_array. foreach ( $nested_array as $parent_id => $parent_array ) { $submenu_lv2_found = false; if ( ! empty( $parent_array['submenu'] ) ) { // Loop over parent array's submenu. foreach ( $parent_array['submenu'] as $submenu_lv1_id => $submenu_lv1_array ) { if ( $menu['parent'] === $submenu_lv1_id ) { if ( ! isset( $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'] ) ) { $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'] = array(); } $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $menu_id ] = $menu; $additional = array( 'title_encoded' => htmlentities2( $menu['title'] ), 'title_clean' => wp_strip_all_tags( $menu['title'] ), 'title_default_encoded' => htmlentities2( $menu['title_default'] ), 'title_default_clean' => wp_strip_all_tags( $menu['title_default'] ), 'submenu' => array(), ); $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $menu_id ] = array_merge( $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $menu_id ], $additional ); unset( $flat_array[ $menu_id ] ); $submenu_lv2_found = true; break; } } } if ( $submenu_lv2_found ) { break; } } } } // Seventh, get the 3rd level submenu items. if ( ! empty( $flat_array ) ) { // Loop over flat_array. foreach ( $flat_array as $menu_id => $menu ) { // Loop over nested_array. foreach ( $nested_array as $parent_id => $parent_array ) { $submenu_lv3_found = false; if ( ! empty( $parent_array['submenu'] ) ) { // Loop over parent array's submenu. foreach ( $parent_array['submenu'] as $submenu_lv1_id => $submenu_lv1_array ) { if ( ! empty( $submenu_lv1_array['submenu'] ) ) { // Loop over submenu level 1's submenu. foreach ( $submenu_lv1_array['submenu'] as $submenu_lv2_id => $submenu_lv2_array ) { if ( $menu['parent'] === $submenu_lv2_id ) { if ( ! isset( $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $submenu_lv2_id ]['submenu'] ) ) { $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $submenu_lv2_id ]['submenu'] = array(); } $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $submenu_lv2_id ]['submenu'][ $menu_id ] = $menu; $additional = array( 'title_encoded' => htmlentities2( $menu['title'] ), 'title_clean' => wp_strip_all_tags( $menu['title'] ), 'title_default_encoded' => htmlentities2( $menu['title_default'] ), 'title_default_clean' => wp_strip_all_tags( $menu['title_default'] ), 'submenu' => array(), ); $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $submenu_lv2_id ]['submenu'][ $menu_id ] = array_merge( $nested_array[ $parent_id ]['submenu'][ $submenu_lv1_id ]['submenu'][ $submenu_lv2_id ]['submenu'][ $menu_id ], $additional ); unset( $flat_array[ $menu_id ] ); $submenu_lv3_found = true; break; } } } if ( $submenu_lv3_found ) { break; } } } if ( $submenu_lv3_found ) { break; } } } } return $nested_array; } }