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/widgets.php (1 issue)

Labels
Severity

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
 * Widget administration panel
4
 *
5
 * @package WordPress
6
 * @subpackage Administration
7
 */
8
9
/** WordPress Administration Bootstrap */
10
require_once( dirname( __FILE__ ) . '/admin.php' );
11
12
/** WordPress Administration Widgets API */
13
require_once(ABSPATH . 'wp-admin/includes/widgets.php');
14
15
if ( ! current_user_can( 'edit_theme_options' ) ) {
16
	wp_die(
17
		'<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
18
		'<p>' . __( 'Sorry, you are not allowed to edit theme options on this site.' ) . '</p>',
19
		403
20
	);
21
}
22
23
$widgets_access = get_user_setting( 'widgets_access' );
24
if ( isset($_GET['widgets-access']) ) {
25
	check_admin_referer( 'widgets-access' );
26
27
	$widgets_access = 'on' == $_GET['widgets-access'] ? 'on' : 'off';
28
	set_user_setting( 'widgets_access', $widgets_access );
29
}
30
31
if ( 'on' == $widgets_access ) {
32
	add_filter( 'admin_body_class', 'wp_widgets_access_body_class' );
33
} else {
34
	wp_enqueue_script('admin-widgets');
35
36
	if ( wp_is_mobile() )
37
		wp_enqueue_script( 'jquery-touch-punch' );
38
}
39
40
/**
41
 * Fires early before the Widgets administration screen loads,
42
 * after scripts are enqueued.
43
 *
44
 * @since 2.2.0
45
 */
46
do_action( 'sidebar_admin_setup' );
47
48
$title = __( 'Widgets' );
49
$parent_file = 'themes.php';
50
51
get_current_screen()->add_help_tab( array(
52
'id'		=> 'overview',
53
'title'		=> __('Overview'),
54
'content'	=>
55
	'<p>' . __('Widgets are independent sections of content that can be placed into any widgetized area provided by your theme (commonly called sidebars). To populate your sidebars/widget areas with individual widgets, drag and drop the title bars into the desired area. By default, only the first widget area is expanded. To populate additional widget areas, click on their title bars to expand them.') . '</p>
56
	<p>' . __('The Available Widgets section contains all the widgets you can choose from. Once you drag a widget into a sidebar, it will open to allow you to configure its settings. When you are happy with the widget settings, click the Save button and the widget will go live on your site. If you click Delete, it will remove the widget.') . '</p>'
57
) );
58
get_current_screen()->add_help_tab( array(
59
'id'		=> 'removing-reusing',
60
'title'		=> __('Removing and Reusing'),
61
'content'	=>
62
	'<p>' . __('If you want to remove the widget but save its setting for possible future use, just drag it into the Inactive Widgets area. You can add them back anytime from there. This is especially helpful when you switch to a theme with fewer or different widget areas.') . '</p>
63
	<p>' . __('Widgets may be used multiple times. You can give each widget a title, to display on your site, but it&#8217;s not required.') . '</p>
64
	<p>' . __('Enabling Accessibility Mode, via Screen Options, allows you to use Add and Edit buttons instead of using drag and drop.') . '</p>'
65
) );
66
get_current_screen()->add_help_tab( array(
67
'id'		=> 'missing-widgets',
68
'title'		=> __('Missing Widgets'),
69
'content'	=>
70
	'<p>' . __('Many themes show some sidebar widgets by default until you edit your sidebars, but they are not automatically displayed in your sidebar management tool. After you make your first widget change, you can re-add the default widgets by adding them from the Available Widgets area.') . '</p>' .
71
		'<p>' . __('When changing themes, there is often some variation in the number and setup of widget areas/sidebars and sometimes these conflicts make the transition a bit less smooth. If you changed themes and seem to be missing widgets, scroll down on this screen to the Inactive Widgets area, where all of your widgets and their settings will have been saved.') . '</p>'
72
) );
73
74
get_current_screen()->set_help_sidebar(
75
	'<p><strong>' . __('For more information:') . '</strong></p>' .
76
	'<p>' . __('<a href="https://codex.wordpress.org/Appearance_Widgets_Screen">Documentation on Widgets</a>') . '</p>' .
77
	'<p>' . __('<a href="https://wordpress.org/support/">Support Forums</a>') . '</p>'
78
);
79
80
if ( ! current_theme_supports( 'widgets' ) ) {
81
	wp_die( __( 'The theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="https://codex.wordpress.org/Widgetizing_Themes">follow these instructions</a>.' ) );
82
}
83
84
// These are the widgets grouped by sidebar
85
$sidebars_widgets = wp_get_sidebars_widgets();
86
87
if ( empty( $sidebars_widgets ) )
88
	$sidebars_widgets = wp_get_widget_defaults();
89
90
foreach ( $sidebars_widgets as $sidebar_id => $widgets ) {
91
	if ( 'wp_inactive_widgets' == $sidebar_id )
92
		continue;
93
94
	if ( ! is_registered_sidebar( $sidebar_id ) ) {
95
		if ( ! empty( $widgets ) ) { // register the inactive_widgets area as sidebar
96
			register_sidebar(array(
97
				'name' => __( 'Inactive Sidebar (not used)' ),
98
				'id' => $sidebar_id,
99
				'class' => 'inactive-sidebar orphan-sidebar',
100
				'description' => __( 'This sidebar is no longer available and does not show anywhere on your site. Remove each of the widgets below to fully remove this inactive sidebar.' ),
101
				'before_widget' => '',
102
				'after_widget' => '',
103
				'before_title' => '',
104
				'after_title' => '',
105
			));
106
		} else {
107
			unset( $sidebars_widgets[ $sidebar_id ] );
108
		}
109
	}
110
}
111
112
// register the inactive_widgets area as sidebar
113
register_sidebar(array(
114
	'name' => __('Inactive Widgets'),
115
	'id' => 'wp_inactive_widgets',
116
	'class' => 'inactive-sidebar',
117
	'description' => __( 'Drag widgets here to remove them from the sidebar but keep their settings.' ),
118
	'before_widget' => '',
119
	'after_widget' => '',
120
	'before_title' => '',
121
	'after_title' => '',
122
));
123
124
retrieve_widgets();
125
126
// We're saving a widget without js
127
if ( isset($_POST['savewidget']) || isset($_POST['removewidget']) ) {
128
	$widget_id = $_POST['widget-id'];
129
	check_admin_referer("save-delete-widget-$widget_id");
130
131
	$number = isset($_POST['multi_number']) ? (int) $_POST['multi_number'] : '';
132
	if ( $number ) {
133
		foreach ( $_POST as $key => $val ) {
134
			if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) {
135
				$_POST[$key] = array( $number => array_shift($val) );
136
				break;
137
			}
138
		}
139
	}
140
141
	$sidebar_id = $_POST['sidebar'];
142
	$position = isset($_POST[$sidebar_id . '_position']) ? (int) $_POST[$sidebar_id . '_position'] - 1 : 0;
143
144
	$id_base = $_POST['id_base'];
145
	$sidebar = isset($sidebars_widgets[$sidebar_id]) ? $sidebars_widgets[$sidebar_id] : array();
146
147
	// Delete.
148
	if ( isset($_POST['removewidget']) && $_POST['removewidget'] ) {
149
150
		if ( !in_array($widget_id, $sidebar, true) ) {
151
			wp_redirect( admin_url('widgets.php?error=0') );
152
			exit;
153
		}
154
155
		$sidebar = array_diff( $sidebar, array($widget_id) );
156
		$_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
157
158
		/**
159
		 * Fires immediately after a widget has been marked for deletion.
160
		 *
161
		 * @since 4.4.0
162
		 *
163
		 * @param string $widget_id  ID of the widget marked for deletion.
164
		 * @param string $sidebar_id ID of the sidebar the widget was deleted from.
165
		 * @param string $id_base    ID base for the widget.
166
		 */
167
		do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base );
168
	}
169
170
	$_POST['widget-id'] = $sidebar;
171
172 View Code Duplication
	foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
173
		if ( $name != $id_base || !is_callable($control['callback']) )
174
			continue;
175
176
		ob_start();
177
			call_user_func_array( $control['callback'], $control['params'] );
178
		ob_end_clean();
179
180
		break;
181
	}
182
183
	$sidebars_widgets[$sidebar_id] = $sidebar;
184
185
	// Remove old position.
186
	if ( !isset($_POST['delete_widget']) ) {
187
		foreach ( $sidebars_widgets as $key => $sb ) {
188
			if ( is_array($sb) )
189
				$sidebars_widgets[$key] = array_diff( $sb, array($widget_id) );
190
		}
191
		array_splice( $sidebars_widgets[$sidebar_id], $position, 0, $widget_id );
192
	}
193
194
	wp_set_sidebars_widgets($sidebars_widgets);
195
	wp_redirect( admin_url('widgets.php?message=0') );
196
	exit;
197
}
198
199
// Remove inactive widgets without js
200
if ( isset( $_POST['removeinactivewidgets'] ) ) {
201
	check_admin_referer( 'remove-inactive-widgets', '_wpnonce_remove_inactive_widgets' );
202
203
	if ( $_POST['removeinactivewidgets'] ) {
204 View Code Duplication
		foreach ( $sidebars_widgets['wp_inactive_widgets'] as $key => $widget_id ) {
205
			$pieces = explode( '-', $widget_id );
206
			$multi_number = array_pop( $pieces );
207
			$id_base = implode( '-', $pieces );
208
			$widget = get_option( 'widget_' . $id_base );
209
			unset( $widget[$multi_number] );
210
			update_option( 'widget_' . $id_base, $widget );
211
			unset( $sidebars_widgets['wp_inactive_widgets'][$key] );
212
		}
213
214
		wp_set_sidebars_widgets( $sidebars_widgets );
215
	}
216
217
	wp_redirect( admin_url( 'widgets.php?message=0' ) );
218
	exit;
219
}
220
221
// Output the widget form without js
222
if ( isset($_GET['editwidget']) && $_GET['editwidget'] ) {
223
	$widget_id = $_GET['editwidget'];
224
225
	if ( isset($_GET['addnew']) ) {
226
		// Default to the first sidebar
227
		$keys = array_keys( $wp_registered_sidebars );
228
		$sidebar = reset( $keys );
229
230
		if ( isset($_GET['base']) && isset($_GET['num']) ) { // multi-widget
231
			// Copy minimal info from an existing instance of this widget to a new instance
232
			foreach ( $wp_registered_widget_controls as $control ) {
233
				if ( $_GET['base'] === $control['id_base'] ) {
234
					$control_callback = $control['callback'];
235
					$multi_number = (int) $_GET['num'];
236
					$control['params'][0]['number'] = -1;
237
					$widget_id = $control['id'] = $control['id_base'] . '-' . $multi_number;
238
					$wp_registered_widget_controls[$control['id']] = $control;
239
					break;
240
				}
241
			}
242
		}
243
	}
244
245
	if ( isset($wp_registered_widget_controls[$widget_id]) && !isset($control) ) {
246
		$control = $wp_registered_widget_controls[$widget_id];
247
		$control_callback = $control['callback'];
248
	} elseif ( !isset($wp_registered_widget_controls[$widget_id]) && isset($wp_registered_widgets[$widget_id]) ) {
249
		$name = esc_html( strip_tags($wp_registered_widgets[$widget_id]['name']) );
250
	}
251
252
	if ( !isset($name) )
253
		$name = esc_html( strip_tags($control['name']) );
254
255
	if ( !isset($sidebar) )
256
		$sidebar = isset($_GET['sidebar']) ? $_GET['sidebar'] : 'wp_inactive_widgets';
257
258
	if ( !isset($multi_number) )
259
		$multi_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : '';
260
261
	$id_base = isset($control['id_base']) ? $control['id_base'] : $control['id'];
262
263
	// Show the widget form.
264
	$width = ' style="width:' . max($control['width'], 350) . 'px"';
265
	$key = isset($_GET['key']) ? (int) $_GET['key'] : 0;
266
267
	require_once( ABSPATH . 'wp-admin/admin-header.php' ); ?>
268
	<div class="wrap">
269
	<h1><?php echo esc_html( $title ); ?></h1>
270
	<div class="editwidget"<?php echo $width; ?>>
271
	<h2><?php printf( __( 'Widget %s' ), $name ); ?></h2>
272
273
	<form action="widgets.php" method="post">
274
	<div class="widget-inside">
275
<?php
276
	if ( is_callable( $control_callback ) )
277
		call_user_func_array( $control_callback, $control['params'] );
278
	else
279
		echo '<p>' . __('There are no options for this widget.') . "</p>\n"; ?>
280
	</div>
281
282
	<p class="describe"><?php _e('Select both the sidebar for this widget and the position of the widget in that sidebar.'); ?></p>
283
	<div class="widget-position">
284
	<table class="widefat"><thead><tr><th><?php _e('Sidebar'); ?></th><th><?php _e('Position'); ?></th></tr></thead><tbody>
285
<?php
286
	foreach ( $wp_registered_sidebars as $sbname => $sbvalue ) {
287
		echo "\t\t<tr><td><label><input type='radio' name='sidebar' value='" . esc_attr($sbname) . "'" . checked( $sbname, $sidebar, false ) . " /> $sbvalue[name]</label></td><td>";
288
		if ( 'wp_inactive_widgets' == $sbname || 'orphaned_widgets' == substr( $sbname, 0, 16 ) ) {
289
			echo '&nbsp;';
290
		} else {
291
			if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) {
292
				$j = 1;
293
				$sidebars_widgets[$sbname] = array();
294
			} else {
295
				$j = count($sidebars_widgets[$sbname]);
296
				if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) )
297
					$j++;
298
			}
299
			$selected = '';
300
			echo "\t\t<select name='{$sbname}_position'>\n";
301
			echo "\t\t<option value=''>" . __('&mdash; Select &mdash;') . "</option>\n";
302
			for ( $i = 1; $i <= $j; $i++ ) {
303
				if ( in_array($widget_id, $sidebars_widgets[$sbname], true) )
304
					$selected = selected( $i, $key + 1, false );
305
				echo "\t\t<option value='$i'$selected> $i </option>\n";
306
			}
307
			echo "\t\t</select>\n";
308
		}
309
		echo "</td></tr>\n";
310
	} ?>
311
	</tbody></table>
312
	</div>
313
314
	<div class="widget-control-actions">
315
<?php
316
	if ( isset($_GET['addnew']) ) { ?>
317
	<a href="widgets.php" class="button alignleft"><?php _e('Cancel'); ?></a>
318
<?php
319
	} else {
320
		submit_button( __( 'Delete' ), 'alignleft', 'removewidget', false );
321
	}
322
	submit_button( __( 'Save Widget' ), 'primary alignright', 'savewidget', false ); ?>
323
	<input type="hidden" name="widget-id" class="widget-id" value="<?php echo esc_attr($widget_id); ?>" />
324
	<input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" />
325
	<input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" />
326
<?php	wp_nonce_field("save-delete-widget-$widget_id"); ?>
327
	<br class="clear" />
328
	</div>
329
	</form>
330
	</div>
331
	</div>
332
<?php
333
	require_once( ABSPATH . 'wp-admin/admin-footer.php' );
334
	exit;
335
}
336
337
$messages = array(
338
	__('Changes saved.')
339
);
340
341
$errors = array(
342
	__('Error while saving.'),
343
	__('Error in displaying the widget settings form.')
344
);
345
346
require_once( ABSPATH . 'wp-admin/admin-header.php' ); ?>
347
348
<div class="wrap">
349
<h1 class="wp-heading-inline"><?php
350
echo esc_html( $title );
351
?></h1>
352
353
<?php
354
if ( current_user_can( 'customize' ) ) {
355
	printf(
356
		' <a class="page-title-action hide-if-no-customize" href="%1$s">%2$s</a>',
357
		esc_url( add_query_arg(
358
			array(
359
				array( 'autofocus' => array( 'panel' => 'widgets' ) ),
360
				'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...
361
			),
362
			admin_url( 'customize.php' )
363
		) ),
364
		__( 'Manage with Live Preview' )
365
	);
366
}
367
?>
368
369
<hr class="wp-header-end">
370
371
<?php if ( isset($_GET['message']) && isset($messages[$_GET['message']]) ) { ?>
372
<div id="message" class="updated notice is-dismissible"><p><?php echo $messages[$_GET['message']]; ?></p></div>
373
<?php } ?>
374
<?php if ( isset($_GET['error']) && isset($errors[$_GET['error']]) ) { ?>
375
<div id="message" class="error"><p><?php echo $errors[$_GET['error']]; ?></p></div>
376
<?php } ?>
377
378
<?php
379
/**
380
 * Fires before the Widgets administration page content loads.
381
 *
382
 * @since 3.0.0
383
 */
384
do_action( 'widgets_admin_page' ); ?>
385
386
<div class="widget-liquid-left">
387
<div id="widgets-left">
388
	<div id="available-widgets" class="widgets-holder-wrap">
389
		<div class="sidebar-name">
390
			<div class="sidebar-name-arrow"><br /></div>
391
			<h2><?php _e( 'Available Widgets' ); ?> <span id="removing-widget"><?php _ex( 'Deactivate', 'removing-widget' ); ?> <span></span></span></h2>
392
		</div>
393
		<div class="widget-holder">
394
			<div class="sidebar-description">
395
				<p class="description"><?php _e('To activate a widget drag it to a sidebar or click on it. To deactivate a widget and delete its settings, drag it back.'); ?></p>
396
			</div>
397
			<div id="widget-list">
398
				<?php wp_list_widgets(); ?>
399
			</div>
400
			<br class='clear' />
401
		</div>
402
		<br class="clear" />
403
	</div>
404
405
<?php
406
407
$theme_sidebars = array();
408
foreach ( $wp_registered_sidebars as $sidebar => $registered_sidebar ) {
409
	if ( false !== strpos( $registered_sidebar['class'], 'inactive-sidebar' ) || 'orphaned_widgets' == substr( $sidebar, 0, 16 ) ) {
410
		$wrap_class = 'widgets-holder-wrap';
411
		if ( !empty( $registered_sidebar['class'] ) )
412
			$wrap_class .= ' ' . $registered_sidebar['class'];
413
414
		$is_inactive_widgets = 'wp_inactive_widgets' == $registered_sidebar['id'];
415
		?>
416
		<div class="<?php echo esc_attr( $wrap_class ); ?>">
417
			<div class="widget-holder inactive">
418
				<?php wp_list_widget_controls( $registered_sidebar['id'], $registered_sidebar['name'] ); ?>
419
420
				<?php if ( $is_inactive_widgets ) { ?>
421
				<div class="remove-inactive-widgets">
422
					<form action="" method="post">
423
						<p>
424
							<?php
425
							$attributes = array( 'id' => 'inactive-widgets-control-remove' );
426
427
							if ( empty($sidebars_widgets['wp_inactive_widgets']) ) {
428
								$attributes['disabled'] = '';
429
							}
430
431
							submit_button( __( 'Clear Inactive Widgets' ), 'delete', 'removeinactivewidgets', false, $attributes );
432
							?>
433
							<span class="spinner"></span>
434
						</p>
435
						<?php wp_nonce_field( 'remove-inactive-widgets', '_wpnonce_remove_inactive_widgets' ); ?>
436
					</form>
437
				</div>
438
				<?php } ?>
439
			</div>
440
			<?php if ( $is_inactive_widgets ) { ?>
441
			<p class="description"><?php _e( 'This will clear all items from the inactive widgets list. You will not be able to restore any customizations.' ); ?></p>
442
			<?php } ?>
443
		</div>
444
		<?php
445
446
	} else {
447
		$theme_sidebars[$sidebar] = $registered_sidebar;
448
	}
449
}
450
451
?>
452
</div>
453
</div>
454
<?php
455
456
$i = $split = 0;
457
$single_sidebar_class = '';
458
$sidebars_count = count( $theme_sidebars );
459
460
if ( $sidebars_count > 1 ) {
461
	$split = ceil( $sidebars_count / 2 );
462
} else {
463
	$single_sidebar_class = ' single-sidebar';
464
}
465
466
?>
467
<div class="widget-liquid-right">
468
<div id="widgets-right" class="wp-clearfix<?php echo $single_sidebar_class; ?>">
469
<div class="sidebars-column-1">
470
<?php
471
472
foreach ( $theme_sidebars as $sidebar => $registered_sidebar ) {
473
	$wrap_class = 'widgets-holder-wrap';
474
	if ( !empty( $registered_sidebar['class'] ) )
475
		$wrap_class .= ' sidebar-' . $registered_sidebar['class'];
476
477
	if ( $i > 0 )
478
		$wrap_class .= ' closed';
479
480
	if ( $split && $i == $split ) {
481
		?>
482
		</div><div class="sidebars-column-2">
483
		<?php
484
	}
485
486
	?>
487
	<div class="<?php echo esc_attr( $wrap_class ); ?>">
488
		<?php wp_list_widget_controls( $sidebar, $registered_sidebar['name'] ); // Show the control forms for each of the widgets in this sidebar ?>
489
	</div>
490
	<?php
491
492
	$i++;
493
}
494
495
?>
496
</div>
497
</div>
498
</div>
499
<form method="post">
500
<?php wp_nonce_field( 'save-sidebar-widgets', '_wpnonce_widgets', false ); ?>
501
</form>
502
<br class="clear" />
503
</div>
504
505
<div class="widgets-chooser">
506
	<ul class="widgets-chooser-sidebars"></ul>
507
	<div class="widgets-chooser-actions">
508
		<button class="button widgets-chooser-cancel"><?php _e( 'Cancel' ); ?></button>
509
		<button class="button button-primary widgets-chooser-add"><?php _e( 'Add Widget' ); ?></button>
510
	</div>
511
</div>
512
513
<?php
514
515
/**
516
 * Fires after the available widgets and sidebars have loaded, before the admin footer.
517
 *
518
 * @since 2.2.0
519
 */
520
do_action( 'sidebar_admin_page' );
521
require_once( ABSPATH . 'wp-admin/admin-footer.php' );
522