~lewiscawte/+junk/WordPress

« back to all changes in this revision

Viewing changes to wp-admin/includes/plugin.php

  • Committer: Lewis Cawte
  • Date: 2010-08-30 22:01:10 UTC
  • Revision ID: lewis@lewis-desktop-20100830220110-ftupiydkd7afgv0j
Adding WordPress, stable version - 3.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * WordPress Plugin Administration API
 
4
 *
 
5
 * @package WordPress
 
6
 * @subpackage Administration
 
7
 */
 
8
 
 
9
/**
 
10
 * Parse the plugin contents to retrieve plugin's metadata.
 
11
 *
 
12
 * The metadata of the plugin's data searches for the following in the plugin's
 
13
 * header. All plugin data must be on its own line. For plugin description, it
 
14
 * must not have any newlines or only parts of the description will be displayed
 
15
 * and the same goes for the plugin data. The below is formatted for printing.
 
16
 *
 
17
 * <code>
 
18
 * /*
 
19
 * Plugin Name: Name of Plugin
 
20
 * Plugin URI: Link to plugin information
 
21
 * Description: Plugin Description
 
22
 * Author: Plugin author's name
 
23
 * Author URI: Link to the author's web site
 
24
 * Version: Must be set in the plugin for WordPress 2.3+
 
25
 * Text Domain: Optional. Unique identifier, should be same as the one used in
 
26
 *              plugin_text_domain()
 
27
 * Domain Path: Optional. Only useful if the translations are located in a
 
28
 *              folder above the plugin's base path. For example, if .mo files are
 
29
 *              located in the locale folder then Domain Path will be "/locale/" and
 
30
 *              must have the first slash. Defaults to the base folder the plugin is
 
31
 *              located in.
 
32
 * Network: Optional. Specify "Network: true" to require that a plugin is activated
 
33
 *              across all sites in an installation. This will prevent a plugin from being
 
34
 *              activated on a single site when Multisite is enabled.
 
35
 *  * / # Remove the space to close comment
 
36
 * </code>
 
37
 *
 
38
 * Plugin data returned array contains the following:
 
39
 *              'Name' - Name of the plugin, must be unique.
 
40
 *              'Title' - Title of the plugin and the link to the plugin's web site.
 
41
 *              'Description' - Description of what the plugin does and/or notes
 
42
 *              from the author.
 
43
 *              'Author' - The author's name
 
44
 *              'AuthorURI' - The authors web site address.
 
45
 *              'Version' - The plugin version number.
 
46
 *              'PluginURI' - Plugin web site address.
 
47
 *              'TextDomain' - Plugin's text domain for localization.
 
48
 *              'DomainPath' - Plugin's relative directory path to .mo files.
 
49
 *              'Network' - Boolean. Whether the plugin can only be activated network wide.
 
50
 *
 
51
 * Some users have issues with opening large files and manipulating the contents
 
52
 * for want is usually the first 1kiB or 2kiB. This function stops pulling in
 
53
 * the plugin contents when it has all of the required plugin data.
 
54
 *
 
55
 * The first 8kiB of the file will be pulled in and if the plugin data is not
 
56
 * within that first 8kiB, then the plugin author should correct their plugin
 
57
 * and move the plugin data headers to the top.
 
58
 *
 
59
 * The plugin file is assumed to have permissions to allow for scripts to read
 
60
 * the file. This is not checked however and the file is only opened for
 
61
 * reading.
 
62
 *
 
63
 * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations.
 
64
 * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations.
 
65
 * @since 1.5.0
 
66
 *
 
67
 * @param string $plugin_file Path to the plugin file
 
68
 * @param bool $markup If the returned data should have HTML markup applied
 
69
 * @param bool $translate If the returned data should be translated
 
70
 * @return array See above for description.
 
71
 */
 
72
function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
 
73
 
 
74
        $default_headers = array(
 
75
                'Name' => 'Plugin Name',
 
76
                'PluginURI' => 'Plugin URI',
 
77
                'Version' => 'Version',
 
78
                'Description' => 'Description',
 
79
                'Author' => 'Author',
 
80
                'AuthorURI' => 'Author URI',
 
81
                'TextDomain' => 'Text Domain',
 
82
                'DomainPath' => 'Domain Path',
 
83
                'Network' => 'Network',
 
84
                // Site Wide Only is deprecated in favor of Network.
 
85
                '_sitewide' => 'Site Wide Only',
 
86
        );
 
87
 
 
88
        $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' );
 
89
 
 
90
        // Site Wide Only is the old header for Network
 
91
        if ( empty( $plugin_data['Network'] ) && ! empty( $plugin_data['_sitewide'] ) ) {
 
92
                _deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The <code>%1$s</code> plugin header is deprecated. Use <code>%2$s</code> instead.' ), 'Site Wide Only: true', 'Network: true' ) );
 
93
                $plugin_data['Network'] = $plugin_data['_sitewide'];
 
94
        }
 
95
        $plugin_data['Network'] = ( 'true' == strtolower( $plugin_data['Network'] ) );
 
96
        unset( $plugin_data['_sitewide'] );
 
97
 
 
98
        //For backward compatibility by default Title is the same as Name.
 
99
        $plugin_data['Title'] = $plugin_data['Name'];
 
100
 
 
101
        if ( $markup || $translate )
 
102
                $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate );
 
103
 
 
104
        return $plugin_data;
 
105
}
 
106
 
 
107
function _get_plugin_data_markup_translate($plugin_file, $plugin_data, $markup = true, $translate = true) {
 
108
 
 
109
        //Translate fields30
 
110
        if ( $translate && ! empty($plugin_data['TextDomain']) ) {
 
111
                if ( ! empty( $plugin_data['DomainPath'] ) )
 
112
                        load_plugin_textdomain($plugin_data['TextDomain'], false, dirname($plugin_file). $plugin_data['DomainPath']);
 
113
                else
 
114
                        load_plugin_textdomain($plugin_data['TextDomain'], false, dirname($plugin_file));
 
115
 
 
116
                foreach ( array('Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version') as $field )
 
117
                        $plugin_data[ $field ] = translate($plugin_data[ $field ], $plugin_data['TextDomain']);
 
118
        }
 
119
 
 
120
        //Apply Markup
 
121
        if ( $markup ) {
 
122
                if ( ! empty($plugin_data['PluginURI']) && ! empty($plugin_data['Name']) )
 
123
                        $plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '" title="' . __( 'Visit plugin homepage' ) . '">' . $plugin_data['Name'] . '</a>';
 
124
                else
 
125
                        $plugin_data['Title'] = $plugin_data['Name'];
 
126
 
 
127
                if ( ! empty($plugin_data['AuthorURI']) && ! empty($plugin_data['Author']) )
 
128
                        $plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '" title="' . __( 'Visit author homepage' ) . '">' . $plugin_data['Author'] . '</a>';
 
129
 
 
130
                $plugin_data['Description'] = wptexturize( $plugin_data['Description'] );
 
131
                if ( ! empty($plugin_data['Author']) )
 
132
                        $plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s'), $plugin_data['Author'] ) . '.</cite>';
 
133
        }
 
134
 
 
135
        $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
 
136
 
 
137
        // Sanitize all displayed data
 
138
        $plugin_data['Title']       = wp_kses($plugin_data['Title'], $plugins_allowedtags);
 
139
        $plugin_data['Version']     = wp_kses($plugin_data['Version'], $plugins_allowedtags);
 
140
        $plugin_data['Description'] = wp_kses($plugin_data['Description'], $plugins_allowedtags);
 
141
        $plugin_data['Author']      = wp_kses($plugin_data['Author'], $plugins_allowedtags);
 
142
 
 
143
        return $plugin_data;
 
144
}
 
145
 
 
146
/**
 
147
 * Get a list of a plugin's files.
 
148
 *
 
149
 * @since 2.8.0
 
150
 *
 
151
 * @param string $plugin Plugin ID
 
152
 * @return array List of files relative to the plugin root.
 
153
 */
 
154
function get_plugin_files($plugin) {
 
155
        $plugin_file = WP_PLUGIN_DIR . '/' . $plugin;
 
156
        $dir = dirname($plugin_file);
 
157
        $plugin_files = array($plugin);
 
158
        if ( is_dir($dir) && $dir != WP_PLUGIN_DIR ) {
 
159
                $plugins_dir = @ opendir( $dir );
 
160
                if ( $plugins_dir ) {
 
161
                        while (($file = readdir( $plugins_dir ) ) !== false ) {
 
162
                                if ( substr($file, 0, 1) == '.' )
 
163
                                        continue;
 
164
                                if ( is_dir( $dir . '/' . $file ) ) {
 
165
                                        $plugins_subdir = @ opendir( $dir . '/' . $file );
 
166
                                        if ( $plugins_subdir ) {
 
167
                                                while (($subfile = readdir( $plugins_subdir ) ) !== false ) {
 
168
                                                        if ( substr($subfile, 0, 1) == '.' )
 
169
                                                                continue;
 
170
                                                        $plugin_files[] = plugin_basename("$dir/$file/$subfile");
 
171
                                                }
 
172
                                                @closedir( $plugins_subdir );
 
173
                                        }
 
174
                                } else {
 
175
                                        if ( plugin_basename("$dir/$file") != $plugin )
 
176
                                                $plugin_files[] = plugin_basename("$dir/$file");
 
177
                                }
 
178
                        }
 
179
                        @closedir( $plugins_dir );
 
180
                }
 
181
        }
 
182
 
 
183
        return $plugin_files;
 
184
}
 
185
 
 
186
/**
 
187
 * Check the plugins directory and retrieve all plugin files with plugin data.
 
188
 *
 
189
 * WordPress only supports plugin files in the base plugins directory
 
190
 * (wp-content/plugins) and in one directory above the plugins directory
 
191
 * (wp-content/plugins/my-plugin). The file it looks for has the plugin data and
 
192
 * must be found in those two locations. It is recommended that do keep your
 
193
 * plugin files in directories.
 
194
 *
 
195
 * The file with the plugin data is the file that will be included and therefore
 
196
 * needs to have the main execution for the plugin. This does not mean
 
197
 * everything must be contained in the file and it is recommended that the file
 
198
 * be split for maintainability. Keep everything in one file for extreme
 
199
 * optimization purposes.
 
200
 *
 
201
 * @since unknown
 
202
 *
 
203
 * @param string $plugin_folder Optional. Relative path to single plugin folder.
 
204
 * @return array Key is the plugin file path and the value is an array of the plugin data.
 
205
 */
 
206
function get_plugins($plugin_folder = '') {
 
207
 
 
208
        if ( ! $cache_plugins = wp_cache_get('plugins', 'plugins') )
 
209
                $cache_plugins = array();
 
210
 
 
211
        if ( isset($cache_plugins[ $plugin_folder ]) )
 
212
                return $cache_plugins[ $plugin_folder ];
 
213
 
 
214
        $wp_plugins = array ();
 
215
        $plugin_root = WP_PLUGIN_DIR;
 
216
        if ( !empty($plugin_folder) )
 
217
                $plugin_root .= $plugin_folder;
 
218
 
 
219
        // Files in wp-content/plugins directory
 
220
        $plugins_dir = @ opendir( $plugin_root);
 
221
        $plugin_files = array();
 
222
        if ( $plugins_dir ) {
 
223
                while (($file = readdir( $plugins_dir ) ) !== false ) {
 
224
                        if ( substr($file, 0, 1) == '.' )
 
225
                                continue;
 
226
                        if ( is_dir( $plugin_root.'/'.$file ) ) {
 
227
                                $plugins_subdir = @ opendir( $plugin_root.'/'.$file );
 
228
                                if ( $plugins_subdir ) {
 
229
                                        while (($subfile = readdir( $plugins_subdir ) ) !== false ) {
 
230
                                                if ( substr($subfile, 0, 1) == '.' )
 
231
                                                        continue;
 
232
                                                if ( substr($subfile, -4) == '.php' )
 
233
                                                        $plugin_files[] = "$file/$subfile";
 
234
                                        }
 
235
                                }
 
236
                        } else {
 
237
                                if ( substr($file, -4) == '.php' )
 
238
                                        $plugin_files[] = $file;
 
239
                        }
 
240
                }
 
241
        } else {
 
242
                return $wp_plugins;
 
243
        }
 
244
 
 
245
        @closedir( $plugins_dir );
 
246
        @closedir( $plugins_subdir );
 
247
 
 
248
        if ( empty($plugin_files) )
 
249
                return $wp_plugins;
 
250
 
 
251
        foreach ( $plugin_files as $plugin_file ) {
 
252
                if ( !is_readable( "$plugin_root/$plugin_file" ) )
 
253
                        continue;
 
254
 
 
255
                $plugin_data = get_plugin_data( "$plugin_root/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached.
 
256
 
 
257
                if ( empty ( $plugin_data['Name'] ) )
 
258
                        continue;
 
259
 
 
260
                $wp_plugins[plugin_basename( $plugin_file )] = $plugin_data;
 
261
        }
 
262
 
 
263
        uasort( $wp_plugins, create_function( '$a, $b', 'return strnatcasecmp( $a["Name"], $b["Name"] );' ));
 
264
 
 
265
        $cache_plugins[ $plugin_folder ] = $wp_plugins;
 
266
        wp_cache_set('plugins', $cache_plugins, 'plugins');
 
267
 
 
268
        return $wp_plugins;
 
269
}
 
270
 
 
271
/**
 
272
 * Check the mu-plugins directory and retrieve all mu-plugin files with any plugin data.
 
273
 *
 
274
 * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins).
 
275
 *
 
276
 * @since 3.0.0
 
277
 * @return array Key is the mu-plugin file path and the value is an array of the mu-plugin data.
 
278
 */
 
279
function get_mu_plugins() {
 
280
        $wp_plugins = array();
 
281
        // Files in wp-content/mu-plugins directory
 
282
        $plugin_files = array();
 
283
 
 
284
        if ( ! is_dir( WPMU_PLUGIN_DIR ) )
 
285
                return $wp_plugins;
 
286
        if ( $plugins_dir = @ opendir( WPMU_PLUGIN_DIR ) ) {
 
287
                while ( ( $file = readdir( $plugins_dir ) ) !== false ) {
 
288
                        if ( substr( $file, -4 ) == '.php' )
 
289
                                $plugin_files[] = $file;
 
290
                }
 
291
        } else {
 
292
                return $wp_plugins;
 
293
        }
 
294
 
 
295
        @closedir( $plugins_dir );
 
296
 
 
297
        if ( empty($plugin_files) )
 
298
                return $wp_plugins;
 
299
 
 
300
        foreach ( $plugin_files as $plugin_file ) {
 
301
                if ( !is_readable( WPMU_PLUGIN_DIR . "/$plugin_file" ) )
 
302
                        continue;
 
303
 
 
304
                $plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached.
 
305
 
 
306
                if ( empty ( $plugin_data['Name'] ) )
 
307
                        $plugin_data['Name'] = $plugin_file;
 
308
 
 
309
                $wp_plugins[ $plugin_file ] = $plugin_data;
 
310
        }
 
311
 
 
312
        if ( isset( $wp_plugins['index.php'] ) && filesize( WPMU_PLUGIN_DIR . '/index.php') <= 30 ) // silence is golden
 
313
                unset( $wp_plugins['index.php'] );
 
314
 
 
315
        uasort( $wp_plugins, create_function( '$a, $b', 'return strnatcasecmp( $a["Name"], $b["Name"] );' ));
 
316
 
 
317
        return $wp_plugins;
 
318
}
 
319
 
 
320
/**
 
321
 * Check the wp-content directory and retrieve all drop-ins with any plugin data.
 
322
 *
 
323
 * @since 3.0.0
 
324
 * @return array Key is the file path and the value is an array of the plugin data.
 
325
 */
 
326
function get_dropins() {
 
327
        $dropins = array();
 
328
        $plugin_files = array();
 
329
 
 
330
        $_dropins = _get_dropins();
 
331
 
 
332
        // These exist in the wp-content directory
 
333
        if ( $plugins_dir = @ opendir( WP_CONTENT_DIR ) ) {
 
334
                while ( ( $file = readdir( $plugins_dir ) ) !== false ) {
 
335
                        if ( isset( $_dropins[ $file ] ) )
 
336
                                $plugin_files[] = $file;
 
337
                }
 
338
        } else {
 
339
                return $dropins;
 
340
        }
 
341
 
 
342
        @closedir( $plugins_dir );
 
343
 
 
344
        if ( empty($plugin_files) )
 
345
                return $dropins;
 
346
 
 
347
        foreach ( $plugin_files as $plugin_file ) {
 
348
                if ( !is_readable( WP_CONTENT_DIR . "/$plugin_file" ) )
 
349
                        continue;
 
350
                $plugin_data = get_plugin_data( WP_CONTENT_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached.
 
351
                if ( empty( $plugin_data['Name'] ) )
 
352
                        $plugin_data['Name'] = $plugin_file;
 
353
                $dropins[ $plugin_file ] = $plugin_data;
 
354
        }
 
355
 
 
356
        uksort( $dropins, create_function( '$a, $b', 'return strnatcasecmp( $a, $b );' ));
 
357
 
 
358
        return $dropins;
 
359
}
 
360
 
 
361
/**
 
362
 * Returns drop-ins that WordPress uses.
 
363
 *
 
364
 * Includes Multisite drop-ins only when is_multisite()
 
365
 *
 
366
 * @since 3.0.0
 
367
 * @return array Key is file name. The value is an array, with the first value the
 
368
 *      purpose of the drop-in and the second value the name of the constant that must be
 
369
 *      true for the drop-in to be used, or true if no constant is required.
 
370
 */
 
371
function _get_dropins() {
 
372
        $dropins = array(
 
373
                'advanced-cache.php' => array( __( 'Advanced caching plugin.'       ), 'WP_CACHE' ), // WP_CACHE
 
374
                'db.php'             => array( __( 'Custom database class.'         ), true ), // auto on load
 
375
                'db-error.php'       => array( __( 'Custom database error message.' ), true ), // auto on error
 
376
                'install.php'        => array( __( 'Custom install script.'         ), true ), // auto on install
 
377
                'maintenance.php'    => array( __( 'Custom maintenance message.'    ), true ), // auto on maintenance
 
378
                'object-cache.php'   => array( __( 'External object cache.'         ), true ), // auto on load
 
379
        );
 
380
 
 
381
        if ( is_multisite() ) {
 
382
                $dropins['sunrise.php'       ] = array( __( 'Executed before Multisite is loaded.' ), 'SUNRISE' ); // SUNRISE
 
383
                $dropins['blog-deleted.php'  ] = array( __( 'Custom site deleted message.'   ), true ); // auto on deleted blog
 
384
                $dropins['blog-inactive.php' ] = array( __( 'Custom site inactive message.'  ), true ); // auto on inactive blog
 
385
                $dropins['blog-suspended.php'] = array( __( 'Custom site suspended message.' ), true ); // auto on archived or spammed blog
 
386
        }
 
387
 
 
388
        return $dropins;
 
389
}
 
390
 
 
391
/**
 
392
 * Check whether the plugin is active by checking the active_plugins list.
 
393
 *
 
394
 * @since 2.5.0
 
395
 *
 
396
 * @param string $plugin Base plugin path from plugins directory.
 
397
 * @return bool True, if in the active plugins list. False, not in the list.
 
398
 */
 
399
function is_plugin_active( $plugin ) {
 
400
        return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
 
401
}
 
402
 
 
403
/**
 
404
 * Check whether the plugin is active for the entire network.
 
405
 *
 
406
 * @since 3.0.0
 
407
 *
 
408
 * @param string $plugin Base plugin path from plugins directory.
 
409
 * @return bool True, if active for the network, otherwise false.
 
410
 */
 
411
function is_plugin_active_for_network( $plugin ) {
 
412
        if ( !is_multisite() )
 
413
                return false;
 
414
 
 
415
        $plugins = get_site_option( 'active_sitewide_plugins');
 
416
        if ( isset($plugins[$plugin]) )
 
417
                return true;
 
418
 
 
419
        return false;
 
420
}
 
421
 
 
422
/**
 
423
 * Checks for "Network: true" in the plugin header to see if this should
 
424
 * be activated only as a network wide plugin. The plugin would also work
 
425
 * when Multisite is not enabled.
 
426
 *
 
427
 * Checks for "Site Wide Only: true" for backwards compatibility.
 
428
 *
 
429
 * @since 3.0.0
 
430
 *
 
431
 * @param $file Plugin to check
 
432
 * $return bool True if plugin is network only, false otherwise.
 
433
 */
 
434
function is_network_only_plugin( $plugin ) {
 
435
        $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
 
436
        if ( $plugin_data )
 
437
                return $plugin_data['Network'];
 
438
        return false;
 
439
}
 
440
 
 
441
/**
 
442
 * Attempts activation of plugin in a "sandbox" and redirects on success.
 
443
 *
 
444
 * A plugin that is already activated will not attempt to be activated again.
 
445
 *
 
446
 * The way it works is by setting the redirection to the error before trying to
 
447
 * include the plugin file. If the plugin fails, then the redirection will not
 
448
 * be overwritten with the success message. Also, the options will not be
 
449
 * updated and the activation hook will not be called on plugin error.
 
450
 *
 
451
 * It should be noted that in no way the below code will actually prevent errors
 
452
 * within the file. The code should not be used elsewhere to replicate the
 
453
 * "sandbox", which uses redirection to work.
 
454
 * {@source 13 1}
 
455
 *
 
456
 * If any errors are found or text is outputted, then it will be captured to
 
457
 * ensure that the success redirection will update the error redirection.
 
458
 *
 
459
 * @since unknown
 
460
 *
 
461
 * @param string $plugin Plugin path to main plugin file with plugin data.
 
462
 * @param string $redirect Optional. URL to redirect to.
 
463
 * @param bool $network_wide Whether to enable the plugin for all sites in the network or just the current site.  Multisite only. Default is false.
 
464
 * @return WP_Error|null WP_Error on invalid file or null on success.
 
465
 */
 
466
function activate_plugin( $plugin, $redirect = '', $network_wide = false) {
 
467
        $plugin  = plugin_basename( trim( $plugin ) );
 
468
 
 
469
        if ( is_multisite() && ( $network_wide || is_network_only_plugin($plugin) ) ) {
 
470
                $network_wide = true;
 
471
                $current = get_site_option( 'active_sitewide_plugins', array() );
 
472
        } else {
 
473
                $current = get_option( 'active_plugins', array() );
 
474
        }
 
475
 
 
476
        $valid = validate_plugin($plugin);
 
477
        if ( is_wp_error($valid) )
 
478
                return $valid;
 
479
 
 
480
        if ( !in_array($plugin, $current) ) {
 
481
                if ( !empty($redirect) )
 
482
                        wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error
 
483
                ob_start();
 
484
                include(WP_PLUGIN_DIR . '/' . $plugin);
 
485
                do_action( 'activate_plugin', trim( $plugin) );
 
486
                if ( $network_wide ) {
 
487
                        $current[$plugin] = time();
 
488
                        update_site_option( 'active_sitewide_plugins', $current );
 
489
                } else {
 
490
                        $current[] = $plugin;
 
491
                        sort($current);
 
492
                        update_option('active_plugins', $current);
 
493
                }
 
494
                do_action( 'activate_' . trim( $plugin ) );
 
495
                do_action( 'activated_plugin', trim( $plugin) );
 
496
                if ( ob_get_length() > 0 ) {
 
497
                        $output = ob_get_clean();
 
498
                        return new WP_Error('unexpected_output', __('The plugin generated unexpected output.'), $output);
 
499
                }
 
500
                ob_end_clean();
 
501
        }
 
502
 
 
503
        return null;
 
504
}
 
505
 
 
506
/**
 
507
 * Deactivate a single plugin or multiple plugins.
 
508
 *
 
509
 * The deactivation hook is disabled by the plugin upgrader by using the $silent
 
510
 * parameter.
 
511
 *
 
512
 * @since unknown
 
513
 *
 
514
 * @param string|array $plugins Single plugin or list of plugins to deactivate.
 
515
 * @param bool $silent Optional, default is false. Prevent calling deactivate hook.
 
516
 */
 
517
function deactivate_plugins( $plugins, $silent = false ) {
 
518
        $network_current = get_site_option( 'active_sitewide_plugins', array() );
 
519
        $current = get_option( 'active_plugins', array() );
 
520
        $do_blog = $do_network = false;
 
521
 
 
522
        foreach ( (array) $plugins as $plugin ) {
 
523
                $plugin = plugin_basename($plugin);
 
524
                if ( ! is_plugin_active($plugin) )
 
525
                        continue;
 
526
                if ( ! $silent )
 
527
                        do_action( 'deactivate_plugin', trim( $plugin ) );
 
528
 
 
529
                if ( is_plugin_active_for_network($plugin) ) {
 
530
                        // Deactivate network wide
 
531
                        $do_network = true;
 
532
                        unset( $network_current[ $plugin ] );
 
533
                } else {
 
534
                        // Deactivate for this blog only
 
535
                        $key = array_search( $plugin, (array) $current );
 
536
                        if ( false !== $key ) {
 
537
                                $do_blog = true;
 
538
                                array_splice( $current, $key, 1 );
 
539
                        }
 
540
                }
 
541
 
 
542
                //Used by Plugin updater to internally deactivate plugin, however, not to notify plugins of the fact to prevent plugin output.
 
543
                if ( ! $silent ) {
 
544
                        do_action( 'deactivate_' . trim( $plugin ) );
 
545
                        do_action( 'deactivated_plugin', trim( $plugin ) );
 
546
                }
 
547
        }
 
548
 
 
549
        if ( $do_blog )
 
550
                update_option('active_plugins', $current);
 
551
        if ( $do_network )
 
552
                update_site_option( 'active_sitewide_plugins', $network_current );
 
553
}
 
554
 
 
555
/**
 
556
 * Activate multiple plugins.
 
557
 *
 
558
 * When WP_Error is returned, it does not mean that one of the plugins had
 
559
 * errors. It means that one or more of the plugins file path was invalid.
 
560
 *
 
561
 * The execution will be halted as soon as one of the plugins has an error.
 
562
 *
 
563
 * @since unknown
 
564
 *
 
565
 * @param string|array $plugins
 
566
 * @param string $redirect Redirect to page after successful activation.
 
567
 * @param bool $network_wide Whether to enable the plugin for all sites in the network.
 
568
 * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation.
 
569
 */
 
570
function activate_plugins($plugins, $redirect = '', $network_wide) {
 
571
        if ( !is_array($plugins) )
 
572
                $plugins = array($plugins);
 
573
 
 
574
        $errors = array();
 
575
        foreach ( (array) $plugins as $plugin ) {
 
576
                if ( !empty($redirect) )
 
577
                        $redirect = add_query_arg('plugin', $plugin, $redirect);
 
578
                $result = activate_plugin($plugin, $redirect, $network_wide);
 
579
                if ( is_wp_error($result) )
 
580
                        $errors[$plugin] = $result;
 
581
        }
 
582
 
 
583
        if ( !empty($errors) )
 
584
                return new WP_Error('plugins_invalid', __('One of the plugins is invalid.'), $errors);
 
585
 
 
586
        return true;
 
587
}
 
588
 
 
589
/**
 
590
 * Remove directory and files of a plugin for a single or list of plugin(s).
 
591
 *
 
592
 * If the plugins parameter list is empty, false will be returned. True when
 
593
 * completed.
 
594
 *
 
595
 * @since unknown
 
596
 *
 
597
 * @param array $plugins List of plugin
 
598
 * @param string $redirect Redirect to page when complete.
 
599
 * @return mixed
 
600
 */
 
601
function delete_plugins($plugins, $redirect = '' ) {
 
602
        global $wp_filesystem;
 
603
 
 
604
        if ( empty($plugins) )
 
605
                return false;
 
606
 
 
607
        $checked = array();
 
608
        foreach( $plugins as $plugin )
 
609
                $checked[] = 'checked[]=' . $plugin;
 
610
 
 
611
        ob_start();
 
612
        $url = wp_nonce_url('plugins.php?action=delete-selected&verify-delete=1&' . implode('&', $checked), 'bulk-manage-plugins');
 
613
        if ( false === ($credentials = request_filesystem_credentials($url)) ) {
 
614
                $data = ob_get_contents();
 
615
                ob_end_clean();
 
616
                if ( ! empty($data) ){
 
617
                        include_once( ABSPATH . 'wp-admin/admin-header.php');
 
618
                        echo $data;
 
619
                        include( ABSPATH . 'wp-admin/admin-footer.php');
 
620
                        exit;
 
621
                }
 
622
                return;
 
623
        }
 
624
 
 
625
        if ( ! WP_Filesystem($credentials) ) {
 
626
                request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
 
627
                $data = ob_get_contents();
 
628
                ob_end_clean();
 
629
                if ( ! empty($data) ){
 
630
                        include_once( ABSPATH . 'wp-admin/admin-header.php');
 
631
                        echo $data;
 
632
                        include( ABSPATH . 'wp-admin/admin-footer.php');
 
633
                        exit;
 
634
                }
 
635
                return;
 
636
        }
 
637
 
 
638
        if ( ! is_object($wp_filesystem) )
 
639
                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
 
640
 
 
641
        if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
 
642
                return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors);
 
643
 
 
644
        //Get the base plugin folder
 
645
        $plugins_dir = $wp_filesystem->wp_plugins_dir();
 
646
        if ( empty($plugins_dir) )
 
647
                return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
 
648
 
 
649
        $plugins_dir = trailingslashit( $plugins_dir );
 
650
 
 
651
        $errors = array();
 
652
 
 
653
        foreach( $plugins as $plugin_file ) {
 
654
                // Run Uninstall hook
 
655
                if ( is_uninstallable_plugin( $plugin_file ) )
 
656
                        uninstall_plugin($plugin_file);
 
657
 
 
658
                $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin_file) );
 
659
                // If plugin is in its own directory, recursively delete the directory.
 
660
                if ( strpos($plugin_file, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
 
661
                        $deleted = $wp_filesystem->delete($this_plugin_dir, true);
 
662
                else
 
663
                        $deleted = $wp_filesystem->delete($plugins_dir . $plugin_file);
 
664
 
 
665
                if ( ! $deleted )
 
666
                        $errors[] = $plugin_file;
 
667
        }
 
668
 
 
669
        if ( ! empty($errors) )
 
670
                return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s.'), implode(', ', $errors)) );
 
671
 
 
672
        // Force refresh of plugin update information
 
673
        if ( $current = get_site_transient('update_plugins') ) {
 
674
                unset( $current->response[ $plugin_file ] );
 
675
                set_site_transient('update_plugins', $current);
 
676
        }
 
677
 
 
678
        return true;
 
679
}
 
680
 
 
681
/**
 
682
 * Validate active plugins
 
683
 *
 
684
 * Validate all active plugins, deactivates invalid and
 
685
 * returns an array of deactivated ones.
 
686
 *
 
687
 * @since unknown
 
688
 * @return array invalid plugins, plugin as key, error as value
 
689
 */
 
690
function validate_active_plugins() {
 
691
        $plugins = get_option( 'active_plugins', array() );
 
692
        // validate vartype: array
 
693
        if ( ! is_array( $plugins ) ) {
 
694
                update_option( 'active_plugins', array() );
 
695
                $plugins = array();
 
696
        }
 
697
 
 
698
        if ( is_multisite() && is_super_admin() ) {
 
699
                $network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
 
700
                $plugins = array_merge( $plugins, array_keys( $network_plugins ) );
 
701
        }
 
702
 
 
703
        if ( empty( $plugins ) )
 
704
                return;
 
705
 
 
706
        $invalid = array();
 
707
 
 
708
        // invalid plugins get deactivated
 
709
        foreach ( $plugins as $plugin ) {
 
710
                $result = validate_plugin( $plugin );
 
711
                if ( is_wp_error( $result ) ) {
 
712
                        $invalid[$plugin] = $result;
 
713
                        deactivate_plugins( $plugin, true );
 
714
                }
 
715
        }
 
716
        return $invalid;
 
717
}
 
718
 
 
719
/**
 
720
 * Validate the plugin path.
 
721
 *
 
722
 * Checks that the file exists and {@link validate_file() is valid file}.
 
723
 *
 
724
 * @since unknown
 
725
 *
 
726
 * @param string $plugin Plugin Path
 
727
 * @return WP_Error|int 0 on success, WP_Error on failure.
 
728
 */
 
729
function validate_plugin($plugin) {
 
730
        if ( validate_file($plugin) )
 
731
                return new WP_Error('plugin_invalid', __('Invalid plugin path.'));
 
732
        if ( ! file_exists(WP_PLUGIN_DIR . '/' . $plugin) )
 
733
                return new WP_Error('plugin_not_found', __('Plugin file does not exist.'));
 
734
 
 
735
        $installed_plugins = get_plugins();
 
736
        if ( ! isset($installed_plugins[$plugin]) )
 
737
                return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.'));
 
738
        return 0;
 
739
}
 
740
 
 
741
/**
 
742
 * Whether the plugin can be uninstalled.
 
743
 *
 
744
 * @since 2.7.0
 
745
 *
 
746
 * @param string $plugin Plugin path to check.
 
747
 * @return bool Whether plugin can be uninstalled.
 
748
 */
 
749
function is_uninstallable_plugin($plugin) {
 
750
        $file = plugin_basename($plugin);
 
751
 
 
752
        $uninstallable_plugins = (array) get_option('uninstall_plugins');
 
753
        if ( isset( $uninstallable_plugins[$file] ) || file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) )
 
754
                return true;
 
755
 
 
756
        return false;
 
757
}
 
758
 
 
759
/**
 
760
 * Uninstall a single plugin.
 
761
 *
 
762
 * Calls the uninstall hook, if it is available.
 
763
 *
 
764
 * @since 2.7.0
 
765
 *
 
766
 * @param string $plugin Relative plugin path from Plugin Directory.
 
767
 */
 
768
function uninstall_plugin($plugin) {
 
769
        $file = plugin_basename($plugin);
 
770
 
 
771
        $uninstallable_plugins = (array) get_option('uninstall_plugins');
 
772
        if ( file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) {
 
773
                if ( isset( $uninstallable_plugins[$file] ) ) {
 
774
                        unset($uninstallable_plugins[$file]);
 
775
                        update_option('uninstall_plugins', $uninstallable_plugins);
 
776
                }
 
777
                unset($uninstallable_plugins);
 
778
 
 
779
                define('WP_UNINSTALL_PLUGIN', $file);
 
780
                include WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php';
 
781
 
 
782
                return true;
 
783
        }
 
784
 
 
785
        if ( isset( $uninstallable_plugins[$file] ) ) {
 
786
                $callable = $uninstallable_plugins[$file];
 
787
                unset($uninstallable_plugins[$file]);
 
788
                update_option('uninstall_plugins', $uninstallable_plugins);
 
789
                unset($uninstallable_plugins);
 
790
 
 
791
                include WP_PLUGIN_DIR . '/' . $file;
 
792
 
 
793
                add_action( 'uninstall_' . $file, $callable );
 
794
                do_action( 'uninstall_' . $file );
 
795
        }
 
796
}
 
797
 
 
798
//
 
799
// Menu
 
800
//
 
801
 
 
802
/**
 
803
 * Add a top level menu page
 
804
 *
 
805
 * This function takes a capability which will be used to determine whether
 
806
 * or not a page is included in the menu.
 
807
 *
 
808
 * The function which is hooked in to handle the output of the page must check
 
809
 * that the user has the required capability as well.
 
810
 *
 
811
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
812
 * @param string $menu_title The text to be used for the menu
 
813
 * @param string $capability The capability required for this menu to be displayed to the user.
 
814
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
815
 * @param callback $function The function to be called to output the content for this page.
 
816
 * @param string $icon_url The url to the icon to be used for this menu
 
817
 * @param int $position The position in the menu order this one should appear
 
818
 */
 
819
function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = NULL ) {
 
820
        global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages;
 
821
 
 
822
        $menu_slug = plugin_basename( $menu_slug );
 
823
 
 
824
        $admin_page_hooks[$menu_slug] = sanitize_title( $menu_title );
 
825
 
 
826
        $hookname = get_plugin_page_hookname( $menu_slug, '' );
 
827
 
 
828
        if ( !empty( $function ) && !empty( $hookname ) && current_user_can( $capability ) )
 
829
                add_action( $hookname, $function );
 
830
 
 
831
        if ( empty($icon_url) )
 
832
                $icon_url = esc_url( admin_url( 'images/generic.png' ) );
 
833
        elseif ( is_ssl() && 0 === strpos($icon_url, 'http://') )
 
834
                $icon_url = 'https://' . substr($icon_url, 7);
 
835
 
 
836
        $new_menu = array( $menu_title, $capability, $menu_slug, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url );
 
837
 
 
838
        if ( null === $position  )
 
839
                $menu[] = $new_menu;
 
840
        else
 
841
                $menu[$position] = $new_menu;
 
842
 
 
843
        $_registered_pages[$hookname] = true;
 
844
 
 
845
        // No parent as top level
 
846
        $_parent_pages[$menu_slug] = false;
 
847
 
 
848
        return $hookname;
 
849
}
 
850
 
 
851
/**
 
852
 * Add a top level menu page in the 'objects' section
 
853
 *
 
854
 * This function takes a capability which will be used to determine whether
 
855
 * or not a page is included in the menu.
 
856
 *
 
857
 * The function which is hooked in to handle the output of the page must check
 
858
 * that the user has the required capability as well.
 
859
 *
 
860
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
861
 * @param string $menu_title The text to be used for the menu
 
862
 * @param string $capability The capability required for this menu to be displayed to the user.
 
863
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
864
 * @param callback $function The function to be called to output the content for this page.
 
865
 * @param string $icon_url The url to the icon to be used for this menu
 
866
 */
 
867
function add_object_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '') {
 
868
        global $_wp_last_object_menu;
 
869
 
 
870
        $_wp_last_object_menu++;
 
871
 
 
872
        return add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $_wp_last_object_menu);
 
873
}
 
874
 
 
875
/**
 
876
 * Add a top level menu page in the 'utility' section
 
877
 *
 
878
 * This function takes a capability which will be used to determine whether
 
879
 * or not a page is included in the menu.
 
880
 *
 
881
 * The function which is hooked in to handle the output of the page must check
 
882
 * that the user has the required capability as well.
 
883
 *
 
884
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
885
 * @param string $menu_title The text to be used for the menu
 
886
 * @param string $capability The capability required for this menu to be displayed to the user.
 
887
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
888
 * @param callback $function The function to be called to output the content for this page.
 
889
 * @param string $icon_url The url to the icon to be used for this menu
 
890
 */
 
891
function add_utility_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '') {
 
892
        global $_wp_last_utility_menu;
 
893
 
 
894
        $_wp_last_utility_menu++;
 
895
 
 
896
        return add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $_wp_last_utility_menu);
 
897
}
 
898
 
 
899
/**
 
900
 * Add a sub menu page
 
901
 *
 
902
 * This function takes a capability which will be used to determine whether
 
903
 * or not a page is included in the menu.
 
904
 *
 
905
 * The function which is hooked in to handle the output of the page must check
 
906
 * that the user has the required capability as well.
 
907
 *
 
908
 * @param string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page)
 
909
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
910
 * @param string $menu_title The text to be used for the menu
 
911
 * @param string $capability The capability required for this menu to be displayed to the user.
 
912
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
913
 * @param callback $function The function to be called to output the content for this page.
 
914
 */
 
915
function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
916
        global $submenu;
 
917
        global $menu;
 
918
        global $_wp_real_parent_file;
 
919
        global $_wp_submenu_nopriv;
 
920
        global $_registered_pages;
 
921
        global $_parent_pages;
 
922
 
 
923
        $menu_slug = plugin_basename( $menu_slug );
 
924
        $parent_slug = plugin_basename( $parent_slug);
 
925
 
 
926
        if ( isset( $_wp_real_parent_file[$parent_slug] ) )
 
927
                $parent_slug = $_wp_real_parent_file[$parent_slug];
 
928
 
 
929
        if ( !current_user_can( $capability ) ) {
 
930
                $_wp_submenu_nopriv[$parent_slug][$menu_slug] = true;
 
931
                return false;
 
932
        }
 
933
 
 
934
        // If the parent doesn't already have a submenu, add a link to the parent
 
935
        // as the first item in the submenu.  If the submenu file is the same as the
 
936
        // parent file someone is trying to link back to the parent manually.  In
 
937
        // this case, don't automatically add a link back to avoid duplication.
 
938
        if (!isset( $submenu[$parent_slug] ) && $menu_slug != $parent_slug  ) {
 
939
                foreach ( (array)$menu as $parent_menu ) {
 
940
                        if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) )
 
941
                                $submenu[$parent_slug][] = $parent_menu;
 
942
                }
 
943
        }
 
944
 
 
945
        $submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );
 
946
 
 
947
        $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug);
 
948
        if (!empty ( $function ) && !empty ( $hookname ))
 
949
                add_action( $hookname, $function );
 
950
 
 
951
        $_registered_pages[$hookname] = true;
 
952
        // backwards-compatibility for plugins using add_management page.  See wp-admin/admin.php for redirect from edit.php to tools.php
 
953
        if ( 'tools.php' == $parent_slug )
 
954
                $_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true;
 
955
 
 
956
        // No parent as top level
 
957
        $_parent_pages[$menu_slug] = $parent_slug;
 
958
 
 
959
        return $hookname;
 
960
}
 
961
 
 
962
/**
 
963
 * Add sub menu page to the tools main menu.
 
964
*
 
965
 * This function takes a capability which will be used to determine whether
 
966
 * or not a page is included in the menu.
 
967
 *
 
968
 * The function which is hooked in to handle the output of the page must check
 
969
 * that the user has the required capability as well.
 
970
 *
 
971
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
972
 * @param string $menu_title The text to be used for the menu
 
973
 * @param string $capability The capability required for this menu to be displayed to the user.
 
974
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
975
 * @param callback $function The function to be called to output the content for this page.
 
976
 */
 
977
function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
978
        return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
979
}
 
980
 
 
981
/**
 
982
 * Add sub menu page to the options main menu.
 
983
*
 
984
 * This function takes a capability which will be used to determine whether
 
985
 * or not a page is included in the menu.
 
986
 *
 
987
 * The function which is hooked in to handle the output of the page must check
 
988
 * that the user has the required capability as well.
 
989
 *
 
990
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
991
 * @param string $menu_title The text to be used for the menu
 
992
 * @param string $capability The capability required for this menu to be displayed to the user.
 
993
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
994
 * @param callback $function The function to be called to output the content for this page.
 
995
 */
 
996
function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
997
        return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
998
}
 
999
 
 
1000
/**
 
1001
 * Add sub menu page to the themes main menu.
 
1002
*
 
1003
 * This function takes a capability which will be used to determine whether
 
1004
 * or not a page is included in the menu.
 
1005
 *
 
1006
 * The function which is hooked in to handle the output of the page must check
 
1007
 * that the user has the required capability as well.
 
1008
 *
 
1009
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1010
 * @param string $menu_title The text to be used for the menu
 
1011
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1012
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1013
 * @param callback $function The function to be called to output the content for this page.
 
1014
 */
 
1015
function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1016
        return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1017
}
 
1018
 
 
1019
/**
 
1020
 * Add sub menu page to the plugins main menu.
 
1021
*
 
1022
 * This function takes a capability which will be used to determine whether
 
1023
 * or not a page is included in the menu.
 
1024
 *
 
1025
 * The function which is hooked in to handle the output of the page must check
 
1026
 * that the user has the required capability as well.
 
1027
 *
 
1028
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1029
 * @param string $menu_title The text to be used for the menu
 
1030
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1031
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1032
 * @param callback $function The function to be called to output the content for this page.
 
1033
 */
 
1034
function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1035
        return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1036
}
 
1037
 
 
1038
/**
 
1039
 * Add sub menu page to the Users/Profile main menu.
 
1040
*
 
1041
 * This function takes a capability which will be used to determine whether
 
1042
 * or not a page is included in the menu.
 
1043
 *
 
1044
 * The function which is hooked in to handle the output of the page must check
 
1045
 * that the user has the required capability as well.
 
1046
 *
 
1047
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1048
 * @param string $menu_title The text to be used for the menu
 
1049
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1050
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1051
 * @param callback $function The function to be called to output the content for this page.
 
1052
 */
 
1053
function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1054
        if ( current_user_can('edit_users') )
 
1055
                $parent = 'users.php';
 
1056
        else
 
1057
                $parent = 'profile.php';
 
1058
        return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $function );
 
1059
}
 
1060
/**
 
1061
 * Add sub menu page to the Dashboard main menu.
 
1062
*
 
1063
 * This function takes a capability which will be used to determine whether
 
1064
 * or not a page is included in the menu.
 
1065
 *
 
1066
 * The function which is hooked in to handle the output of the page must check
 
1067
 * that the user has the required capability as well.
 
1068
 *
 
1069
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1070
 * @param string $menu_title The text to be used for the menu
 
1071
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1072
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1073
 * @param callback $function The function to be called to output the content for this page.
 
1074
 */
 
1075
function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1076
        return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1077
}
 
1078
 
 
1079
/**
 
1080
 * Add sub menu page to the posts main menu.
 
1081
*
 
1082
 * This function takes a capability which will be used to determine whether
 
1083
 * or not a page is included in the menu.
 
1084
 *
 
1085
 * The function which is hooked in to handle the output of the page must check
 
1086
 * that the user has the required capability as well.
 
1087
 *
 
1088
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1089
 * @param string $menu_title The text to be used for the menu
 
1090
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1091
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1092
 * @param callback $function The function to be called to output the content for this page.
 
1093
 */
 
1094
function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1095
        return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1096
}
 
1097
 
 
1098
/**
 
1099
 * Add sub menu page to the media main menu.
 
1100
*
 
1101
 * This function takes a capability which will be used to determine whether
 
1102
 * or not a page is included in the menu.
 
1103
 *
 
1104
 * The function which is hooked in to handle the output of the page must check
 
1105
 * that the user has the required capability as well.
 
1106
 *
 
1107
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1108
 * @param string $menu_title The text to be used for the menu
 
1109
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1110
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1111
 * @param callback $function The function to be called to output the content for this page.
 
1112
 */
 
1113
function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1114
        return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1115
}
 
1116
 
 
1117
/**
 
1118
 * Add sub menu page to the links main menu.
 
1119
*
 
1120
 * This function takes a capability which will be used to determine whether
 
1121
 * or not a page is included in the menu.
 
1122
 *
 
1123
 * The function which is hooked in to handle the output of the page must check
 
1124
 * that the user has the required capability as well.
 
1125
 *
 
1126
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1127
 * @param string $menu_title The text to be used for the menu
 
1128
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1129
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1130
 * @param callback $function The function to be called to output the content for this page.
 
1131
 */
 
1132
function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1133
        return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1134
}
 
1135
 
 
1136
/**
 
1137
 * Add sub menu page to the pages main menu.
 
1138
*
 
1139
 * This function takes a capability which will be used to determine whether
 
1140
 * or not a page is included in the menu.
 
1141
 *
 
1142
 * The function which is hooked in to handle the output of the page must check
 
1143
 * that the user has the required capability as well.
 
1144
 *
 
1145
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1146
 * @param string $menu_title The text to be used for the menu
 
1147
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1148
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1149
 * @param callback $function The function to be called to output the content for this page.
 
1150
 */
 
1151
function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1152
        return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1153
}
 
1154
 
 
1155
/**
 
1156
 * Add sub menu page to the comments main menu.
 
1157
*
 
1158
 * This function takes a capability which will be used to determine whether
 
1159
 * or not a page is included in the menu.
 
1160
 *
 
1161
 * The function which is hooked in to handle the output of the page must check
 
1162
 * that the user has the required capability as well.
 
1163
 *
 
1164
 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
 
1165
 * @param string $menu_title The text to be used for the menu
 
1166
 * @param string $capability The capability required for this menu to be displayed to the user.
 
1167
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1168
 * @param callback $function The function to be called to output the content for this page.
 
1169
 */
 
1170
function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
 
1171
        return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function );
 
1172
}
 
1173
 
 
1174
/**
 
1175
 * Get the url to access a particular menu page based on the slug it was registered with.
 
1176
 *
 
1177
 * If the slug hasn't been registered properly no url will be returned
 
1178
 *
 
1179
 * @since 3.0
 
1180
 *
 
1181
 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
 
1182
 * @param bool $echo Whether or not to echo the url - default is true
 
1183
 * @return string the url
 
1184
 */
 
1185
function menu_page_url($menu_slug, $echo = true) {
 
1186
        global $_parent_pages;
 
1187
 
 
1188
        if ( isset( $_parent_pages[$menu_slug] ) ) {
 
1189
                if ( $_parent_pages[$menu_slug] ) {
 
1190
                        $url = admin_url( add_query_arg( 'page', $menu_slug, $_parent_pages[$menu_slug] ) );
 
1191
                } else {
 
1192
                        $url = admin_url('admin.php?page=' . $menu_slug);
 
1193
                }
 
1194
        } else {
 
1195
                $url = '';
 
1196
        }
 
1197
 
 
1198
        $url = esc_url($url);
 
1199
 
 
1200
        if ( $echo )
 
1201
                echo $url;
 
1202
 
 
1203
        return $url;
 
1204
}
 
1205
 
 
1206
//
 
1207
// Pluggable Menu Support -- Private
 
1208
//
 
1209
 
 
1210
function get_admin_page_parent( $parent = '' ) {
 
1211
        global $parent_file;
 
1212
        global $menu;
 
1213
        global $submenu;
 
1214
        global $pagenow;
 
1215
        global $typenow;
 
1216
        global $plugin_page;
 
1217
        global $_wp_real_parent_file;
 
1218
        global $_wp_menu_nopriv;
 
1219
        global $_wp_submenu_nopriv;
 
1220
 
 
1221
        if ( !empty ( $parent ) && 'admin.php' != $parent ) {
 
1222
                if ( isset( $_wp_real_parent_file[$parent] ) )
 
1223
                        $parent = $_wp_real_parent_file[$parent];
 
1224
                return $parent;
 
1225
        }
 
1226
 
 
1227
        /*
 
1228
        if ( !empty ( $parent_file ) ) {
 
1229
                if ( isset( $_wp_real_parent_file[$parent_file] ) )
 
1230
                        $parent_file = $_wp_real_parent_file[$parent_file];
 
1231
 
 
1232
                return $parent_file;
 
1233
        }
 
1234
        */
 
1235
 
 
1236
        if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) {
 
1237
                foreach ( (array)$menu as $parent_menu ) {
 
1238
                        if ( $parent_menu[2] == $plugin_page ) {
 
1239
                                $parent_file = $plugin_page;
 
1240
                                if ( isset( $_wp_real_parent_file[$parent_file] ) )
 
1241
                                        $parent_file = $_wp_real_parent_file[$parent_file];
 
1242
                                return $parent_file;
 
1243
                        }
 
1244
                }
 
1245
                if ( isset( $_wp_menu_nopriv[$plugin_page] ) ) {
 
1246
                        $parent_file = $plugin_page;
 
1247
                        if ( isset( $_wp_real_parent_file[$parent_file] ) )
 
1248
                                        $parent_file = $_wp_real_parent_file[$parent_file];
 
1249
                        return $parent_file;
 
1250
                }
 
1251
        }
 
1252
 
 
1253
        if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) {
 
1254
                $parent_file = $pagenow;
 
1255
                if ( isset( $_wp_real_parent_file[$parent_file] ) )
 
1256
                        $parent_file = $_wp_real_parent_file[$parent_file];
 
1257
                return $parent_file;
 
1258
        }
 
1259
 
 
1260
        foreach (array_keys( (array)$submenu ) as $parent) {
 
1261
                foreach ( $submenu[$parent] as $submenu_array ) {
 
1262
                        if ( isset( $_wp_real_parent_file[$parent] ) )
 
1263
                                $parent = $_wp_real_parent_file[$parent];
 
1264
                        if ( !empty($typenow) && ($submenu_array[2] == "$pagenow?post_type=$typenow") ) {
 
1265
                                $parent_file = $parent;
 
1266
                                return $parent;
 
1267
                        } elseif ( $submenu_array[2] == $pagenow && empty($typenow) && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) {
 
1268
                                $parent_file = $parent;
 
1269
                                return $parent;
 
1270
                        } else
 
1271
                                if ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) {
 
1272
                                        $parent_file = $parent;
 
1273
                                        return $parent;
 
1274
                                }
 
1275
                }
 
1276
        }
 
1277
 
 
1278
        if ( empty($parent_file) )
 
1279
                $parent_file = '';
 
1280
        return '';
 
1281
}
 
1282
 
 
1283
function get_admin_page_title() {
 
1284
        global $title;
 
1285
        global $menu;
 
1286
        global $submenu;
 
1287
        global $pagenow;
 
1288
        global $plugin_page;
 
1289
        global $typenow;
 
1290
 
 
1291
        if ( ! empty ( $title ) )
 
1292
                return $title;
 
1293
 
 
1294
        $hook = get_plugin_page_hook( $plugin_page, $pagenow );
 
1295
 
 
1296
        $parent = $parent1 = get_admin_page_parent();
 
1297
 
 
1298
        if ( empty ( $parent) ) {
 
1299
                foreach ( (array)$menu as $menu_array ) {
 
1300
                        if ( isset( $menu_array[3] ) ) {
 
1301
                                if ( $menu_array[2] == $pagenow ) {
 
1302
                                        $title = $menu_array[3];
 
1303
                                        return $menu_array[3];
 
1304
                                } else
 
1305
                                        if ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) {
 
1306
                                                $title = $menu_array[3];
 
1307
                                                return $menu_array[3];
 
1308
                                        }
 
1309
                        } else {
 
1310
                                $title = $menu_array[0];
 
1311
                                return $title;
 
1312
                        }
 
1313
                }
 
1314
        } else {
 
1315
                foreach ( array_keys( $submenu ) as $parent ) {
 
1316
                        foreach ( $submenu[$parent] as $submenu_array ) {
 
1317
                                if ( isset( $plugin_page ) &&
 
1318
                                        ( $plugin_page == $submenu_array[2] ) &&
 
1319
                                        (
 
1320
                                                ( $parent == $pagenow ) ||
 
1321
                                                ( $parent == $plugin_page ) ||
 
1322
                                                ( $plugin_page == $hook ) ||
 
1323
                                                ( $pagenow == 'admin.php' && $parent1 != $submenu_array[2] ) ||
 
1324
                                                ( !empty($typenow) && $parent == $pagenow . '?post_type=' . $typenow)
 
1325
                                        )
 
1326
                                        ) {
 
1327
                                                $title = $submenu_array[3];
 
1328
                                                return $submenu_array[3];
 
1329
                                        }
 
1330
 
 
1331
                                if ( $submenu_array[2] != $pagenow || isset( $_GET['page'] ) ) // not the current page
 
1332
                                        continue;
 
1333
 
 
1334
                                if ( isset( $submenu_array[3] ) ) {
 
1335
                                        $title = $submenu_array[3];
 
1336
                                        return $submenu_array[3];
 
1337
                                } else {
 
1338
                                        $title = $submenu_array[0];
 
1339
                                        return $title;
 
1340
                                }
 
1341
                        }
 
1342
                }
 
1343
                if ( empty ( $title ) ) {
 
1344
                        foreach ( $menu as $menu_array ) {
 
1345
                                if ( isset( $plugin_page ) &&
 
1346
                                        ( $plugin_page == $menu_array[2] ) &&
 
1347
                                        ( $pagenow == 'admin.php' ) &&
 
1348
                                        ( $parent1 == $menu_array[2] ) )
 
1349
                                        {
 
1350
                                                $title = $menu_array[3];
 
1351
                                                return $menu_array[3];
 
1352
                                        }
 
1353
                        }
 
1354
                }
 
1355
        }
 
1356
 
 
1357
        return $title;
 
1358
}
 
1359
 
 
1360
function get_plugin_page_hook( $plugin_page, $parent_page ) {
 
1361
        $hook = get_plugin_page_hookname( $plugin_page, $parent_page );
 
1362
        if ( has_action($hook) )
 
1363
                return $hook;
 
1364
        else
 
1365
                return null;
 
1366
}
 
1367
 
 
1368
function get_plugin_page_hookname( $plugin_page, $parent_page ) {
 
1369
        global $admin_page_hooks;
 
1370
 
 
1371
        $parent = get_admin_page_parent( $parent_page );
 
1372
 
 
1373
        $page_type = 'admin';
 
1374
        if ( empty ( $parent_page ) || 'admin.php' == $parent_page || isset( $admin_page_hooks[$plugin_page] ) ) {
 
1375
                if ( isset( $admin_page_hooks[$plugin_page] ) )
 
1376
                        $page_type = 'toplevel';
 
1377
                else
 
1378
                        if ( isset( $admin_page_hooks[$parent] ))
 
1379
                                $page_type = $admin_page_hooks[$parent];
 
1380
        } else if ( isset( $admin_page_hooks[$parent] ) ) {
 
1381
                $page_type = $admin_page_hooks[$parent];
 
1382
        }
 
1383
 
 
1384
        $plugin_name = preg_replace( '!\.php!', '', $plugin_page );
 
1385
 
 
1386
        return $page_type . '_page_' . $plugin_name;
 
1387
}
 
1388
 
 
1389
function user_can_access_admin_page() {
 
1390
        global $pagenow;
 
1391
        global $menu;
 
1392
        global $submenu;
 
1393
        global $_wp_menu_nopriv;
 
1394
        global $_wp_submenu_nopriv;
 
1395
        global $plugin_page;
 
1396
        global $_registered_pages;
 
1397
 
 
1398
        $parent = get_admin_page_parent();
 
1399
 
 
1400
        if ( !isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$parent][$pagenow] ) )
 
1401
                return false;
 
1402
 
 
1403
        if ( isset( $plugin_page ) ) {
 
1404
                if ( isset( $_wp_submenu_nopriv[$parent][$plugin_page] ) )
 
1405
                        return false;
 
1406
 
 
1407
                $hookname = get_plugin_page_hookname($plugin_page, $parent);
 
1408
 
 
1409
                if ( !isset($_registered_pages[$hookname]) )
 
1410
                        return false;
 
1411
        }
 
1412
 
 
1413
        if ( empty( $parent) ) {
 
1414
                if ( isset( $_wp_menu_nopriv[$pagenow] ) )
 
1415
                        return false;
 
1416
                if ( isset( $_wp_submenu_nopriv[$pagenow][$pagenow] ) )
 
1417
                        return false;
 
1418
                if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) )
 
1419
                        return false;
 
1420
                if ( isset( $plugin_page ) && isset( $_wp_menu_nopriv[$plugin_page] ) )
 
1421
                        return false;
 
1422
                foreach (array_keys( $_wp_submenu_nopriv ) as $key ) {
 
1423
                        if ( isset( $_wp_submenu_nopriv[$key][$pagenow] ) )
 
1424
                                return false;
 
1425
                        if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$key][$plugin_page] ) )
 
1426
                        return false;
 
1427
                }
 
1428
                return true;
 
1429
        }
 
1430
 
 
1431
        if ( isset( $plugin_page ) && ( $plugin_page == $parent ) && isset( $_wp_menu_nopriv[$plugin_page] ) )
 
1432
                return false;
 
1433
 
 
1434
        if ( isset( $submenu[$parent] ) ) {
 
1435
                foreach ( $submenu[$parent] as $submenu_array ) {
 
1436
                        if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) {
 
1437
                                if ( current_user_can( $submenu_array[1] ))
 
1438
                                        return true;
 
1439
                                else
 
1440
                                        return false;
 
1441
                        } else if ( $submenu_array[2] == $pagenow ) {
 
1442
                                if ( current_user_can( $submenu_array[1] ))
 
1443
                                        return true;
 
1444
                                else
 
1445
                                        return false;
 
1446
                        }
 
1447
                }
 
1448
        }
 
1449
 
 
1450
        foreach ( $menu as $menu_array ) {
 
1451
                if ( $menu_array[2] == $parent) {
 
1452
                        if ( current_user_can( $menu_array[1] ))
 
1453
                                return true;
 
1454
                        else
 
1455
                                return false;
 
1456
                }
 
1457
        }
 
1458
 
 
1459
        return true;
 
1460
}
 
1461
 
 
1462
/* Whitelist functions */
 
1463
 
 
1464
/**
 
1465
 * Register a setting and its sanitization callback
 
1466
 *
 
1467
 * @since 2.7.0
 
1468
 *
 
1469
 * @param string $option_group A settings group name.  Should correspond to a whitelisted option key name.
 
1470
 *      Default whitelisted option key names include "general," "discussion," and "reading," among others.
 
1471
 * @param string $option_name The name of an option to sanitize and save.
 
1472
 * @param unknown_type $sanitize_callback A callback function that sanitizes the option's value.
 
1473
 * @return unknown
 
1474
 */
 
1475
function register_setting( $option_group, $option_name, $sanitize_callback = '' ) {
 
1476
        global $new_whitelist_options;
 
1477
 
 
1478
        if ( 'misc' == $option_group ) {
 
1479
                _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
 
1480
                $option_group = 'general';
 
1481
        }
 
1482
 
 
1483
        $new_whitelist_options[ $option_group ][] = $option_name;
 
1484
        if ( $sanitize_callback != '' )
 
1485
                add_filter( "sanitize_option_{$option_name}", $sanitize_callback );
 
1486
}
 
1487
 
 
1488
/**
 
1489
 * Unregister a setting
 
1490
 *
 
1491
 * @since 2.7.0
 
1492
 *
 
1493
 * @param unknown_type $option_group
 
1494
 * @param unknown_type $option_name
 
1495
 * @param unknown_type $sanitize_callback
 
1496
 * @return unknown
 
1497
 */
 
1498
function unregister_setting( $option_group, $option_name, $sanitize_callback = '' ) {
 
1499
        global $new_whitelist_options;
 
1500
 
 
1501
        if ( 'misc' == $option_group ) {
 
1502
                _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
 
1503
                $option_group = 'general';
 
1504
        }
 
1505
 
 
1506
        $pos = array_search( $option_name, (array) $new_whitelist_options );
 
1507
        if ( $pos !== false )
 
1508
                unset( $new_whitelist_options[ $option_group ][ $pos ] );
 
1509
        if ( $sanitize_callback != '' )
 
1510
                remove_filter( "sanitize_option_{$option_name}", $sanitize_callback );
 
1511
}
 
1512
 
 
1513
/**
 
1514
 * {@internal Missing Short Description}}
 
1515
 *
 
1516
 * @since unknown
 
1517
 *
 
1518
 * @param unknown_type $options
 
1519
 * @return unknown
 
1520
 */
 
1521
function option_update_filter( $options ) {
 
1522
        global $new_whitelist_options;
 
1523
 
 
1524
        if ( is_array( $new_whitelist_options ) )
 
1525
                $options = add_option_whitelist( $new_whitelist_options, $options );
 
1526
 
 
1527
        return $options;
 
1528
}
 
1529
add_filter( 'whitelist_options', 'option_update_filter' );
 
1530
 
 
1531
/**
 
1532
 * {@internal Missing Short Description}}
 
1533
 *
 
1534
 * @since unknown
 
1535
 *
 
1536
 * @param unknown_type $new_options
 
1537
 * @param unknown_type $options
 
1538
 * @return unknown
 
1539
 */
 
1540
function add_option_whitelist( $new_options, $options = '' ) {
 
1541
        if ( $options == '' )
 
1542
                global $whitelist_options;
 
1543
        else
 
1544
                $whitelist_options = $options;
 
1545
 
 
1546
        foreach ( $new_options as $page => $keys ) {
 
1547
                foreach ( $keys as $key ) {
 
1548
                        if ( !isset($whitelist_options[ $page ]) || !is_array($whitelist_options[ $page ]) ) {
 
1549
                                $whitelist_options[ $page ] = array();
 
1550
                                $whitelist_options[ $page ][] = $key;
 
1551
                        } else {
 
1552
                                $pos = array_search( $key, $whitelist_options[ $page ] );
 
1553
                                if ( $pos === false )
 
1554
                                        $whitelist_options[ $page ][] = $key;
 
1555
                        }
 
1556
                }
 
1557
        }
 
1558
 
 
1559
        return $whitelist_options;
 
1560
}
 
1561
 
 
1562
/**
 
1563
 * {@internal Missing Short Description}}
 
1564
 *
 
1565
 * @since unknown
 
1566
 *
 
1567
 * @param unknown_type $del_options
 
1568
 * @param unknown_type $options
 
1569
 * @return unknown
 
1570
 */
 
1571
function remove_option_whitelist( $del_options, $options = '' ) {
 
1572
        if ( $options == '' )
 
1573
                global $whitelist_options;
 
1574
        else
 
1575
                $whitelist_options = $options;
 
1576
 
 
1577
        foreach ( $del_options as $page => $keys ) {
 
1578
                foreach ( $keys as $key ) {
 
1579
                        if ( isset($whitelist_options[ $page ]) && is_array($whitelist_options[ $page ]) ) {
 
1580
                                $pos = array_search( $key, $whitelist_options[ $page ] );
 
1581
                                if ( $pos !== false )
 
1582
                                        unset( $whitelist_options[ $page ][ $pos ] );
 
1583
                        }
 
1584
                }
 
1585
        }
 
1586
 
 
1587
        return $whitelist_options;
 
1588
}
 
1589
 
 
1590
/**
 
1591
 * Output nonce, action, and option_page fields for a settings page.
 
1592
 *
 
1593
 * @since 2.7.0
 
1594
 *
 
1595
 * @param string $option_group A settings group name.  This should match the group name used in register_setting().
 
1596
 */
 
1597
function settings_fields($option_group) {
 
1598
        echo "<input type='hidden' name='option_page' value='" . esc_attr($option_group) . "' />";
 
1599
        echo '<input type="hidden" name="action" value="update" />';
 
1600
        wp_nonce_field("$option_group-options");
 
1601
}
 
1602
 
 
1603
?>