|
1 <?php |
|
2 /** |
|
3 * WP_Classic_To_Block_Menu_Converter class |
|
4 * |
|
5 * @package WordPress |
|
6 * @since 6.3.0 |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Converts a Classic Menu to Block Menu blocks. |
|
11 * |
|
12 * @since 6.3.0 |
|
13 * @access public |
|
14 */ |
|
15 class WP_Classic_To_Block_Menu_Converter { |
|
16 |
|
17 /** |
|
18 * Converts a Classic Menu to blocks. |
|
19 * |
|
20 * @since 6.3.0 |
|
21 * |
|
22 * @param WP_Term $menu The Menu term object of the menu to convert. |
|
23 * @return string|WP_Error The serialized and normalized parsed blocks on success, |
|
24 * an empty string when there are no menus to convert, |
|
25 * or WP_Error on invalid menu. |
|
26 */ |
|
27 public static function convert( $menu ) { |
|
28 |
|
29 if ( ! is_nav_menu( $menu ) ) { |
|
30 return new WP_Error( |
|
31 'invalid_menu', |
|
32 __( 'The menu provided is not a valid menu.' ) |
|
33 ); |
|
34 } |
|
35 |
|
36 $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); |
|
37 |
|
38 if ( empty( $menu_items ) ) { |
|
39 return ''; |
|
40 } |
|
41 |
|
42 // Set up the $menu_item variables. |
|
43 // Adds the class property classes for the current context, if applicable. |
|
44 _wp_menu_item_classes_by_context( $menu_items ); |
|
45 |
|
46 $menu_items_by_parent_id = static::group_by_parent_id( $menu_items ); |
|
47 |
|
48 $first_menu_item = isset( $menu_items_by_parent_id[0] ) |
|
49 ? $menu_items_by_parent_id[0] |
|
50 : array(); |
|
51 |
|
52 $inner_blocks = static::to_blocks( |
|
53 $first_menu_item, |
|
54 $menu_items_by_parent_id |
|
55 ); |
|
56 |
|
57 return serialize_blocks( $inner_blocks ); |
|
58 } |
|
59 |
|
60 /** |
|
61 * Returns an array of menu items grouped by the id of the parent menu item. |
|
62 * |
|
63 * @since 6.3.0 |
|
64 * |
|
65 * @param array $menu_items An array of menu items. |
|
66 * @return array |
|
67 */ |
|
68 private static function group_by_parent_id( $menu_items ) { |
|
69 $menu_items_by_parent_id = array(); |
|
70 |
|
71 foreach ( $menu_items as $menu_item ) { |
|
72 $menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item; |
|
73 } |
|
74 |
|
75 return $menu_items_by_parent_id; |
|
76 } |
|
77 |
|
78 /** |
|
79 * Turns menu item data into a nested array of parsed blocks |
|
80 * |
|
81 * @since 6.3.0 |
|
82 * |
|
83 * @param array $menu_items An array of menu items that represent |
|
84 * an individual level of a menu. |
|
85 * @param array $menu_items_by_parent_id An array keyed by the id of the |
|
86 * parent menu where each element is an |
|
87 * array of menu items that belong to |
|
88 * that parent. |
|
89 * @return array An array of parsed block data. |
|
90 */ |
|
91 private static function to_blocks( $menu_items, $menu_items_by_parent_id ) { |
|
92 |
|
93 if ( empty( $menu_items ) ) { |
|
94 return array(); |
|
95 } |
|
96 |
|
97 $blocks = array(); |
|
98 |
|
99 foreach ( $menu_items as $menu_item ) { |
|
100 $class_name = ! empty( $menu_item->classes ) ? implode( ' ', (array) $menu_item->classes ) : null; |
|
101 $id = ( null !== $menu_item->object_id && 'custom' !== $menu_item->object ) ? $menu_item->object_id : null; |
|
102 $opens_in_new_tab = null !== $menu_item->target && '_blank' === $menu_item->target; |
|
103 $rel = ( null !== $menu_item->xfn && '' !== $menu_item->xfn ) ? $menu_item->xfn : null; |
|
104 $kind = null !== $menu_item->type ? str_replace( '_', '-', $menu_item->type ) : 'custom'; |
|
105 |
|
106 $block = array( |
|
107 'blockName' => isset( $menu_items_by_parent_id[ $menu_item->ID ] ) ? 'core/navigation-submenu' : 'core/navigation-link', |
|
108 'attrs' => array( |
|
109 'className' => $class_name, |
|
110 'description' => $menu_item->description, |
|
111 'id' => $id, |
|
112 'kind' => $kind, |
|
113 'label' => $menu_item->title, |
|
114 'opensInNewTab' => $opens_in_new_tab, |
|
115 'rel' => $rel, |
|
116 'title' => $menu_item->attr_title, |
|
117 'type' => $menu_item->object, |
|
118 'url' => $menu_item->url, |
|
119 ), |
|
120 ); |
|
121 |
|
122 $block['innerBlocks'] = isset( $menu_items_by_parent_id[ $menu_item->ID ] ) |
|
123 ? static::to_blocks( $menu_items_by_parent_id[ $menu_item->ID ], $menu_items_by_parent_id ) |
|
124 : array(); |
|
125 $block['innerContent'] = array_map( 'serialize_block', $block['innerBlocks'] ); |
|
126 |
|
127 $blocks[] = $block; |
|
128 } |
|
129 |
|
130 return $blocks; |
|
131 } |
|
132 } |