Completed
Pull Request — master (#27)
by
unknown
02:13
created

WP_JSON_Menus::get_menu_locations()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 29
Code Lines 18

Duplication

Lines 18
Ratio 62.07 %

Importance

Changes 9
Bugs 1 Features 1
Metric Value
cc 5
eloc 18
c 9
b 1
f 1
nc 2
nop 0
dl 18
loc 29
rs 8.439
1
<?php
2
/**
3
 * WP JSON API Menu routes
4
 *
5
 * @package WP_API_Menus
6
 */
7
8
if ( ! defined( 'ABSPATH' ) ) {
9
	exit; // Exit if accessed directly
10
}
11
12
if ( ! class_exists( 'WP_JSON_Menus' ) ) :
13
14
15
	/**
16
	 * WP JSON Menus class.
17
	 *
18
	 * WP API Menus support for WP API v1.
19
	 *
20
	 * @package WP_API_Menus
21
	 * @since 1.0.0
22
	 */
23
	class WP_JSON_Menus {
24
25
26
		/**
27
		 * Register menu routes for WP API.
28
		 *
29
		 * @since 1.0.0
30
		 * @param  array $routes Existing routes
31
		 * @return array Modified routes
32
		 */
33
		public function register_routes( $routes ) {
34
35
			// all registered menus
36
			$routes['/menus'] = array(
37
				array( array( $this, 'get_menus' ), WP_JSON_Server::READABLE ),
38
			);
39
			// a specific menu
40
			$routes['/menus/(?P<id>\d+)'] = array(
41
				array( array( $this, 'get_menu' ), WP_JSON_Server::READABLE ),
42
			);
43
			// a specific menu rendered in html
44
			$routes['/menu-html/(?P<id>[a-zA-Z0-9_-]+)'] = array(
45
				array( array( $this, 'get_menu_html' ), WP_JSON_Server::READABLE ),
46
			);
47
			// all registered menu locations
48
			$routes['/menu-locations'] = array(
49
				array( array( $this, 'get_menu_locations' ), WP_JSON_Server::READABLE ),
50
			);
51
			// menu for given location
52
			$routes['/menu-locations/(?P<location>[a-zA-Z0-9_-]+)'] = array(
53
				array( array( $this, 'get_menu_location' ), WP_JSON_Server::READABLE ),
54
			);
55
			// menu for given location rendered in html
56
			$routes['/menu-html-location/(?P<location>[a-zA-Z0-9_-]+)'] = array(
57
				array( array( $this, 'get_menu_html_location' ), WP_JSON_Server::READABLE ),
58
			);
59
60
			return $routes;
61
		}
62
63
64
		/**
65
		 * Get menus.
66
		 *
67
		 * @since  1.0.0
68
		 * @return array All registered menus
69
		 */
70
		public static function get_menus() {
71
72
			$json_url = get_json_url() . '/menus/';
73
			$json_url_base = get_json_url();
74
			$wp_menus = wp_get_nav_menus();
75
76
			$i = 0;
77
			$json_menus = array();
78 View Code Duplication
			foreach ( $wp_menus as $wp_menu ) :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
79
80
				$menu = (array) $wp_menu;
81
82
				$json_menus[ $i ]                 = $menu;
83
				$json_menus[ $i ]['ID']           = $menu['term_id'];
84
				$json_menus[ $i ]['name']         = $menu['name'];
85
				$json_menus[ $i ]['slug']         = $menu['slug'];
86
				$json_menus[ $i ]['description']  = $menu['description'];
87
				$json_menus[ $i ]['count']        = $menu['count'];
88
89
				$json_menus[ $i ]['meta']['links']['collection'] = $json_url;
90
				$json_menus[ $i ]['meta']['links']['self']       = $json_url . $menu['term_id'];
91
				$json_menus[ $i ]['meta']['links']['self']       = $json_url_base . '/menu-html/' . $menu['term_id'];
92
93
				$i ++;
94
			endforeach;
95
96
			return $json_menus;
97
		}
98
99
100
		/**
101
		 * Get a menu.
102
		 *
103
		 * @since  1.0.0
104
		 * @param  int   $id ID of the menu
105
		 * @return array Menu data
106
		 */
107
		public function get_menu( $id ) {
108
109
			$json_url       = get_json_url() . '/menus/';
110
			$wp_menu_object = $id ? wp_get_nav_menu_object( $id ) : array();
111
			$wp_menu_items  = $id ? wp_get_nav_menu_items( $id ) : array();
112
113
			$json_menu = array();
114
115 View Code Duplication
			if ( $wp_menu_object ) :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
117
				$menu = (array) $wp_menu_object;
118
				$json_menu['ID']            = abs( $menu['term_id'] );
119
				$json_menu['name']          = $menu['name'];
120
				$json_menu['slug']          = $menu['slug'];
121
				$json_menu['description']   = $menu['description'];
122
				$json_menu['count']         = abs( $menu['count'] );
123
124
				$json_menu_items = array();
125
				foreach ( $wp_menu_items as $item_object ) {
126
					$json_menu_items[] = $this->format_menu_item( $item_object );
127
				}
128
129
				$json_menu['items']                       = $json_menu_items;
130
				$json_menu['meta']['links']['collection'] = $json_url;
131
				$json_menu['meta']['links']['self']       = $json_url . $id;
132
133
			endif;
134
135
			return $json_menu;
136
		}
137
138
139
		/**
140
		 * Get a menu rendered in html.
141
		 *
142
		 * @since  1.0.0
143
		 * @param  int   $id ID of the menu
0 ignored issues
show
Bug introduced by
There is no parameter named $id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
144
		 * @return array Menu data
145
		 */
146
		public function get_menu_html( $menu_id ) {
147
148
			$json_url_base  = get_json_url();
149
			$wp_menu_object = $menu_id ? wp_get_nav_menu_object( $menu_id ) : array();
150
			$wp_menu_items  = $menu_id ? wp_get_nav_menu_items( $menu_id ) : array();
0 ignored issues
show
Unused Code introduced by
$wp_menu_items is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
151
152
			$json_menu = array();
153
154 View Code Duplication
			if ( $wp_menu_object ) :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
156
				$menu = (array) $wp_menu_object;
157
				$json_menu['ID']            = abs( $menu['term_id'] );
158
				$json_menu['name']          = $menu['name'];
159
				$json_menu['slug']          = $menu['slug'];
160
				$json_menu['description']   = $menu['description'];
161
				$json_menu['count']         = abs( $menu['count'] );
162
163
				ob_start();
164
           			wp_nav_menu( array( 'menu' => $menu_id ) );
165
           		$json_menu['html']=ob_get_clean();
166
167
           		$json_menu['meta']['links']['collection'] = $json_url_base . '/menus/';
168
				$json_menu['meta']['links']['self']       = $json_url_base . '/menu-html/' . $menu_id;
169
170
			endif;
171
172
			return $json_menu;
173
		}
174
175
176
		/**
177
		 * Get menu locations.
178
		 *
179
		 * @since  1.0.0
180
		 * @return array All registered menus locations
181
		 */
182
		public static function get_menu_locations() {
183
184
			$locations        = get_nav_menu_locations();
185
			$registered_menus = get_registered_nav_menus();
186
			$json_url         = get_json_url() . '/menu-locations/';
187
			$json_url_base    = get_json_url();
188
			$json_menus       = array();
189
190 View Code Duplication
			if ( $locations && $registered_menus ) :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
191
192
				foreach ( $registered_menus as $slug => $label ) :
193
194
					// Sanity check
195
					if ( ! isset( $locations[ $slug ] ) ) {
196
						continue;
197
					}
198
199
					$json_menus[ $slug ]['ID']                          = $locations[ $slug ];
200
					$json_menus[ $slug ]['label']                       = $label;
201
					$json_menus[ $slug ]['meta']['links']['collection'] = $json_url;
202
					$json_menus[ $slug ]['meta']['links']['self']       = $json_url . $slug;
203
					$json_menus[ $slug ]['meta']['links']['html']       = $json_url_base . '/menu-html-location/' . $slug;
204
205
				endforeach;
206
207
			endif;
208
209
			return $json_menus;
210
		}
211
212
213
		/**
214
		 * Get menu for location.
215
		 *
216
		 * @since  1.0.0
217
		 * @param  string $location The theme location menu name
218
		 * @return array The menu for the corresponding location
219
		 */
220
		public function get_menu_location( $location ) {
221
222
			$locations = get_nav_menu_locations();
223
			if ( ! isset( $locations[ $location ] ) ) {
224
				return array();
225
			}
226
227
			$wp_menu = wp_get_nav_menu_object( $locations[ $location ] );
228
			$menu_items = wp_get_nav_menu_items( $wp_menu->term_id );
229
230
			$sorted_menu_items = $top_level_menu_items = $menu_items_with_children = array();
231
232
			foreach ( (array) $menu_items as $menu_item ) {
233
				$sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
234
			}
235
			foreach ( $sorted_menu_items as $menu_item ) {
236
				if ( (int) $menu_item->menu_item_parent !== 0 ) {
237
					$menu_items_with_children[ $menu_item->menu_item_parent ] = true;
238
				} else {
239
					$top_level_menu_items[] = $menu_item;
240
				}
241
			}
242
243
			$menu = array();
244
			while ( $sorted_menu_items ) :
0 ignored issues
show
Bug Best Practice introduced by
The expression $sorted_menu_items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
245
246
				$i = 0;
247
				foreach ( $top_level_menu_items as $top_item ) :
248
249
					$menu[ $i ] = $this->format_menu_item( $top_item, false );
250
					if ( isset( $menu_items_with_children[ $top_item->ID ] ) ) {
251
						$menu[ $i ]['children'] = $this->get_nav_menu_item_children( $top_item->ID, $menu_items, false );
252
					} else {
253
						$menu[ $i ]['children'] = array();
254
					}
255
256
					$i++;
257
				endforeach;
258
259
				break;
260
261
			endwhile;
262
263
			return $menu;
264
		}
265
266
		/**
267
		 * Get menu rendered in html for location.
268
		 *
269
		 * @since  1.x.0
270
		 * @param  string $location The theme location menu name
271
		 * @return array The menu for the corresponding location
272
		 */
273
		public static function get_menu_html_location( $location ) {
274
275
			$locations        = get_nav_menu_locations();
276
			if ( ! isset( $locations[ $location ] ) ) {
277
				return array();
278
			}
279
280
			$wp_menu_object = get_term( $locations[$location], 'nav_menu' );
281
			$json_url_base  = get_json_url();
282
283
			$json_menu      = array();
284
285 View Code Duplication
			if ( $wp_menu_object ) :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286
287
				$menu = (array) $wp_menu_object;
288
				$json_menu['ID']            = abs( $menu['term_id'] );
289
				$json_menu['name']          = $menu['name'];
290
				$json_menu['slug']          = $menu['slug'];
291
				$json_menu['location_slug'] = $location;
292
				$json_menu['description']   = $menu['description'];
293
				$json_menu['count']         = abs( $menu['count'] );
294
295
				ob_start();
296
           			wp_nav_menu( array( 'menu' => $location ) );
297
           		$json_menu['html']=ob_get_clean();
298
299
           		$json_menu['meta']['links']['collection'] = $json_url_base . '/menu-locations/';
300
				$json_menu['meta']['links']['self']       = $json_url_base . '/menu-html-location/' . $location;
301
302
			endif;
303
304
			return $json_menu;
305
		}
306
307
308
		/**
309
		 * Returns all child nav_menu_items under a specific parent.
310
		 *
311
		 * @since  1.1.0
312
		 * @param  int     $parent_id      the parent nav_menu_item ID
313
		 * @param  array   $nav_menu_items navigation menu items
314
		 * @param  bool    $depth          gives all children or direct children only
315
		 * @return array   returns filtered array of nav_menu_items
316
		 */
317 View Code Duplication
		public function get_nav_menu_item_children( $parent_id, $nav_menu_items, $depth = true ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
319
			$nav_menu_item_list = array();
320
321
			foreach ( (array) $nav_menu_items as $nav_menu_item ) :
322
323
				if ( $nav_menu_item->menu_item_parent == $parent_id ) :
324
325
					$nav_menu_item_list[] = $this->format_menu_item( $nav_menu_item, true, $nav_menu_items );
326
327
					if ( $depth ) {
328
						if ( $children = $this->get_nav_menu_item_children( $nav_menu_item->ID, $nav_menu_items ) ) {
329
							$nav_menu_item_list = array_merge( $nav_menu_item_list, $children );
330
						}
331
					}
332
333
				endif;
334
335
			endforeach;
336
337
			return $nav_menu_item_list;
338
		}
339
340
341
		/**
342
		 * Format a menu item for JSON API consumption.
343
		 *
344
		 * @since   1.1.0
345
		 * @param   object|array    $menu_item  the menu item
346
		 * @param   bool            $children   get menu item children (default false)
347
		 * @param   array           $menu       the menu the item belongs to (used when $children is set to true)
348
		 * @return  array   a formatted menu item for JSON
349
		 */
350 View Code Duplication
		public function format_menu_item( $menu_item, $children = false, $menu = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
351
352
			$item = (array) $menu_item;
353
354
			$menu_item = array(
355
				'ID'          => abs( $item['ID'] ),
356
				'order'       => (int) $item['menu_order'],
357
				'parent'      => abs( $item['menu_item_parent'] ),
358
				'title'       => $item['title'],
359
				'url'         => $item['url'],
360
				'attr'        => $item['attr_title'],
361
				'target'      => $item['target'],
362
				'classes'     => implode( ' ', $item['classes'] ),
363
				'xfn'         => $item['xfn'],
364
				'description' => $item['description'],
365
				'object_id'   => abs( $item['object_id'] ),
366
				'object'      => $item['object'],
367
				'type'        => $item['type'],
368
				'type_label'  => $item['type_label'],
369
			);
370
371
			if ( $children === true && ! empty( $menu ) ) {
372
				$menu_item['children'] = $this->get_nav_menu_item_children( $item['ID'], $menu );
373
			}
374
375
			return apply_filters( 'json_menus_format_menu_item', $menu_item );
376
		}
377
378
379
	}
380
381
382
endif;
383