'GET', 'callback' => [ __CLASS__, 'get_menus' ], 'permission_callback' => [ __CLASS__, 'can_edit_builder' ], ] ); register_rest_route( 'nyxonn-builder/v1', '/menus/(?P\d+)/items', [ 'methods' => 'GET', 'callback' => [ __CLASS__, 'get_menu_items' ], 'permission_callback' => [ __CLASS__, 'can_edit_builder' ], ] ); } public static function can_edit_builder() { return class_exists( Role_Manager::class ) && Role_Manager::can_use_builder(); } public static function get_menus() { $menus = wp_get_nav_menus( [ 'hide_empty' => false, ] ); $data = []; foreach ( $menus as $menu ) { $data[] = [ 'id' => intval( $menu->term_id ), 'name' => esc_html( $menu->name ), 'slug' => sanitize_title( $menu->slug ), ]; } return rest_ensure_response( [ 'success' => true, 'menus' => $data, ] ); } public static function get_menu_items( \WP_REST_Request $request ) { $menu_id = intval( $request->get_param( 'id' ) ); if ( ! $menu_id ) { return rest_ensure_response( [ 'success' => true, 'items' => [], ] ); } $items = wp_get_nav_menu_items( $menu_id, [ 'update_post_term_cache' => false, ] ); if ( ! is_array( $items ) ) { $items = []; } usort( $items, function ( $a, $b ) { $a_order = isset( $a->menu_order ) ? intval( $a->menu_order ) : 0; $b_order = isset( $b->menu_order ) ? intval( $b->menu_order ) : 0; return $a_order <=> $b_order; } ); $nodes = []; foreach ( $items as $item ) { $id = intval( $item->ID ?? 0 ); if ( ! $id ) { continue; } $nodes[ $id ] = [ 'id' => $id, 'parent' => intval( $item->menu_item_parent ?? 0 ), 'title' => esc_html( $item->title ?? '' ), 'url' => esc_url_raw( $item->url ?? '' ), 'target' => esc_attr( $item->target ?? '' ), 'classes' => array_values( array_filter( array_map( 'sanitize_html_class', is_array( $item->classes ?? null ) ? $item->classes : [] ) ) ), 'children' => [], ]; } $tree = []; foreach ( $nodes as $id => $node ) { $parent = intval( $node['parent'] ); if ( $parent && isset( $nodes[ $parent ] ) ) { $nodes[ $parent ]['children'][] = $id; } else { $tree[] = $id; } } $build = function ( $id ) use ( &$build, $nodes ) { if ( ! isset( $nodes[ $id ] ) ) { return null; } $entry = $nodes[ $id ]; $children = []; foreach ( $entry['children'] as $child_id ) { $child = $build( $child_id ); if ( $child ) { $children[] = $child; } } return [ 'id' => $entry['id'], 'title' => $entry['title'], 'url' => $entry['url'], 'target' => $entry['target'], 'classes' => $entry['classes'], 'children' => $children, ]; }; $output = []; foreach ( $tree as $root_id ) { $entry = $build( $root_id ); if ( $entry ) { $output[] = $entry; } } return rest_ensure_response( [ 'success' => true, 'items' => $output, ] ); } }