1111 * Get all registered menus
1212 * @return array List of menus with slug and description
1313 */
14- function wp_api_v2_menus_get_all_menus () {
15- $ menus = get_terms ('nav_menu ' , array ('hide_empty ' => true ) );
16-
17- foreach ( $ menus as $ key => $ menu ) {
18- // check if there is acf installed
19- if ( class_exists ('acf ' ) ) {
20- $ fields = get_fields ($ menu );
21- if (! empty ($ fields) ) {
22- foreach ( $ fields as $ field_key => $ item ) {
23- // add all acf custom fields
24- $ menus [$ key ]->$ field_key = $ item ;
25- }
26- }
27- }
28- }
29-
30- return $ menus ;
14+ function wp_api_v2_menus_get_all_menus () {
15+ $ menus = get_terms ( 'nav_menu ' , array ( 'hide_empty ' => true ) );
16+
17+ foreach ( $ menus as $ key => $ menu ) {
18+ // check if there is acf installed
19+ if ( class_exists ( 'acf ' ) ) {
20+ $ fields = get_fields ( $ menu );
21+ if ( ! empty ( $ fields ) ) {
22+ foreach ( $ fields as $ field_key => $ item ) {
23+ // add all acf custom fields
24+ $ menus [ $ key ]->$ field_key = $ item ;
25+ }
26+ }
27+ }
28+ }
29+
30+ return $ menus ;
3131}
3232
3333/**
3434 * Get all locations
3535 * @return array List of locations
3636 **/
3737
38- function wp_api_v2_menu_get_all_locations () {
39- $ nav_menu_locations = get_nav_menu_locations ();
40- $ locations = new stdClass ;
41- foreach ($ nav_menu_locations as $ location_slug => $ menu_id ) {
42- if (get_term ($ location_slug ) !== NULL ) {
43- $ locations ->{$ location_slug } = get_term ($ location_slug );
44- } else {
45- $ locations ->{$ location_slug } = new stdClass ;
46- }
47- $ locations ->{$ location_slug }->slug = $ location_slug ;
48- $ locations ->{$ location_slug }->menu = get_term ($ menu_id );
49- }
50- return $ locations ;
38+ function wp_api_v2_menu_get_all_locations () {
39+ $ nav_menu_locations = get_nav_menu_locations ();
40+ $ locations = new stdClass ;
41+ foreach ( $ nav_menu_locations as $ location_slug => $ menu_id ) {
42+ if ( get_term ( $ location_slug ) !== null ) {
43+ $ locations ->{$ location_slug } = get_term ( $ location_slug );
44+ } else {
45+ $ locations ->{$ location_slug } = new stdClass ;
46+ }
47+ $ locations ->{$ location_slug }->slug = $ location_slug ;
48+ $ locations ->{$ location_slug }->menu = get_term ( $ menu_id );
49+ }
50+
51+ return $ locations ;
5152}
5253
5354/**
5455 * Get menu's data from his id
55- * @param array $data WP REST API data variable
56+ *
57+ * @param array $data WP REST API data variable
58+ *
5659 * @return object Menu's data with his items
5760 */
58- function wp_api_v2_locations_get_menu_data ( $ data ) {
59- // Create default empty object
60- $ menu = new stdClass ;
61-
62- // this could be replaced with `if (has_nav_menu($data['id']))`
63- if (($ locations = get_nav_menu_locations ()) && isset ($ locations [$ data ['id ' ]])) {
64- // Replace default empty object with the location object
65- $ menu = get_term ( $ locations [ $ data ['id ' ] ] );
66- $ menu ->items = wp_api_v2_menus_get_menu_items ($ locations [$ data ['id ' ]]);
67- } else {
68- return new WP_Error ( 'not_found ' , 'No location has been found with this id or slug: ` ' .$ data ['id ' ].'`. Please ensure you passed an existing location ID or location slug. ' , array ( 'status ' => 404 ) );
69- }
70-
71- // check if there is acf installed
72- if ( class_exists ('acf ' ) ) {
73- $ fields = get_fields ($ menu );
74- if (!empty ($ fields )) {
75- foreach ($ fields as $ field_key => $ item ) {
76- // add all acf custom fields
77- $ menu ->$ field_key = $ item ;
78- }
79- }
80- }
81-
82- return $ menu ;
61+ function wp_api_v2_locations_get_menu_data ( $ data ) {
62+ // Create default empty object
63+ $ menu = new stdClass ;
64+
65+ // this could be replaced with `if (has_nav_menu($data['id']))`
66+ if ( ( $ locations = get_nav_menu_locations () ) && isset ( $ locations [ $ data ['id ' ] ] ) ) {
67+ // Replace default empty object with the location object
68+ $ menu = get_term ( $ locations [ $ data ['id ' ] ] );
69+ $ menu ->items = wp_api_v2_menus_get_menu_items ( $ locations [ $ data ['id ' ] ] );
70+ } else {
71+ return new WP_Error ( 'not_found ' , 'No location has been found with this id or slug: ` ' . $ data ['id ' ] . '`. Please ensure you passed an existing location ID or location slug. ' , array ( 'status ' => 404 ) );
72+ }
73+
74+ // check if there is acf installed
75+ if ( class_exists ( 'acf ' ) ) {
76+ $ fields = get_fields ( $ menu );
77+ if ( ! empty ( $ fields ) ) {
78+ foreach ( $ fields as $ field_key => $ item ) {
79+ // add all acf custom fields
80+ $ menu ->$ field_key = $ item ;
81+ }
82+ }
83+ }
84+
85+ return $ menu ;
86+ }
87+
88+ /**
89+ * Check if a menu item is child of one of the menu's element passed as reference
90+ *
91+ * @param $parents Menu's items
92+ * @param $child Menu's item to check
93+ *
94+ * @return bool True if the parent is found, false otherwise
95+ */
96+ function wp_api_v2_menus_dna_test ( &$ parents , $ child ) {
97+ foreach ( $ parents as $ key => $ item ) {
98+ if ( $ child ->menu_item_parent == $ item ->ID ) {
99+ if ( ! $ item ->child_items ) {
100+ $ item ->child_items = [];
101+ }
102+ array_push ( $ item ->child_items , $ child );
103+ return true ;
104+ }
105+
106+ if ($ item ->child_items ) {
107+ if (wp_api_v2_menus_dna_test ($ item ->child_items , $ child )) {
108+ return true ;
109+ }
110+ }
111+ }
112+
113+ return false ;
83114}
84115
85116/**
86117 * Retrieve items for a specific menu
118+ *
87119 * @param $id Menu id
120+ *
88121 * @return array List of menu items
89122 */
90- function wp_api_v2_menus_get_menu_items ($ id ) {
91- $ menu_items = wp_get_nav_menu_items ($ id );
92-
93- // wordpress does not group child menu items with parent menu items
94- $ child_items = [];
95- // pull all child menu items into separate object
96- foreach ($ menu_items as $ key => $ item ) {
97- if ($ item ->menu_item_parent ) {
98- array_push ($ child_items , $ item );
99- unset($ menu_items [$ key ]);
100- }
101- }
102-
103- // push child items into their parent item in the original object
104- foreach ($ menu_items as $ item ) {
105- foreach ($ child_items as $ key => $ child ) {
106- if ($ child ->menu_item_parent == $ item ->ID ) {
107- if (!$ item ->child_items ) $ item ->child_items = [];
108- array_push ($ item ->child_items , $ child );
109- unset($ child_items [$ key ]);
110- }
111- }
112- }
113-
114- // check if there is acf installed
115- if (class_exists ('acf ' )) {
116- foreach ($ menu_items as $ menu_key => $ menu_item ) {
117- $ fields = get_fields ($ menu_item ->ID );
118- if (!empty ($ fields )) {
119- foreach ($ fields as $ field_key => $ item ) {
120- // add all acf custom fields
121- $ menu_items [$ menu_key ]->$ field_key = $ item ;
122- }
123- }
124- }
125- }
126- return $ menu_items ;
123+ function wp_api_v2_menus_get_menu_items ( $ id ) {
124+ $ menu_items = wp_get_nav_menu_items ( $ id );
125+
126+ // wordpress does not group child menu items with parent menu items
127+ $ child_items = [];
128+ // pull all child menu items into separate object
129+ foreach ( $ menu_items as $ key => $ item ) {
130+ if ( $ item ->menu_item_parent ) {
131+ array_push ( $ child_items , $ item );
132+ unset( $ menu_items [ $ key ] );
133+ }
134+ }
135+
136+ // push child items into their parent item in the original object
137+ do {
138+ foreach ($ child_items as $ key => $ child_item ) {
139+ if (wp_api_v2_menus_dna_test ($ menu_items , $ child_item )) {
140+ unset($ child_items [$ key ]);
141+ }
142+ }
143+ } while (count ($ child_items ));
144+
145+ // check if there is acf installed
146+ if ( class_exists ( 'acf ' ) ) {
147+ foreach ( $ menu_items as $ menu_key => $ menu_item ) {
148+ $ fields = get_fields ( $ menu_item ->ID );
149+ if ( ! empty ( $ fields ) ) {
150+ foreach ( $ fields as $ field_key => $ item ) {
151+ // add all acf custom fields
152+ $ menu_items [ $ menu_key ]->$ field_key = $ item ;
153+ }
154+ }
155+ }
156+ }
157+
158+ return $ menu_items ;
127159}
128160
129161/**
130162 * Get menu's data from his id.
131163 * It ensures compatibility for previous versions when this endpoint
132164 * was allowing locations id in place of menus id)
133165 *
134- * @param array $data WP REST API data variable
166+ * @param array $data WP REST API data variable
167+ *
135168 * @return object Menu's data with his items
136169 */
137- function wp_api_v2_menus_get_menu_data ( $ data ) {
138- // This ensure retro compatibility with versions `<= 0.5` when this endpoint
139- // was allowing locations id in place of menus id
140- if (has_nav_menu ($ data ['id ' ]) ) {
141- $ menu = wp_api_v2_locations_get_menu_data ($ data );
142- } else if (is_nav_menu ($ data ['id ' ]) ) {
143- if (is_int ($ data ['id ' ]) ) {
144- $ id = $ data ['id ' ];
145- } else {
146- $ id = wp_get_nav_menu_object ($ data ['id ' ]);
147- }
148- $ menu = get_term ($ id );
149- $ menu ->items = wp_api_v2_menus_get_menu_items ($ id );
150- } else {
151- return new WP_Error ( 'not_found ' , 'No menu has been found with this id or slug: ` ' . $ data ['id ' ]. '`. Please ensure you passed an existing menu ID, menu slug, location ID or location slug. ' , array ( 'status ' => 404 ) );
152- }
153-
154- // check if there is acf installed
155- if ( class_exists ('acf ' ) ) {
156- $ fields = get_fields ($ menu );
157- if (! empty ($ fields) ) {
158- foreach ( $ fields as $ field_key => $ item ) {
159- // add all acf custom fields
160- $ menu ->$ field_key = $ item ;
161- }
162- }
163- }
164-
165- return $ menu ;
170+ function wp_api_v2_menus_get_menu_data ( $ data ) {
171+ // This ensure retro compatibility with versions `<= 0.5` when this endpoint
172+ // was allowing locations id in place of menus id
173+ if ( has_nav_menu ( $ data ['id ' ] ) ) {
174+ $ menu = wp_api_v2_locations_get_menu_data ( $ data );
175+ } else if ( is_nav_menu ( $ data ['id ' ] ) ) {
176+ if ( is_int ( $ data ['id ' ] ) ) {
177+ $ id = $ data ['id ' ];
178+ } else {
179+ $ id = wp_get_nav_menu_object ( $ data ['id ' ] );
180+ }
181+ $ menu = get_term ( $ id );
182+ $ menu ->items = wp_api_v2_menus_get_menu_items ( $ id );
183+ } else {
184+ return new WP_Error ( 'not_found ' , 'No menu has been found with this id or slug: ` ' . $ data ['id ' ] . '`. Please ensure you passed an existing menu ID, menu slug, location ID or location slug. ' , array ( 'status ' => 404 ) );
185+ }
186+
187+ // check if there is acf installed
188+ if ( class_exists ( 'acf ' ) ) {
189+ $ fields = get_fields ( $ menu );
190+ if ( ! empty ( $ fields ) ) {
191+ foreach ( $ fields as $ field_key => $ item ) {
192+ // add all acf custom fields
193+ $ menu ->$ field_key = $ item ;
194+ }
195+ }
196+ }
197+
198+ return $ menu ;
166199}
167200
168- add_action ('rest_api_init ' , function () {
169- register_rest_route ('menus/v1 ' , '/menus ' , array (
170- 'methods ' => 'GET ' ,
171- 'callback ' => 'wp_api_v2_menus_get_all_menus ' ,
172- ) );
173-
174- register_rest_route ('menus/v1 ' , '/menus/(?P<id>[a-zA-Z0-9_-]+) ' , array (
175- 'methods ' => 'GET ' ,
176- 'callback ' => 'wp_api_v2_menus_get_menu_data ' ,
177- ) );
178-
179- register_rest_route ('menus/v1 ' , '/locations/(?P<id>[a-zA-Z0-9_-]+) ' , array (
180- 'methods ' => 'GET ' ,
181- 'callback ' => 'wp_api_v2_locations_get_menu_data ' ,
182- ) );
183-
184- register_rest_route ('menus/v1 ' , '/locations ' , array (
185- 'methods ' => 'GET ' ,
186- 'callback ' => 'wp_api_v2_menu_get_all_locations ' ,
187- ) );
188- } );
201+ add_action ( 'rest_api_init ' , function () {
202+ register_rest_route ( 'menus/v1 ' , '/menus ' , array (
203+ 'methods ' => 'GET ' ,
204+ 'callback ' => 'wp_api_v2_menus_get_all_menus ' ,
205+ ) );
206+
207+ register_rest_route ( 'menus/v1 ' , '/menus/(?P<id>[a-zA-Z0-9_-]+) ' , array (
208+ 'methods ' => 'GET ' ,
209+ 'callback ' => 'wp_api_v2_menus_get_menu_data ' ,
210+ ) );
211+
212+ register_rest_route ( 'menus/v1 ' , '/locations/(?P<id>[a-zA-Z0-9_-]+) ' , array (
213+ 'methods ' => 'GET ' ,
214+ 'callback ' => 'wp_api_v2_locations_get_menu_data ' ,
215+ ) );
216+
217+ register_rest_route ( 'menus/v1 ' , '/locations ' , array (
218+ 'methods ' => 'GET ' ,
219+ 'callback ' => 'wp_api_v2_menu_get_all_locations ' ,
220+ ) );
221+ } );
0 commit comments