Completed
Push — master ( 0e4fe9...f5c78e )
by Fulvio
02:21
created

WP_JSON_Menus::format_menu_item()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 27
Code Lines 20

Duplication

Lines 27
Ratio 100 %
Metric Value
cc 3
eloc 20
nc 2
nop 3
dl 27
loc 27
rs 8.8571
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 23 and the first side effect is on line 9.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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 {
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
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
			// all registered menu locations
44
			$routes['/menu-locations'] = array(
45
				array( array( $this, 'get_menu_locations' ), WP_JSON_Server::READABLE ),
46
			);
47
			// menu for given location
48
			$routes['/menu-locations/(?P<location>[a-zA-Z0-9_-]+)'] = array(
49
				array( array( $this, 'get_menu_location' ), WP_JSON_Server::READABLE ),
50
			);
51
52
			return $routes;
53
		}
54
55
56
		/**
57
		 * Get menus.
58
		 *
59
		 * @since  1.0.0
60
		 * @return array All registered menus
61
		 */
62
		public static function get_menus() {
63
64
			$json_url = get_json_url() . '/menus/';
65
			$wp_menus = wp_get_nav_menus();
66
67
			$i = 0;
68
			$json_menus = array();
69 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...
70
71
				$menu = (array) $wp_menu;
72
73
				$json_menus[ $i ]                 = $menu;
74
				$json_menus[ $i ]['ID']           = $menu['term_id'];
75
				$json_menus[ $i ]['name']         = $menu['name'];
76
				$json_menus[ $i ]['slug']         = $menu['slug'];
77
				$json_menus[ $i ]['description']  = $menu['description'];
78
				$json_menus[ $i ]['count']        = $menu['count'];
79
80
				$json_menus[ $i ]['meta']['links']['collection'] = $json_url;
81
				$json_menus[ $i ]['meta']['links']['self']       = $json_url . $menu['term_id'];
82
83
				$i ++;
84
			endforeach;
85
86
			return $json_menus;
87
		}
88
89
90
		/**
91
		 * Get a menu.
92
		 *
93
		 * @since  1.0.0
94
		 * @param  int   $id ID of the menu
95
		 * @return array Menu data
96
		 */
97
		public function get_menu( $id ) {
98
99
			$json_url       = get_json_url() . '/menus/';
100
			$wp_menu_object = $id ? wp_get_nav_menu_object( $id ) : array();
101
			$wp_menu_items  = $id ? wp_get_nav_menu_items( $id ) : array();
102
103
			$json_menu = array();
104
105 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...
106
107
				$menu = (array) $wp_menu_object;
108
				$json_menu['ID']            = abs( $menu['term_id'] );
109
				$json_menu['name']          = $menu['name'];
110
				$json_menu['slug']          = $menu['slug'];
111
				$json_menu['description']   = $menu['description'];
112
				$json_menu['count']         = abs( $menu['count'] );
113
114
				$json_menu_items = array();
115
				foreach ( $wp_menu_items as $item_object ) {
116
					$json_menu_items[] = $this->format_menu_item( $item_object );
117
				}
118
119
				$json_menu['items']                       = $json_menu_items;
120
				$json_menu['meta']['links']['collection'] = $json_url;
121
				$json_menu['meta']['links']['self']       = $json_url . $id;
122
123
			endif;
124
125
			return $json_menu;
126
		}
127
128
129
		/**
130
		 * Get menu locations.
131
		 *
132
		 * @since  1.0.0
133
		 * @return array All registered menus locations
134
		 */
135 View Code Duplication
		public static function get_menu_locations() {
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...
136
137
			$locations        = get_nav_menu_locations();
138
			$registered_menus = get_registered_nav_menus();
139
			$json_url         = get_json_url() . '/menu-locations/';
140
			$json_menus       = array();
141
142
			if ( $locations && $registered_menus ) :
143
144
				foreach ( $registered_menus as $slug => $label ) :
145
146
					// Sanity check
147
					if ( ! isset( $locations[ $slug ] ) ) {
148
						continue;
149
					}
150
151
					$json_menus[ $slug ]['ID']                          = $locations[ $slug ];
152
					$json_menus[ $slug ]['label']                       = $label;
153
					$json_menus[ $slug ]['meta']['links']['collection'] = $json_url;
154
					$json_menus[ $slug ]['meta']['links']['self']       = $json_url . $slug;
155
156
				endforeach;
157
158
			endif;
159
160
			return $json_menus;
161
		}
162
163
164
		/**
165
		 * Get menu for location.
166
		 *
167
		 * @since  1.0.0
168
		 * @param  string $location The theme location menu name
169
		 * @return array The menu for the corresponding location
170
		 */
171
		public function get_menu_location( $location ) {
172
173
			$locations = get_nav_menu_locations();
174
			if ( ! isset( $locations[ $location ] ) ) {
175
				return array();
176
			}
177
178
			$wp_menu = wp_get_nav_menu_object( $locations[ $location ] );
179
			$menu_items = wp_get_nav_menu_items( $wp_menu->term_id );
180
181
			$sorted_menu_items = $top_level_menu_items = $menu_items_with_children = array();
182
183
			foreach ( (array) $menu_items as $menu_item ) {
184
				$sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
185
			}
186 View Code Duplication
			foreach ( $sorted_menu_items as $menu_item ) {
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...
187
				if ( (int) $menu_item->menu_item_parent !== 0 ) {
188
					$menu_items_with_children[ $menu_item->menu_item_parent ] = true;
189
				} else {
190
					$top_level_menu_items[] = $menu_item;
191
				}
192
			}
193
194
			$menu = array();
195 View Code Duplication
			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...
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...
196
197
				$i = 0;
198
				foreach ( $top_level_menu_items as $top_item ) :
199
200
					$menu[ $i ] = $this->format_menu_item( $top_item, false );
201
					if ( isset( $menu_items_with_children[ $top_item->ID ] ) ) {
202
						$menu[ $i ]['children'] = $this->get_nav_menu_item_children( $top_item->ID, $menu_items, false );
203
					} else {
204
						$menu[ $i ]['children'] = array();
205
					}
206
207
					$i++;
208
				endforeach;
209
210
				break;
211
212
			endwhile;
213
214
			return $menu;
215
		}
216
217
218
		/**
219
		 * Returns all child nav_menu_items under a specific parent.
220
		 *
221
		 * @since  1.1.0
222
		 * @param  int     $parent_id      the parent nav_menu_item ID
223
		 * @param  array   $nav_menu_items navigation menu items
224
		 * @param  bool    $depth          gives all children or direct children only
225
		 * @return array   returns filtered array of nav_menu_items
226
		 */
227 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...
228
229
			$nav_menu_item_list = array();
230
231
			foreach ( (array) $nav_menu_items as $nav_menu_item ) :
232
233
				if ( $nav_menu_item->menu_item_parent == $parent_id ) :
234
235
					$nav_menu_item_list[] = $this->format_menu_item( $nav_menu_item, true, $nav_menu_items );
236
237
					if ( $depth ) {
238
						if ( $children = $this->get_nav_menu_item_children( $nav_menu_item->ID, $nav_menu_items ) ) {
239
							$nav_menu_item_list = array_merge( $nav_menu_item_list, $children );
240
						}
241
					}
242
243
				endif;
244
245
			endforeach;
246
247
			return $nav_menu_item_list;
248
		}
249
250
251
		/**
252
		 * Format a menu item for JSON API consumption.
253
		 *
254
		 * @since   1.1.0
255
		 * @param   object|array    $menu_item  the menu item
256
		 * @param   bool            $children   get menu item children (default false)
257
		 * @param   array           $menu       the menu the item belongs to (used when $children is set to true)
258
		 * @return  array   a formatted menu item for JSON
259
		 */
260 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...
261
262
			$item = (array) $menu_item;
263
264
			$menu_item = array(
265
				'ID'          => abs( $item['ID'] ),
266
				'order'       => (int) $item['menu_order'],
267
				'parent'      => abs( $item['menu_item_parent'] ),
268
				'title'       => $item['title'],
269
				'url'         => $item['url'],
270
				'attr'        => $item['attr_title'],
271
				'target'      => $item['target'],
272
				'classes'     => implode( ' ', $item['classes'] ),
273
				'xfn'         => $item['xfn'],
274
				'description' => $item['description'],
275
				'object_id'   => abs( $item['object_id'] ),
276
				'object'      => $item['object'],
277
				'type'        => $item['type'],
278
				'type_label'  => $item['type_label'],
279
			);
280
281
			if ( $children === true && ! empty( $menu ) ) {
282
				$menu_item['children'] = $this->get_nav_menu_item_children( $item['ID'], $menu );
283
			}
284
285
			return apply_filters( 'json_menus_format_menu_item', $menu_item );
286
		}
287
288
289
	}
290
291
292
endif;
293