Issues (4967)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/wp-admin/nav-menus.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * WordPress Administration for Navigation Menus
4
 * Interface functions
5
 *
6
 * @version 2.0.0
7
 *
8
 * @package WordPress
9
 * @subpackage Administration
10
 */
11
12
/** Load WordPress Administration Bootstrap */
13
require_once( dirname( __FILE__ ) . '/admin.php' );
14
15
// Load all the nav menu interface functions
16
require_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
17
18
if ( ! current_theme_supports( 'menus' ) && ! current_theme_supports( 'widgets' ) )
19
	wp_die( __( 'Your theme does not support navigation menus or widgets.' ) );
20
21
// Permissions Check
22
if ( ! current_user_can( 'edit_theme_options' ) ) {
23
	wp_die(
24
		'<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
25
		'<p>' . __( 'Sorry, you are not allowed to edit theme options on this site.' ) . '</p>',
26
		403
27
	);
28
}
29
30
wp_enqueue_script( 'nav-menu' );
31
32
if ( wp_is_mobile() )
33
	wp_enqueue_script( 'jquery-touch-punch' );
34
35
// Container for any messages displayed to the user
36
$messages = array();
37
38
// Container that stores the name of the active menu
39
$nav_menu_selected_title = '';
40
41
// The menu id of the current menu being edited
42
$nav_menu_selected_id = isset( $_REQUEST['menu'] ) ? (int) $_REQUEST['menu'] : 0;
43
44
// Get existing menu locations assignments
45
$locations = get_registered_nav_menus();
46
$menu_locations = get_nav_menu_locations();
47
$num_locations = count( array_keys( $locations ) );
48
49
// Allowed actions: add, update, delete
50
$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit';
51
52
/*
53
 * If a JSON blob of navigation menu data is found, expand it and inject it
54
 * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
55
 */
56
_wp_expand_nav_menu_post_data();
57
58
switch ( $action ) {
59
	case 'add-menu-item':
60
		check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
61
		if ( isset( $_REQUEST['nav-menu-locations'] ) )
62
			set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_REQUEST['menu-locations'] ) );
63
		elseif ( isset( $_REQUEST['menu-item'] ) )
64
			wp_save_nav_menu_items( $nav_menu_selected_id, $_REQUEST['menu-item'] );
65
		break;
66
	case 'move-down-menu-item' :
67
68
		// Moving down a menu item is the same as moving up the next in order.
69
		check_admin_referer( 'move-menu_item' );
70
		$menu_item_id = isset( $_REQUEST['menu-item'] ) ? (int) $_REQUEST['menu-item'] : 0;
71
		if ( is_nav_menu_item( $menu_item_id ) ) {
72
			$menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
73
			if ( ! is_wp_error( $menus ) && ! empty( $menus[0] ) ) {
74
				$menu_id = (int) $menus[0];
75
				$ordered_menu_items = wp_get_nav_menu_items( $menu_id );
76
				$menu_item_data = (array) wp_setup_nav_menu_item( get_post( $menu_item_id ) );
77
78
				// Set up the data we need in one pass through the array of menu items.
79
				$dbids_to_orders = array();
80
				$orders_to_dbids = array();
81 View Code Duplication
				foreach ( (array) $ordered_menu_items as $ordered_menu_item_object ) {
82
					if ( isset( $ordered_menu_item_object->ID ) ) {
83
						if ( isset( $ordered_menu_item_object->menu_order ) ) {
84
							$dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
85
							$orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
86
						}
87
					}
88
				}
89
90
				// Get next in order.
91
				if (
92
					isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] + 1] )
93
				) {
94
					$next_item_id = $orders_to_dbids[$dbids_to_orders[$menu_item_id] + 1];
95
					$next_item_data = (array) wp_setup_nav_menu_item( get_post( $next_item_id ) );
96
97
					// If not siblings of same parent, bubble menu item up but keep order.
98
					if (
99
						! empty( $menu_item_data['menu_item_parent'] ) &&
100
						(
101
							empty( $next_item_data['menu_item_parent'] ) ||
102
							$next_item_data['menu_item_parent'] != $menu_item_data['menu_item_parent']
103
						)
104
					) {
105
106
						$parent_db_id = in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids ) ? (int) $menu_item_data['menu_item_parent'] : 0;
107
108
						$parent_object = wp_setup_nav_menu_item( get_post( $parent_db_id ) );
0 ignored issues
show
It seems like get_post($parent_db_id) targeting get_post() can also be of type array or null; however, wp_setup_nav_menu_item() does only seem to accept object, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
109
110
						if ( ! is_wp_error( $parent_object ) ) {
111
							$parent_data = (array) $parent_object;
112
							$menu_item_data['menu_item_parent'] = $parent_data['menu_item_parent'];
113
							update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
114
115
						}
116
117
					// Make menu item a child of its next sibling.
118
					} else {
119
						$next_item_data['menu_order'] = $next_item_data['menu_order'] - 1;
120
						$menu_item_data['menu_order'] = $menu_item_data['menu_order'] + 1;
121
122
						$menu_item_data['menu_item_parent'] = $next_item_data['ID'];
123
						update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
124
125
						wp_update_post($menu_item_data);
126
						wp_update_post($next_item_data);
127
					}
128
129
				// The item is last but still has a parent, so bubble up.
130
				} elseif (
131
					! empty( $menu_item_data['menu_item_parent'] ) &&
132
					in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids )
133
				) {
134
					$menu_item_data['menu_item_parent'] = (int) get_post_meta( $menu_item_data['menu_item_parent'], '_menu_item_menu_item_parent', true);
135
					update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
136
				}
137
			}
138
		}
139
140
		break;
141
	case 'move-up-menu-item' :
142
		check_admin_referer( 'move-menu_item' );
143
		$menu_item_id = isset( $_REQUEST['menu-item'] ) ? (int) $_REQUEST['menu-item'] : 0;
144
		if ( is_nav_menu_item( $menu_item_id ) ) {
145
			$menus = isset( $_REQUEST['menu'] ) ? array( (int) $_REQUEST['menu'] ) : wp_get_object_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) );
146
			if ( ! is_wp_error( $menus ) && ! empty( $menus[0] ) ) {
147
				$menu_id = (int) $menus[0];
148
				$ordered_menu_items = wp_get_nav_menu_items( $menu_id );
149
				$menu_item_data = (array) wp_setup_nav_menu_item( get_post( $menu_item_id ) );
150
151
				// Set up the data we need in one pass through the array of menu items.
152
				$dbids_to_orders = array();
153
				$orders_to_dbids = array();
154 View Code Duplication
				foreach ( (array) $ordered_menu_items as $ordered_menu_item_object ) {
155
					if ( isset( $ordered_menu_item_object->ID ) ) {
156
						if ( isset( $ordered_menu_item_object->menu_order ) ) {
157
							$dbids_to_orders[$ordered_menu_item_object->ID] = $ordered_menu_item_object->menu_order;
158
							$orders_to_dbids[$ordered_menu_item_object->menu_order] = $ordered_menu_item_object->ID;
159
						}
160
					}
161
				}
162
163
				// If this menu item is not first.
164
				if ( ! empty( $dbids_to_orders[$menu_item_id] ) && ! empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ) {
165
166
					// If this menu item is a child of the previous.
167
					if (
168
						! empty( $menu_item_data['menu_item_parent'] ) &&
169
						in_array( $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ) ) &&
170
						isset( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) &&
171
						( $menu_item_data['menu_item_parent'] == $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] )
172
					) {
173
						$parent_db_id = in_array( $menu_item_data['menu_item_parent'], $orders_to_dbids ) ? (int) $menu_item_data['menu_item_parent'] : 0;
174
						$parent_object = wp_setup_nav_menu_item( get_post( $parent_db_id ) );
0 ignored issues
show
It seems like get_post($parent_db_id) targeting get_post() can also be of type array or null; however, wp_setup_nav_menu_item() does only seem to accept object, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
175
176
						if ( ! is_wp_error( $parent_object ) ) {
177
							$parent_data = (array) $parent_object;
178
179
							/*
180
							 * If there is something before the parent and parent a child of it,
181
							 * make menu item a child also of it.
182
							 */
183
							if (
184
								! empty( $dbids_to_orders[$parent_db_id] ) &&
185
								! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] ) &&
186
								! empty( $parent_data['menu_item_parent'] )
187
							) {
188
								$menu_item_data['menu_item_parent'] = $parent_data['menu_item_parent'];
189
190
							/*
191
							 * Else if there is something before parent and parent not a child of it,
192
							 * make menu item a child of that something's parent
193
							 */
194
							} elseif (
195
								! empty( $dbids_to_orders[$parent_db_id] ) &&
196
								! empty( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1] )
197
							) {
198
								$_possible_parent_id = (int) get_post_meta( $orders_to_dbids[$dbids_to_orders[$parent_db_id] - 1], '_menu_item_menu_item_parent', true);
199
								if ( in_array( $_possible_parent_id, array_keys( $dbids_to_orders ) ) )
200
									$menu_item_data['menu_item_parent'] = $_possible_parent_id;
201
								else
202
									$menu_item_data['menu_item_parent'] = 0;
203
204
							// Else there isn't something before the parent.
205
							} else {
206
								$menu_item_data['menu_item_parent'] = 0;
207
							}
208
209
							// Set former parent's [menu_order] to that of menu-item's.
210
							$parent_data['menu_order'] = $parent_data['menu_order'] + 1;
211
212
							// Set menu-item's [menu_order] to that of former parent.
213
							$menu_item_data['menu_order'] = $menu_item_data['menu_order'] - 1;
214
215
							// Save changes.
216
							update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
217
							wp_update_post($menu_item_data);
218
							wp_update_post($parent_data);
219
						}
220
221
					// Else this menu item is not a child of the previous.
222
					} elseif (
223
						empty( $menu_item_data['menu_order'] ) ||
224
						empty( $menu_item_data['menu_item_parent'] ) ||
225
						! in_array( $menu_item_data['menu_item_parent'], array_keys( $dbids_to_orders ) ) ||
226
						empty( $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] ) ||
227
						$orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1] != $menu_item_data['menu_item_parent']
228
					) {
229
						// Just make it a child of the previous; keep the order.
230
						$menu_item_data['menu_item_parent'] = (int) $orders_to_dbids[$dbids_to_orders[$menu_item_id] - 1];
231
						update_post_meta( $menu_item_data['ID'], '_menu_item_menu_item_parent', (int) $menu_item_data['menu_item_parent'] );
232
						wp_update_post($menu_item_data);
233
					}
234
				}
235
			}
236
		}
237
		break;
238
239
	case 'delete-menu-item':
240
		$menu_item_id = (int) $_REQUEST['menu-item'];
241
242
		check_admin_referer( 'delete-menu_item_' . $menu_item_id );
243
244
		if ( is_nav_menu_item( $menu_item_id ) && wp_delete_post( $menu_item_id, true ) )
245
			$messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __('The menu item has been successfully deleted.') . '</p></div>';
246
		break;
247
248
	case 'delete':
249
		check_admin_referer( 'delete-nav_menu-' . $nav_menu_selected_id );
250
		if ( is_nav_menu( $nav_menu_selected_id ) ) {
251
			$deletion = wp_delete_nav_menu( $nav_menu_selected_id );
252
		} else {
253
			// Reset the selected menu.
254
			$nav_menu_selected_id = 0;
255
			unset( $_REQUEST['menu'] );
256
		}
257
258
		if ( ! isset( $deletion ) )
259
			break;
260
261
		if ( is_wp_error( $deletion ) )
262
			$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . $deletion->get_error_message() . '</p></div>';
263
		else
264
			$messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'The menu has been successfully deleted.' ) . '</p></div>';
265
		break;
266
267
	case 'delete_menus':
268
		check_admin_referer( 'nav_menus_bulk_actions' );
269
		foreach ( $_REQUEST['delete_menus'] as $menu_id_to_delete ) {
270
			if ( ! is_nav_menu( $menu_id_to_delete ) )
271
				continue;
272
273
			$deletion = wp_delete_nav_menu( $menu_id_to_delete );
274
			if ( is_wp_error( $deletion ) ) {
275
				$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . $deletion->get_error_message() . '</p></div>';
276
				$deletion_error = true;
277
			}
278
		}
279
280
		if ( empty( $deletion_error ) )
281
			$messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'Selected menus have been successfully deleted.' ) . '</p></div>';
282
		break;
283
284
	case 'update':
285
		check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
286
287
		// Remove menu locations that have been unchecked.
288
		foreach ( $locations as $location => $description ) {
289
			if ( ( empty( $_POST['menu-locations'] ) || empty( $_POST['menu-locations'][ $location ] ) ) && isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id )
290
				unset( $menu_locations[ $location ] );
291
		}
292
293
		// Merge new and existing menu locations if any new ones are set.
294
		if ( isset( $_POST['menu-locations'] ) ) {
295
			$new_menu_locations = array_map( 'absint', $_POST['menu-locations'] );
296
			$menu_locations = array_merge( $menu_locations, $new_menu_locations );
297
		}
298
299
		// Set menu locations.
300
		set_theme_mod( 'nav_menu_locations', $menu_locations );
301
302
		// Add Menu.
303
		if ( 0 == $nav_menu_selected_id ) {
304
			$new_menu_title = trim( esc_html( $_POST['menu-name'] ) );
305
306
			if ( $new_menu_title ) {
307
				$_nav_menu_selected_id = wp_update_nav_menu_object( 0, array('menu-name' => $new_menu_title) );
308
309
				if ( is_wp_error( $_nav_menu_selected_id ) ) {
310
					$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . $_nav_menu_selected_id->get_error_message() . '</p></div>';
0 ignored issues
show
The method get_error_message does only exist in WP_Error, but not in WP_Term.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
311
				} else {
312
					$_menu_object = wp_get_nav_menu_object( $_nav_menu_selected_id );
313
					$nav_menu_selected_id = $_nav_menu_selected_id;
314
					$nav_menu_selected_title = $_menu_object->name;
315
					if ( isset( $_REQUEST['menu-item'] ) )
316
						wp_save_nav_menu_items( $nav_menu_selected_id, absint( $_REQUEST['menu-item'] ) );
317
					if ( isset( $_REQUEST['zero-menu-state'] ) ) {
318
						// If there are menu items, add them
319
						wp_nav_menu_update_menu_items( $nav_menu_selected_id, $nav_menu_selected_title );
320
						// Auto-save nav_menu_locations
321
						$locations = get_nav_menu_locations();
322
						foreach ( $locations as $location => $menu_id ) {
323
								$locations[ $location ] = $nav_menu_selected_id;
324
								break; // There should only be 1
325
						}
326
						set_theme_mod( 'nav_menu_locations', $locations );
327
					}
328
					if ( isset( $_REQUEST['use-location'] ) ) {
329
						$locations = get_registered_nav_menus();
330
						$menu_locations = get_nav_menu_locations();
331
						if ( isset( $locations[ $_REQUEST['use-location'] ] ) )
332
							$menu_locations[ $_REQUEST['use-location'] ] = $nav_menu_selected_id;
333
						set_theme_mod( 'nav_menu_locations', $menu_locations );
334
					}
335
336
					// $messages[] = '<div id="message" class="updated"><p>' . sprintf( __( '<strong>%s</strong> has been created.' ), $nav_menu_selected_title ) . '</p></div>';
337
					wp_redirect( admin_url( 'nav-menus.php?menu=' . $_nav_menu_selected_id ) );
338
					exit();
339
				}
340
			} else {
341
				$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>';
342
			}
343
344
		// Update existing menu.
345
		} else {
346
347
			$_menu_object = wp_get_nav_menu_object( $nav_menu_selected_id );
348
349
			$menu_title = trim( esc_html( $_POST['menu-name'] ) );
350
			if ( ! $menu_title ) {
351
				$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>';
352
				$menu_title = $_menu_object->name;
353
			}
354
355
			if ( ! is_wp_error( $_menu_object ) ) {
356
				$_nav_menu_selected_id = wp_update_nav_menu_object( $nav_menu_selected_id, array( 'menu-name' => $menu_title ) );
357
				if ( is_wp_error( $_nav_menu_selected_id ) ) {
358
					$_menu_object = $_nav_menu_selected_id;
359
					$messages[] = '<div id="message" class="error notice is-dismissible"><p>' . $_nav_menu_selected_id->get_error_message() . '</p></div>';
360
				} else {
361
					$_menu_object = wp_get_nav_menu_object( $_nav_menu_selected_id );
362
					$nav_menu_selected_title = $_menu_object->name;
363
				}
364
			}
365
366
			// Update menu items.
367
			if ( ! is_wp_error( $_menu_object ) ) {
368
				$messages = array_merge( $messages, wp_nav_menu_update_menu_items( $_nav_menu_selected_id, $nav_menu_selected_title ) );
369
370
				// If the menu ID changed, redirect to the new URL.
371
				if ( $nav_menu_selected_id != $_nav_menu_selected_id ) {
372
					wp_redirect( admin_url( 'nav-menus.php?menu=' . intval( $_nav_menu_selected_id ) ) );
373
					exit();
374
				}
375
			}
376
		}
377
		break;
378
	case 'locations':
379
		if ( ! $num_locations ) {
380
			wp_redirect( admin_url( 'nav-menus.php' ) );
381
			exit();
382
		}
383
384
		add_filter( 'screen_options_show_screen', '__return_false' );
385
386
		if ( isset( $_POST['menu-locations'] ) ) {
387
			check_admin_referer( 'save-menu-locations' );
388
389
			$new_menu_locations = array_map( 'absint', $_POST['menu-locations'] );
390
			$menu_locations = array_merge( $menu_locations, $new_menu_locations );
391
			// Set menu locations
392
			set_theme_mod( 'nav_menu_locations', $menu_locations );
393
394
			$messages[] = '<div id="message" class="updated notice is-dismissible"><p>' . __( 'Menu locations updated.' ) . '</p></div>';
395
		}
396
		break;
397
}
398
399
// Get all nav menus.
400
$nav_menus = wp_get_nav_menus();
401
$menu_count = count( $nav_menus );
402
403
// Are we on the add new screen?
404
$add_new_screen = ( isset( $_GET['menu'] ) && 0 == $_GET['menu'] ) ? true : false;
405
406
$locations_screen = ( isset( $_GET['action'] ) && 'locations' == $_GET['action'] ) ? true : false;
407
408
/*
409
 * If we have one theme location, and zero menus, we take them right
410
 * into editing their first menu.
411
 */
412
$page_count = wp_count_posts( 'page' );
413
$one_theme_location_no_menus = ( 1 == count( get_registered_nav_menus() ) && ! $add_new_screen && empty( $nav_menus ) && ! empty( $page_count->publish ) ) ? true : false;
414
415
$nav_menus_l10n = array(
416
	'oneThemeLocationNoMenus' => $one_theme_location_no_menus,
417
	'moveUp'       => __( 'Move up one' ),
418
	'moveDown'     => __( 'Move down one' ),
419
	'moveToTop'    => __( 'Move to the top' ),
420
	/* translators: %s: previous item name */
421
	'moveUnder'    => __( 'Move under %s' ),
422
	/* translators: %s: previous item name */
423
	'moveOutFrom'  => __( 'Move out from under %s' ),
424
	/* translators: %s: previous item name */
425
	'under'        => __( 'Under %s' ),
426
	/* translators: %s: previous item name */
427
	'outFrom'      => __( 'Out from under %s' ),
428
	/* translators: 1: item name, 2: item position, 3: total number of items */
429
	'menuFocus'    => __( '%1$s. Menu item %2$d of %3$d.' ),
430
	/* translators: 1: item name, 2: item position, 3: parent item name */
431
	'subMenuFocus' => __( '%1$s. Sub item number %2$d under %3$s.' ),
432
);
433
wp_localize_script( 'nav-menu', 'menus', $nav_menus_l10n );
434
435
/*
436
 * Redirect to add screen if there are no menus and this users has either zero,
437
 * or more than 1 theme locations.
438
 */
439
if ( 0 == $menu_count && ! $add_new_screen && ! $one_theme_location_no_menus )
440
	wp_redirect( admin_url( 'nav-menus.php?action=edit&menu=0' ) );
441
442
// Get recently edited nav menu.
443
$recently_edited = absint( get_user_option( 'nav_menu_recently_edited' ) );
444
if ( empty( $recently_edited ) && is_nav_menu( $nav_menu_selected_id ) )
445
	$recently_edited = $nav_menu_selected_id;
446
447
// Use $recently_edited if none are selected.
448
if ( empty( $nav_menu_selected_id ) && ! isset( $_GET['menu'] ) && is_nav_menu( $recently_edited ) )
449
	$nav_menu_selected_id = $recently_edited;
450
451
// On deletion of menu, if another menu exists, show it.
452
if ( ! $add_new_screen && 0 < $menu_count && isset( $_GET['action'] ) && 'delete' == $_GET['action'] )
453
	$nav_menu_selected_id = $nav_menus[0]->term_id;
454
455
// Set $nav_menu_selected_id to 0 if no menus.
456
if ( $one_theme_location_no_menus ) {
457
	$nav_menu_selected_id = 0;
458
} elseif ( empty( $nav_menu_selected_id ) && ! empty( $nav_menus ) && ! $add_new_screen ) {
459
	// if we have no selection yet, and we have menus, set to the first one in the list.
460
	$nav_menu_selected_id = $nav_menus[0]->term_id;
461
}
462
463
// Update the user's setting.
464
if ( $nav_menu_selected_id != $recently_edited && is_nav_menu( $nav_menu_selected_id ) )
465
	update_user_meta( $current_user->ID, 'nav_menu_recently_edited', $nav_menu_selected_id );
466
467
// If there's a menu, get its name.
468
if ( ! $nav_menu_selected_title && is_nav_menu( $nav_menu_selected_id ) ) {
469
	$_menu_object = wp_get_nav_menu_object( $nav_menu_selected_id );
470
	$nav_menu_selected_title = ! is_wp_error( $_menu_object ) ? $_menu_object->name : '';
471
}
472
473
// Generate truncated menu names.
474
foreach ( (array) $nav_menus as $key => $_nav_menu ) {
475
	$nav_menus[$key]->truncated_name = wp_html_excerpt( $_nav_menu->name, 40, '&hellip;' );
476
}
477
478
// Retrieve menu locations.
479
if ( current_theme_supports( 'menus' ) ) {
480
	$locations = get_registered_nav_menus();
481
	$menu_locations = get_nav_menu_locations();
482
}
483
484
/*
485
 * Ensure the user will be able to scroll horizontally
486
 * by adding a class for the max menu depth.
487
 *
488
 * @global int $_wp_nav_menu_max_depth
489
 */
490
global $_wp_nav_menu_max_depth;
491
$_wp_nav_menu_max_depth = 0;
492
493
// Calling wp_get_nav_menu_to_edit generates $_wp_nav_menu_max_depth.
494
if ( is_nav_menu( $nav_menu_selected_id ) ) {
495
	$menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array( 'post_status' => 'any' ) );
496
	$edit_markup = wp_get_nav_menu_to_edit( $nav_menu_selected_id );
497
}
498
499
/**
500
 *
501
 * @global int $_wp_nav_menu_max_depth
502
 *
503
 * @param string $classes
504
 * @return string
505
 */
506
function wp_nav_menu_max_depth( $classes ) {
507
	global $_wp_nav_menu_max_depth;
508
	return "$classes menu-max-depth-$_wp_nav_menu_max_depth";
509
}
510
511
add_filter('admin_body_class', 'wp_nav_menu_max_depth');
512
513
wp_nav_menu_setup();
514
wp_initial_nav_menu_meta_boxes();
515
516
if ( ! current_theme_supports( 'menus' ) && ! $num_locations )
517
	$messages[] = '<div id="message" class="updated"><p>' . sprintf( __( 'Your theme does not natively support menus, but you can use them in sidebars by adding a &#8220;Custom Menu&#8221; widget on the <a href="%s">Widgets</a> screen.' ), admin_url( 'widgets.php' ) ) . '</p></div>';
518
519
if ( ! $locations_screen ) : // Main tab
520
	$overview  = '<p>' . __( 'This screen is used for managing your custom navigation menus.' ) . '</p>';
521
	/* translators: 1: Widgets admin screen URL, 2 and 3: The name of the default themes */
522
	$overview .= '<p>' . sprintf( __( 'Menus can be displayed in locations defined by your theme, even used in sidebars by adding a &#8220;Custom Menu&#8221; widget on the <a href="%1$s">Widgets</a> screen. If your theme does not support the custom menus feature (the default themes, %2$s and %3$s, do), you can learn about adding this support by following the Documentation link to the side.' ), admin_url( 'widgets.php' ), 'Twenty Sixteen', 'Twenty Seventeen' ) . '</p>';
523
	$overview .= '<p>' . __( 'From this screen you can:' ) . '</p>';
524
	$overview .= '<ul><li>' . __( 'Create, edit, and delete menus' ) . '</li>';
525
	$overview .= '<li>' . __( 'Add, organize, and modify individual menu items' ) . '</li></ul>';
526
527
	get_current_screen()->add_help_tab( array(
528
		'id'      => 'overview',
529
		'title'   => __( 'Overview' ),
530
		'content' => $overview
531
	) );
532
533
	$menu_management  = '<p>' . __( 'The menu management box at the top of the screen is used to control which menu is opened in the editor below.' ) . '</p>';
534
	$menu_management .= '<ul><li>' . __( 'To edit an existing menu, <strong>choose a menu from the drop down and click Select</strong>' ) . '</li>';
535
	$menu_management .= '<li>' . __( 'If you haven&#8217;t yet created any menus, <strong>click the &#8217;create a new menu&#8217; link</strong> to get started' ) . '</li></ul>';
536
	$menu_management .= '<p>' . __( 'You can assign theme locations to individual menus by <strong>selecting the desired settings</strong> at the bottom of the menu editor. To assign menus to all theme locations at once, <strong>visit the Manage Locations tab</strong> at the top of the screen.' ) . '</p>';
537
538
	get_current_screen()->add_help_tab( array(
539
		'id'      => 'menu-management',
540
		'title'   => __( 'Menu Management' ),
541
		'content' => $menu_management
542
	) );
543
544
	$editing_menus  = '<p>' . __( 'Each custom menu may contain a mix of links to pages, categories, custom URLs or other content types. Menu links are added by selecting items from the expanding boxes in the left-hand column below.' ) . '</p>';
545
	$editing_menus .= '<p>' . __( '<strong>Clicking the arrow to the right of any menu item</strong> in the editor will reveal a standard group of settings. Additional settings such as link target, CSS classes, link relationships, and link descriptions can be enabled and disabled via the Screen Options tab.' ) . '</p>';
546
	$editing_menus .= '<ul><li>' . __( 'Add one or several items at once by <strong>selecting the checkbox next to each item and clicking Add to Menu</strong>' ) . '</li>';
547
	$editing_menus .= '<li>' . __( 'To add a custom link, <strong>expand the Custom Links section, enter a URL and link text, and click Add to Menu</strong>' ) .'</li>';
548
	$editing_menus .= '<li>' . __( 'To reorganize menu items, <strong>drag and drop items with your mouse or use your keyboard</strong>. Drag or move a menu item a little to the right to make it a submenu' ) . '</li>';
549
	$editing_menus .= '<li>' . __( 'Delete a menu item by <strong>expanding it and clicking the Remove link</strong>' ) . '</li></ul>';
550
551
	get_current_screen()->add_help_tab( array(
552
		'id'      => 'editing-menus',
553
		'title'   => __( 'Editing Menus' ),
554
		'content' => $editing_menus
555
	) );
556
else : // Locations Tab.
557
	$locations_overview  = '<p>' . __( 'This screen is used for globally assigning menus to locations defined by your theme.' ) . '</p>';
558
	$locations_overview .= '<ul><li>' . __( 'To assign menus to one or more theme locations, <strong>select a menu from each location&#8217;s drop down.</strong> When you&#8217;re finished, <strong>click Save Changes</strong>' ) . '</li>';
559
	$locations_overview .= '<li>' . __( 'To edit a menu currently assigned to a theme location, <strong>click the adjacent &#8217;Edit&#8217; link</strong>' ) . '</li>';
560
	$locations_overview .= '<li>' . __( 'To add a new menu instead of assigning an existing one, <strong>click the &#8217;Use new menu&#8217; link</strong>. Your new menu will be automatically assigned to that theme location' ) . '</li></ul>';
561
562
	get_current_screen()->add_help_tab( array(
563
		'id'      => 'locations-overview',
564
		'title'   => __( 'Overview' ),
565
		'content' => $locations_overview
566
	) );
567
endif;
568
569
get_current_screen()->set_help_sidebar(
570
	'<p><strong>' . __('For more information:') . '</strong></p>' .
571
	'<p>' . __('<a href="https://codex.wordpress.org/Appearance_Menus_Screen">Documentation on Menus</a>') . '</p>' .
572
	'<p>' . __('<a href="https://wordpress.org/support/">Support Forums</a>') . '</p>'
573
);
574
575
// Get the admin header.
576
require_once( ABSPATH . 'wp-admin/admin-header.php' );
577
?>
578
<div class="wrap">
579
	<h1 class="wp-heading-inline"><?php echo esc_html( __( 'Menus' ) ); ?></h1>
580
	<?php
581
	if ( current_user_can( 'customize' ) ) :
582
		$focus = $locations_screen ? array( 'section' => 'menu_locations' ) : array( 'panel' => 'nav_menus' );
583
		printf(
584
			' <a class="page-title-action hide-if-no-customize" href="%1$s">%2$s</a>',
585
			esc_url( add_query_arg( array(
586
				array( 'autofocus' => $focus ),
587
				'return' => urlencode( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ),
0 ignored issues
show
It seems like wp_unslash($_SERVER['REQUEST_URI']) targeting wp_unslash() can also be of type array; however, remove_query_arg() does only seem to accept boolean|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
588
			), admin_url( 'customize.php' ) ) ),
589
			__( 'Manage with Live Preview' )
590
		);
591
	endif;
592
	?>
593
594
	<hr class="wp-header-end">
595
596
	<h2 class="nav-tab-wrapper wp-clearfix">
597
		<a href="<?php echo admin_url( 'nav-menus.php' ); ?>" class="nav-tab<?php if ( ! isset( $_GET['action'] ) || isset( $_GET['action'] ) && 'locations' != $_GET['action'] ) echo ' nav-tab-active'; ?>"><?php esc_html_e( 'Edit Menus' ); ?></a>
598
		<?php if ( $num_locations && $menu_count ) : ?>
599
			<a href="<?php echo esc_url( add_query_arg( array( 'action' => 'locations' ), admin_url( 'nav-menus.php' ) ) ); ?>" class="nav-tab<?php if ( $locations_screen ) echo ' nav-tab-active'; ?>"><?php esc_html_e( 'Manage Locations' ); ?></a>
600
		<?php
601
			endif;
602
		?>
603
	</h2>
604
	<?php
605
	foreach ( $messages as $message ) :
606
		echo $message . "\n";
607
	endforeach;
608
	?>
609
	<?php
610
	if ( $locations_screen ) :
611
		if ( 1 == $num_locations ) {
612
			echo '<p>' . __( 'Your theme supports one menu. Select which menu you would like to use.' ) . '</p>';
613 View Code Duplication
		} else {
614
			echo '<p>' .  sprintf( _n( 'Your theme supports %s menu. Select which menu appears in each location.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>';
615
		}
616
	?>
617
	<div id="menu-locations-wrap">
618
		<form method="post" action="<?php echo esc_url( add_query_arg( array( 'action' => 'locations' ), admin_url( 'nav-menus.php' ) ) ); ?>">
619
			<table class="widefat fixed" id="menu-locations-table">
620
				<thead>
621
				<tr>
622
					<th scope="col" class="manage-column column-locations"><?php _e( 'Theme Location' ); ?></th>
623
					<th scope="col" class="manage-column column-menus"><?php _e( 'Assigned Menu' ); ?></th>
624
				</tr>
625
				</thead>
626
				<tbody class="menu-locations">
627
				<?php foreach ( $locations as $_location => $_name ) { ?>
628
					<tr class="menu-locations-row">
629
						<td class="menu-location-title"><label for="locations-<?php echo $_location; ?>"><?php echo $_name; ?></label></td>
630
						<td class="menu-location-menus">
631
							<select name="menu-locations[<?php echo $_location; ?>]" id="locations-<?php echo $_location; ?>">
632
								<option value="0"><?php printf( '&mdash; %s &mdash;', esc_html__( 'Select a Menu' ) ); ?></option>
633
								<?php foreach ( $nav_menus as $menu ) : ?>
634
									<?php $selected = isset( $menu_locations[$_location] ) && $menu_locations[$_location] == $menu->term_id; ?>
635
									<option <?php if ( $selected ) echo 'data-orig="true"'; ?> <?php selected( $selected ); ?> value="<?php echo $menu->term_id; ?>">
636
										<?php echo wp_html_excerpt( $menu->name, 40, '&hellip;' ); ?>
637
									</option>
638
								<?php endforeach; ?>
639
							</select>
640
							<div class="locations-row-links">
641
								<?php if ( isset( $menu_locations[ $_location ] ) && 0 != $menu_locations[ $_location ] ) : ?>
642
								<span class="locations-edit-menu-link">
643
									<a href="<?php echo esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => $menu_locations[$_location] ), admin_url( 'nav-menus.php' ) ) ); ?>">
644
										<span aria-hidden="true"><?php _ex( 'Edit', 'menu' ); ?></span><span class="screen-reader-text"><?php _e( 'Edit selected menu' ); ?></span>
645
									</a>
646
								</span>
647
								<?php endif; ?>
648
								<span class="locations-add-menu-link">
649
									<a href="<?php echo esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => 0, 'use-location' => $_location ), admin_url( 'nav-menus.php' ) ) ); ?>">
650
										<?php _ex( 'Use new menu', 'menu' ); ?>
651
									</a>
652
								</span>
653
							</div><!-- .locations-row-links -->
654
						</td><!-- .menu-location-menus -->
655
					</tr><!-- .menu-locations-row -->
656
				<?php } // foreach ?>
657
				</tbody>
658
			</table>
659
			<p class="button-controls wp-clearfix"><?php submit_button( __( 'Save Changes' ), 'primary left', 'nav-menu-locations', false ); ?></p>
660
			<?php wp_nonce_field( 'save-menu-locations' ); ?>
661
			<input type="hidden" name="menu" id="nav-menu-meta-object-id" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
662
		</form>
663
	</div><!-- #menu-locations-wrap -->
664
	<?php
665
	/**
666
	 * Fires after the menu locations table is displayed.
667
	 *
668
	 * @since 3.6.0
669
	 */
670
	do_action( 'after_menu_locations_table' ); ?>
671
	<?php else : ?>
672
	<div class="manage-menus">
673
 		<?php if ( $menu_count < 2 ) : ?>
674
		<span class="add-edit-menu-action">
675
			<?php printf( __( 'Edit your menu below, or <a href="%s">create a new menu</a>.' ), esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => 0 ), admin_url( 'nav-menus.php' ) ) ) ); ?>
676
		</span><!-- /add-edit-menu-action -->
677
		<?php else : ?>
678
			<form method="get" action="<?php echo admin_url( 'nav-menus.php' ); ?>">
679
			<input type="hidden" name="action" value="edit" />
680
			<label for="select-menu-to-edit" class="selected-menu"><?php _e( 'Select a menu to edit:' ); ?></label>
681
			<select name="menu" id="select-menu-to-edit">
682
				<?php if ( $add_new_screen ) : ?>
683
					<option value="0" selected="selected"><?php _e( '&mdash; Select &mdash;' ); ?></option>
684
				<?php endif; ?>
685
				<?php foreach ( (array) $nav_menus as $_nav_menu ) : ?>
686
					<option value="<?php echo esc_attr( $_nav_menu->term_id ); ?>" <?php selected( $_nav_menu->term_id, $nav_menu_selected_id ); ?>>
687
						<?php
688
						echo esc_html( $_nav_menu->truncated_name ) ;
689
690
						if ( ! empty( $menu_locations ) && in_array( $_nav_menu->term_id, $menu_locations ) ) {
691
							$locations_assigned_to_this_menu = array();
692
							foreach ( array_keys( $menu_locations, $_nav_menu->term_id ) as $menu_location_key ) {
693
								if ( isset( $locations[ $menu_location_key ] ) ) {
694
									$locations_assigned_to_this_menu[] = $locations[ $menu_location_key ];
695
								}
696
							}
697
698
							/**
699
							 * Filters the number of locations listed per menu in the drop-down select.
700
							 *
701
							 * @since 3.6.0
702
							 *
703
							 * @param int $locations Number of menu locations to list. Default 3.
704
							 */
705
							$assigned_locations = array_slice( $locations_assigned_to_this_menu, 0, absint( apply_filters( 'wp_nav_locations_listed_per_menu', 3 ) ) );
706
707
							// Adds ellipses following the number of locations defined in $assigned_locations.
708
							if ( ! empty( $assigned_locations ) ) {
709
								printf( ' (%1$s%2$s)',
710
									implode( ', ', $assigned_locations ),
711
									count( $locations_assigned_to_this_menu ) > count( $assigned_locations ) ? ' &hellip;' : ''
712
								);
713
							}
714
						}
715
						?>
716
					</option>
717
				<?php endforeach; ?>
718
			</select>
719
			<span class="submit-btn"><input type="submit" class="button" value="<?php esc_attr_e( 'Select' ); ?>"></span>
720
			<span class="add-new-menu-action">
721
				<?php printf( __( 'or <a href="%s">create a new menu</a>.' ), esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => 0 ), admin_url( 'nav-menus.php' ) ) ) ); ?>
722
			</span><!-- /add-new-menu-action -->
723
		</form>
724
	<?php endif; ?>
725
	</div><!-- /manage-menus -->
726
	<div id="nav-menus-frame" class="wp-clearfix">
727
	<div id="menu-settings-column" class="metabox-holder<?php if ( isset( $_GET['menu'] ) && '0' == $_GET['menu'] ) { echo ' metabox-holder-disabled'; } ?>">
728
729
		<div class="clear"></div>
730
731
		<form id="nav-menu-meta" class="nav-menu-meta" method="post" enctype="multipart/form-data">
732
			<input type="hidden" name="menu" id="nav-menu-meta-object-id" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
733
			<input type="hidden" name="action" value="add-menu-item" />
734
			<?php wp_nonce_field( 'add-menu_item', 'menu-settings-column-nonce' ); ?>
735
			<?php do_accordion_sections( 'nav-menus', 'side', null ); ?>
736
		</form>
737
738
	</div><!-- /#menu-settings-column -->
739
	<div id="menu-management-liquid">
740
		<div id="menu-management">
741
			<form id="update-nav-menu" method="post" enctype="multipart/form-data">
742
				<div class="menu-edit <?php if ( $add_new_screen ) echo 'blank-slate'; ?>">
743
					<input type="hidden" name="nav-menu-data">
744
					<?php
745
					wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
746
					wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
747
					wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' );
748
749
					$menu_name_aria_desc = $add_new_screen ? ' aria-describedby="menu-name-desc"' : '';
750
751
					if ( $one_theme_location_no_menus ) {
752
						$menu_name_val = 'value="' . esc_attr( 'Menu 1' ) . '"';
753
					?>
754
						<input type="hidden" name="zero-menu-state" value="true" />
755
					<?php } else {
756
						$menu_name_val = 'value="' . esc_attr( $nav_menu_selected_title ) . '"';
757
					} ?>
758
 					<input type="hidden" name="action" value="update" />
759
					<input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
760
					<div id="nav-menu-header">
761
						<div class="major-publishing-actions wp-clearfix">
762
							<label class="menu-name-label" for="menu-name"><?php _e( 'Menu Name' ); ?></label>
763
							<input name="menu-name" id="menu-name" type="text" class="menu-name regular-text menu-item-textbox" <?php echo $menu_name_val . $menu_name_aria_desc; ?> />
764
							<div class="publishing-action">
765
								<?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'primary large menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?>
766
							</div><!-- END .publishing-action -->
767
						</div><!-- END .major-publishing-actions -->
768
					</div><!-- END .nav-menu-header -->
769
					<div id="post-body">
770
						<div id="post-body-content" class="wp-clearfix">
771
							<?php if ( ! $add_new_screen ) : ?>
772
							<h3><?php _e( 'Menu Structure' ); ?></h3>
773
							<?php $starter_copy = ( $one_theme_location_no_menus ) ? __( 'Edit your default menu by adding or removing items. Drag each item into the order you prefer. Click Create Menu to save your changes.' ) : __( 'Drag each item into the order you prefer. Click the arrow on the right of the item to reveal additional configuration options.' ); ?>
774
							<div class="drag-instructions post-body-plain" <?php if ( isset( $menu_items ) && 0 == count( $menu_items ) ) { ?>style="display: none;"<?php } ?>>
775
								<p><?php echo $starter_copy; ?></p>
776
							</div>
777
							<?php
778
							if ( isset( $edit_markup ) && ! is_wp_error( $edit_markup ) ) {
779
								echo $edit_markup;
780
							} else {
781
							?>
782
							<ul class="menu" id="menu-to-edit"></ul>
783
							<?php } ?>
784
							<?php endif; ?>
785
							<?php if ( $add_new_screen ) : ?>
786
								<p class="post-body-plain" id="menu-name-desc"><?php _e( 'Give your menu a name, then click Create Menu.' ); ?></p>
787
								<?php if ( isset( $_GET['use-location'] ) ) : ?>
788
									<input type="hidden" name="use-location" value="<?php echo esc_attr( $_GET['use-location'] ); ?>" />
789
								<?php endif; ?>
790
							<?php endif; ?>
791
							<div class="menu-settings" <?php if ( $one_theme_location_no_menus ) { ?>style="display: none;"<?php } ?>>
792
								<h3><?php _e( 'Menu Settings' ); ?></h3>
793
								<?php
794
								if ( ! isset( $auto_add ) ) {
795
									$auto_add = get_option( 'nav_menu_options' );
796
									if ( ! isset( $auto_add['auto_add'] ) )
797
										$auto_add = false;
798
									elseif ( false !== array_search( $nav_menu_selected_id, $auto_add['auto_add'] ) )
799
										$auto_add = true;
800
									else
801
										$auto_add = false;
802
								} ?>
803
804
								<fieldset class="menu-settings-group auto-add-pages">
805
									<legend class="menu-settings-group-name howto"><?php _e( 'Auto add pages' ); ?></legend>
806
									<div class="menu-settings-input checkbox-input">
807
										<input type="checkbox"<?php checked( $auto_add ); ?> name="auto-add-pages" id="auto-add-pages" value="1" /> <label for="auto-add-pages"><?php printf( __('Automatically add new top-level pages to this menu' ), esc_url( admin_url( 'edit.php?post_type=page' ) ) ); ?></label>
808
									</div>
809
								</fieldset>
810
811
								<?php if ( current_theme_supports( 'menus' ) ) : ?>
812
813
									<fieldset class="menu-settings-group menu-theme-locations">
814
										<legend class="menu-settings-group-name howto"><?php _e( 'Display location' ); ?></legend>
815
										<?php foreach ( $locations as $location => $description ) : ?>
816
										<div class="menu-settings-input checkbox-input">
817
											<input type="checkbox"<?php checked( isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id ); ?> name="menu-locations[<?php echo esc_attr( $location ); ?>]" id="locations-<?php echo esc_attr( $location ); ?>" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
818
											<label for="locations-<?php echo esc_attr( $location ); ?>"><?php echo $description; ?></label>
819
											<?php if ( ! empty( $menu_locations[ $location ] ) && $menu_locations[ $location ] != $nav_menu_selected_id ) : ?>
820
												<span class="theme-location-set"><?php
821
													/* translators: %s: menu name */
822
													printf( _x( '(Currently set to: %s)', 'menu location' ),
823
														wp_get_nav_menu_object( $menu_locations[ $location ] )->name
824
													);
825
												?></span>
826
											<?php endif; ?>
827
										</div>
828
										<?php endforeach; ?>
829
									</fieldset>
830
831
								<?php endif; ?>
832
833
							</div>
834
						</div><!-- /#post-body-content -->
835
					</div><!-- /#post-body -->
836
					<div id="nav-menu-footer">
837
						<div class="major-publishing-actions wp-clearfix">
838
							<?php if ( 0 != $menu_count && ! $add_new_screen ) : ?>
839
							<span class="delete-action">
840
								<a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'menu' => $nav_menu_selected_id ), admin_url( 'nav-menus.php' ) ), 'delete-nav_menu-' . $nav_menu_selected_id) ); ?>"><?php _e('Delete Menu'); ?></a>
841
							</span><!-- END .delete-action -->
842
							<?php endif; ?>
843
							<div class="publishing-action">
844
								<?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'primary large menu-save', 'save_menu', false, array( 'id' => 'save_menu_footer' ) ); ?>
845
							</div><!-- END .publishing-action -->
846
						</div><!-- END .major-publishing-actions -->
847
					</div><!-- /#nav-menu-footer -->
848
				</div><!-- /.menu-edit -->
849
			</form><!-- /#update-nav-menu -->
850
		</div><!-- /#menu-management -->
851
	</div><!-- /#menu-management-liquid -->
852
	</div><!-- /#nav-menus-frame -->
853
	<?php endif; ?>
854
</div><!-- /.wrap-->
855
<?php include( ABSPATH . 'wp-admin/admin-footer.php' ); ?>
856