7 */ |
7 */ |
8 |
8 |
9 /** |
9 /** |
10 * Parses the plugin contents to retrieve plugin's metadata. |
10 * Parses the plugin contents to retrieve plugin's metadata. |
11 * |
11 * |
12 * The metadata of the plugin's data searches for the following in the plugin's |
12 * All plugin headers must be on their own line. Plugin description must not have |
13 * header. All plugin data must be on its own line. For plugin description, it |
13 * any newlines, otherwise only parts of the description will be displayed. |
14 * must not have any newlines or only parts of the description will be displayed |
14 * The below is formatted for printing. |
15 * and the same goes for the plugin data. The below is formatted for printing. |
|
16 * |
15 * |
17 * /* |
16 * /* |
18 * Plugin Name: Name of Plugin |
17 * Plugin Name: Name of the plugin. |
19 * Plugin URI: Link to plugin information |
18 * Plugin URI: The home page of the plugin. |
20 * Description: Plugin Description |
19 * Description: Plugin description. |
21 * Author: Plugin author's name |
20 * Author: Plugin author's name. |
22 * Author URI: Link to the author's web site |
21 * Author URI: Link to the author's website. |
23 * Version: Must be set in the plugin for WordPress 2.3+ |
22 * Version: Plugin version. |
24 * Text Domain: Optional. Unique identifier, should be same as the one used in |
23 * Text Domain: Optional. Unique identifier, should be same as the one used in |
25 * load_plugin_textdomain() |
24 * load_plugin_textdomain(). |
26 * Domain Path: Optional. Only useful if the translations are located in a |
25 * Domain Path: Optional. Only useful if the translations are located in a |
27 * folder above the plugin's base path. For example, if .mo files are |
26 * folder above the plugin's base path. For example, if .mo files are |
28 * located in the locale folder then Domain Path will be "/locale/" and |
27 * located in the locale folder then Domain Path will be "/locale/" and |
29 * must have the first slash. Defaults to the base folder the plugin is |
28 * must have the first slash. Defaults to the base folder the plugin is |
30 * located in. |
29 * located in. |
31 * Network: Optional. Specify "Network: true" to require that a plugin is activated |
30 * Network: Optional. Specify "Network: true" to require that a plugin is activated |
32 * across all sites in an installation. This will prevent a plugin from being |
31 * across all sites in an installation. This will prevent a plugin from being |
33 * activated on a single site when Multisite is enabled. |
32 * activated on a single site when Multisite is enabled. |
34 * * / # Remove the space to close comment |
33 * Requires at least: Optional. Specify the minimum required WordPress version. |
35 * |
34 * Requires PHP: Optional. Specify the minimum required PHP version. |
36 * Some users have issues with opening large files and manipulating the contents |
35 * * / # Remove the space to close comment. |
37 * for want is usually the first 1kiB or 2kiB. This function stops pulling in |
36 * |
38 * the plugin contents when it has all of the required plugin data. |
37 * The first 8 KB of the file will be pulled in and if the plugin data is not |
39 * |
38 * within that first 8 KB, then the plugin author should correct their plugin |
40 * The first 8kiB of the file will be pulled in and if the plugin data is not |
|
41 * within that first 8kiB, then the plugin author should correct their plugin |
|
42 * and move the plugin data headers to the top. |
39 * and move the plugin data headers to the top. |
43 * |
40 * |
44 * The plugin file is assumed to have permissions to allow for scripts to read |
41 * The plugin file is assumed to have permissions to allow for scripts to read |
45 * the file. This is not checked however and the file is only opened for |
42 * the file. This is not checked however and the file is only opened for |
46 * reading. |
43 * reading. |
47 * |
44 * |
48 * @since 1.5.0 |
45 * @since 1.5.0 |
|
46 * @since 5.3.0 Added support for `Requires at least` and `Requires PHP` headers. |
49 * |
47 * |
50 * @param string $plugin_file Absolute path to the main plugin file. |
48 * @param string $plugin_file Absolute path to the main plugin file. |
|
49 * @param bool $markup Optional. If the returned data should have HTML markup applied. |
|
50 * Default true. |
|
51 * @param bool $translate Optional. If the returned data should be translated. Default true. |
|
52 * @return array { |
|
53 * Plugin data. Values will be empty if not supplied by the plugin. |
|
54 * |
|
55 * @type string $Name Name of the plugin. Should be unique. |
|
56 * @type string $Title Title of the plugin and link to the plugin's site (if set). |
|
57 * @type string $Description Plugin description. |
|
58 * @type string $Author Author's name. |
|
59 * @type string $AuthorURI Author's website address (if set). |
|
60 * @type string $Version Plugin version. |
|
61 * @type string $TextDomain Plugin textdomain. |
|
62 * @type string $DomainPath Plugins relative directory path to .mo files. |
|
63 * @type bool $Network Whether the plugin can only be activated network-wide. |
|
64 * @type string $RequiresWP Minimum required version of WordPress. |
|
65 * @type string $RequiresPHP Minimum required version of PHP. |
|
66 * } |
|
67 */ |
|
68 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { |
|
69 |
|
70 $default_headers = array( |
|
71 'Name' => 'Plugin Name', |
|
72 'PluginURI' => 'Plugin URI', |
|
73 'Version' => 'Version', |
|
74 'Description' => 'Description', |
|
75 'Author' => 'Author', |
|
76 'AuthorURI' => 'Author URI', |
|
77 'TextDomain' => 'Text Domain', |
|
78 'DomainPath' => 'Domain Path', |
|
79 'Network' => 'Network', |
|
80 'RequiresWP' => 'Requires at least', |
|
81 'RequiresPHP' => 'Requires PHP', |
|
82 // Site Wide Only is deprecated in favor of Network. |
|
83 '_sitewide' => 'Site Wide Only', |
|
84 ); |
|
85 |
|
86 $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' ); |
|
87 |
|
88 // Site Wide Only is the old header for Network. |
|
89 if ( ! $plugin_data['Network'] && $plugin_data['_sitewide'] ) { |
|
90 /* translators: 1: Site Wide Only: true, 2: Network: true */ |
|
91 _deprecated_argument( __FUNCTION__, '3.0.0', sprintf( __( 'The %1$s plugin header is deprecated. Use %2$s instead.' ), '<code>Site Wide Only: true</code>', '<code>Network: true</code>' ) ); |
|
92 $plugin_data['Network'] = $plugin_data['_sitewide']; |
|
93 } |
|
94 $plugin_data['Network'] = ( 'true' === strtolower( $plugin_data['Network'] ) ); |
|
95 unset( $plugin_data['_sitewide'] ); |
|
96 |
|
97 // If no text domain is defined fall back to the plugin slug. |
|
98 if ( ! $plugin_data['TextDomain'] ) { |
|
99 $plugin_slug = dirname( plugin_basename( $plugin_file ) ); |
|
100 if ( '.' !== $plugin_slug && false === strpos( $plugin_slug, '/' ) ) { |
|
101 $plugin_data['TextDomain'] = $plugin_slug; |
|
102 } |
|
103 } |
|
104 |
|
105 if ( $markup || $translate ) { |
|
106 $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate ); |
|
107 } else { |
|
108 $plugin_data['Title'] = $plugin_data['Name']; |
|
109 $plugin_data['AuthorName'] = $plugin_data['Author']; |
|
110 } |
|
111 |
|
112 return $plugin_data; |
|
113 } |
|
114 |
|
115 /** |
|
116 * Sanitizes plugin data, optionally adds markup, optionally translates. |
|
117 * |
|
118 * @since 2.7.0 |
|
119 * |
|
120 * @see get_plugin_data() |
|
121 * |
|
122 * @access private |
|
123 * |
|
124 * @param string $plugin_file Path to the main plugin file. |
|
125 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. |
51 * @param bool $markup Optional. If the returned data should have HTML markup applied. |
126 * @param bool $markup Optional. If the returned data should have HTML markup applied. |
52 * Default true. |
127 * Default true. |
53 * @param bool $translate Optional. If the returned data should be translated. Default true. |
128 * @param bool $translate Optional. If the returned data should be translated. Default true. |
54 * @return array { |
129 * @return array { |
55 * Plugin data. Values will be empty if not supplied by the plugin. |
130 * Plugin data. Values will be empty if not supplied by the plugin. |
63 * @type string $TextDomain Plugin textdomain. |
138 * @type string $TextDomain Plugin textdomain. |
64 * @type string $DomainPath Plugins relative directory path to .mo files. |
139 * @type string $DomainPath Plugins relative directory path to .mo files. |
65 * @type bool $Network Whether the plugin can only be activated network-wide. |
140 * @type bool $Network Whether the plugin can only be activated network-wide. |
66 * } |
141 * } |
67 */ |
142 */ |
68 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { |
|
69 |
|
70 $default_headers = array( |
|
71 'Name' => 'Plugin Name', |
|
72 'PluginURI' => 'Plugin URI', |
|
73 'Version' => 'Version', |
|
74 'Description' => 'Description', |
|
75 'Author' => 'Author', |
|
76 'AuthorURI' => 'Author URI', |
|
77 'TextDomain' => 'Text Domain', |
|
78 'DomainPath' => 'Domain Path', |
|
79 'Network' => 'Network', |
|
80 // Site Wide Only is deprecated in favor of Network. |
|
81 '_sitewide' => 'Site Wide Only', |
|
82 ); |
|
83 |
|
84 $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' ); |
|
85 |
|
86 // Site Wide Only is the old header for Network |
|
87 if ( ! $plugin_data['Network'] && $plugin_data['_sitewide'] ) { |
|
88 /* translators: 1: Site Wide Only: true, 2: Network: true */ |
|
89 _deprecated_argument( __FUNCTION__, '3.0.0', sprintf( __( 'The %1$s plugin header is deprecated. Use %2$s instead.' ), '<code>Site Wide Only: true</code>', '<code>Network: true</code>' ) ); |
|
90 $plugin_data['Network'] = $plugin_data['_sitewide']; |
|
91 } |
|
92 $plugin_data['Network'] = ( 'true' == strtolower( $plugin_data['Network'] ) ); |
|
93 unset( $plugin_data['_sitewide'] ); |
|
94 |
|
95 // If no text domain is defined fall back to the plugin slug. |
|
96 if ( ! $plugin_data['TextDomain'] ) { |
|
97 $plugin_slug = dirname( plugin_basename( $plugin_file ) ); |
|
98 if ( '.' !== $plugin_slug && false === strpos( $plugin_slug, '/' ) ) { |
|
99 $plugin_data['TextDomain'] = $plugin_slug; |
|
100 } |
|
101 } |
|
102 |
|
103 if ( $markup || $translate ) { |
|
104 $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate ); |
|
105 } else { |
|
106 $plugin_data['Title'] = $plugin_data['Name']; |
|
107 $plugin_data['AuthorName'] = $plugin_data['Author']; |
|
108 } |
|
109 |
|
110 return $plugin_data; |
|
111 } |
|
112 |
|
113 /** |
|
114 * Sanitizes plugin data, optionally adds markup, optionally translates. |
|
115 * |
|
116 * @since 2.7.0 |
|
117 * |
|
118 * @see get_plugin_data() |
|
119 * |
|
120 * @access private |
|
121 * |
|
122 * @param string $plugin_file Path to the main plugin file. |
|
123 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. |
|
124 * @param bool $markup Optional. If the returned data should have HTML markup applied. |
|
125 * Default true. |
|
126 * @param bool $translate Optional. If the returned data should be translated. Default true. |
|
127 * @return array { |
|
128 * Plugin data. Values will be empty if not supplied by the plugin. |
|
129 * |
|
130 * @type string $Name Name of the plugin. Should be unique. |
|
131 * @type string $Title Title of the plugin and link to the plugin's site (if set). |
|
132 * @type string $Description Plugin description. |
|
133 * @type string $Author Author's name. |
|
134 * @type string $AuthorURI Author's website address (if set). |
|
135 * @type string $Version Plugin version. |
|
136 * @type string $TextDomain Plugin textdomain. |
|
137 * @type string $DomainPath Plugins relative directory path to .mo files. |
|
138 * @type bool $Network Whether the plugin can only be activated network-wide. |
|
139 * } |
|
140 */ |
|
141 function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) { |
143 function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) { |
142 |
144 |
143 // Sanitize the plugin filename to a WP_PLUGIN_DIR relative path |
145 // Sanitize the plugin filename to a WP_PLUGIN_DIR relative path. |
144 $plugin_file = plugin_basename( $plugin_file ); |
146 $plugin_file = plugin_basename( $plugin_file ); |
145 |
147 |
146 // Translate fields |
148 // Translate fields. |
147 if ( $translate ) { |
149 if ( $translate ) { |
148 if ( $textdomain = $plugin_data['TextDomain'] ) { |
150 $textdomain = $plugin_data['TextDomain']; |
|
151 if ( $textdomain ) { |
149 if ( ! is_textdomain_loaded( $textdomain ) ) { |
152 if ( ! is_textdomain_loaded( $textdomain ) ) { |
150 if ( $plugin_data['DomainPath'] ) { |
153 if ( $plugin_data['DomainPath'] ) { |
151 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) . $plugin_data['DomainPath'] ); |
154 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) . $plugin_data['DomainPath'] ); |
152 } else { |
155 } else { |
153 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) ); |
156 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) ); |
154 } |
157 } |
155 } |
158 } |
156 } elseif ( 'hello.php' == basename( $plugin_file ) ) { |
159 } elseif ( 'hello.php' === basename( $plugin_file ) ) { |
157 $textdomain = 'default'; |
160 $textdomain = 'default'; |
158 } |
161 } |
159 if ( $textdomain ) { |
162 if ( $textdomain ) { |
160 foreach ( array( 'Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field ) { |
163 foreach ( array( 'Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field ) { |
161 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
164 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
162 $plugin_data[ $field ] = translate( $plugin_data[ $field ], $textdomain ); |
165 $plugin_data[ $field ] = translate( $plugin_data[ $field ], $textdomain ); |
163 } |
166 } |
164 } |
167 } |
165 } |
168 } |
166 |
169 |
167 // Sanitize fields |
170 // Sanitize fields. |
168 $allowed_tags_in_links = array( |
171 $allowed_tags_in_links = array( |
169 'abbr' => array( 'title' => true ), |
172 'abbr' => array( 'title' => true ), |
170 'acronym' => array( 'title' => true ), |
173 'acronym' => array( 'title' => true ), |
171 'code' => true, |
174 'code' => true, |
172 'em' => true, |
175 'em' => true, |
283 $plugin_root = WP_PLUGIN_DIR; |
290 $plugin_root = WP_PLUGIN_DIR; |
284 if ( ! empty( $plugin_folder ) ) { |
291 if ( ! empty( $plugin_folder ) ) { |
285 $plugin_root .= $plugin_folder; |
292 $plugin_root .= $plugin_folder; |
286 } |
293 } |
287 |
294 |
288 // Files in wp-content/plugins directory |
295 // Files in wp-content/plugins directory. |
289 $plugins_dir = @ opendir( $plugin_root ); |
296 $plugins_dir = @ opendir( $plugin_root ); |
290 $plugin_files = array(); |
297 $plugin_files = array(); |
|
298 |
291 if ( $plugins_dir ) { |
299 if ( $plugins_dir ) { |
292 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
300 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
293 if ( substr( $file, 0, 1 ) == '.' ) { |
301 if ( '.' === substr( $file, 0, 1 ) ) { |
294 continue; |
302 continue; |
295 } |
303 } |
|
304 |
296 if ( is_dir( $plugin_root . '/' . $file ) ) { |
305 if ( is_dir( $plugin_root . '/' . $file ) ) { |
297 $plugins_subdir = @ opendir( $plugin_root . '/' . $file ); |
306 $plugins_subdir = @ opendir( $plugin_root . '/' . $file ); |
|
307 |
298 if ( $plugins_subdir ) { |
308 if ( $plugins_subdir ) { |
299 while ( ( $subfile = readdir( $plugins_subdir ) ) !== false ) { |
309 while ( ( $subfile = readdir( $plugins_subdir ) ) !== false ) { |
300 if ( substr( $subfile, 0, 1 ) == '.' ) { |
310 if ( '.' === substr( $subfile, 0, 1 ) ) { |
301 continue; |
311 continue; |
302 } |
312 } |
303 if ( substr( $subfile, -4 ) == '.php' ) { |
313 |
|
314 if ( '.php' === substr( $subfile, -4 ) ) { |
304 $plugin_files[] = "$file/$subfile"; |
315 $plugin_files[] = "$file/$subfile"; |
305 } |
316 } |
306 } |
317 } |
|
318 |
307 closedir( $plugins_subdir ); |
319 closedir( $plugins_subdir ); |
308 } |
320 } |
309 } else { |
321 } else { |
310 if ( substr( $file, -4 ) == '.php' ) { |
322 if ( '.php' === substr( $file, -4 ) ) { |
311 $plugin_files[] = $file; |
323 $plugin_files[] = $file; |
312 } |
324 } |
313 } |
325 } |
314 } |
326 } |
|
327 |
315 closedir( $plugins_dir ); |
328 closedir( $plugins_dir ); |
316 } |
329 } |
317 |
330 |
318 if ( empty( $plugin_files ) ) { |
331 if ( empty( $plugin_files ) ) { |
319 return $wp_plugins; |
332 return $wp_plugins; |
345 * Check the mu-plugins directory and retrieve all mu-plugin files with any plugin data. |
359 * Check the mu-plugins directory and retrieve all mu-plugin files with any plugin data. |
346 * |
360 * |
347 * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins). |
361 * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins). |
348 * |
362 * |
349 * @since 3.0.0 |
363 * @since 3.0.0 |
350 * @return array Key is the mu-plugin file path and the value is an array of the mu-plugin data. |
364 * @return array[] Array of arrays of mu-plugin data, keyed by plugin file name. See `get_plugin_data()`. |
351 */ |
365 */ |
352 function get_mu_plugins() { |
366 function get_mu_plugins() { |
353 $wp_plugins = array(); |
367 $wp_plugins = array(); |
354 // Files in wp-content/mu-plugins directory |
|
355 $plugin_files = array(); |
368 $plugin_files = array(); |
356 |
369 |
357 if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { |
370 if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { |
358 return $wp_plugins; |
371 return $wp_plugins; |
359 } |
372 } |
360 if ( $plugins_dir = @ opendir( WPMU_PLUGIN_DIR ) ) { |
373 |
|
374 // Files in wp-content/mu-plugins directory. |
|
375 $plugins_dir = @opendir( WPMU_PLUGIN_DIR ); |
|
376 if ( $plugins_dir ) { |
361 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
377 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
362 if ( substr( $file, -4 ) == '.php' ) { |
378 if ( '.php' === substr( $file, -4 ) ) { |
363 $plugin_files[] = $file; |
379 $plugin_files[] = $file; |
364 } |
380 } |
365 } |
381 } |
366 } else { |
382 } else { |
367 return $wp_plugins; |
383 return $wp_plugins; |
368 } |
384 } |
369 |
385 |
370 @closedir( $plugins_dir ); |
386 closedir( $plugins_dir ); |
371 |
387 |
372 if ( empty( $plugin_files ) ) { |
388 if ( empty( $plugin_files ) ) { |
373 return $wp_plugins; |
389 return $wp_plugins; |
374 } |
390 } |
375 |
391 |
376 foreach ( $plugin_files as $plugin_file ) { |
392 foreach ( $plugin_files as $plugin_file ) { |
377 if ( ! is_readable( WPMU_PLUGIN_DIR . "/$plugin_file" ) ) { |
393 if ( ! is_readable( WPMU_PLUGIN_DIR . "/$plugin_file" ) ) { |
378 continue; |
394 continue; |
379 } |
395 } |
380 |
396 |
381 $plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. |
397 // Do not apply markup/translate as it will be cached. |
|
398 $plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false ); |
382 |
399 |
383 if ( empty( $plugin_data['Name'] ) ) { |
400 if ( empty( $plugin_data['Name'] ) ) { |
384 $plugin_data['Name'] = $plugin_file; |
401 $plugin_data['Name'] = $plugin_file; |
385 } |
402 } |
386 |
403 |
387 $wp_plugins[ $plugin_file ] = $plugin_data; |
404 $wp_plugins[ $plugin_file ] = $plugin_data; |
388 } |
405 } |
389 |
406 |
390 if ( isset( $wp_plugins['index.php'] ) && filesize( WPMU_PLUGIN_DIR . '/index.php' ) <= 30 ) { // silence is golden |
407 if ( isset( $wp_plugins['index.php'] ) && filesize( WPMU_PLUGIN_DIR . '/index.php' ) <= 30 ) { |
|
408 // Silence is golden. |
391 unset( $wp_plugins['index.php'] ); |
409 unset( $wp_plugins['index.php'] ); |
392 } |
410 } |
393 |
411 |
394 uasort( $wp_plugins, '_sort_uname_callback' ); |
412 uasort( $wp_plugins, '_sort_uname_callback' ); |
395 |
413 |
413 |
431 |
414 /** |
432 /** |
415 * Check the wp-content directory and retrieve all drop-ins with any plugin data. |
433 * Check the wp-content directory and retrieve all drop-ins with any plugin data. |
416 * |
434 * |
417 * @since 3.0.0 |
435 * @since 3.0.0 |
418 * @return array Key is the file path and the value is an array of the plugin data. |
436 * @return array[] Array of arrays of dropin plugin data, keyed by plugin file name. See `get_plugin_data()`. |
419 */ |
437 */ |
420 function get_dropins() { |
438 function get_dropins() { |
421 $dropins = array(); |
439 $dropins = array(); |
422 $plugin_files = array(); |
440 $plugin_files = array(); |
423 |
441 |
424 $_dropins = _get_dropins(); |
442 $_dropins = _get_dropins(); |
425 |
443 |
426 // These exist in the wp-content directory |
444 // Files in wp-content directory. |
427 if ( $plugins_dir = @ opendir( WP_CONTENT_DIR ) ) { |
445 $plugins_dir = @opendir( WP_CONTENT_DIR ); |
|
446 if ( $plugins_dir ) { |
428 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
447 while ( ( $file = readdir( $plugins_dir ) ) !== false ) { |
429 if ( isset( $_dropins[ $file ] ) ) { |
448 if ( isset( $_dropins[ $file ] ) ) { |
430 $plugin_files[] = $file; |
449 $plugin_files[] = $file; |
431 } |
450 } |
432 } |
451 } |
433 } else { |
452 } else { |
434 return $dropins; |
453 return $dropins; |
435 } |
454 } |
436 |
455 |
437 @closedir( $plugins_dir ); |
456 closedir( $plugins_dir ); |
438 |
457 |
439 if ( empty( $plugin_files ) ) { |
458 if ( empty( $plugin_files ) ) { |
440 return $dropins; |
459 return $dropins; |
441 } |
460 } |
442 |
461 |
443 foreach ( $plugin_files as $plugin_file ) { |
462 foreach ( $plugin_files as $plugin_file ) { |
444 if ( ! is_readable( WP_CONTENT_DIR . "/$plugin_file" ) ) { |
463 if ( ! is_readable( WP_CONTENT_DIR . "/$plugin_file" ) ) { |
445 continue; |
464 continue; |
446 } |
465 } |
447 $plugin_data = get_plugin_data( WP_CONTENT_DIR . "/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. |
466 |
|
467 // Do not apply markup/translate as it will be cached. |
|
468 $plugin_data = get_plugin_data( WP_CONTENT_DIR . "/$plugin_file", false, false ); |
|
469 |
448 if ( empty( $plugin_data['Name'] ) ) { |
470 if ( empty( $plugin_data['Name'] ) ) { |
449 $plugin_data['Name'] = $plugin_file; |
471 $plugin_data['Name'] = $plugin_file; |
450 } |
472 } |
|
473 |
451 $dropins[ $plugin_file ] = $plugin_data; |
474 $dropins[ $plugin_file ] = $plugin_data; |
452 } |
475 } |
453 |
476 |
454 uksort( $dropins, 'strnatcasecmp' ); |
477 uksort( $dropins, 'strnatcasecmp' ); |
455 |
478 |
460 * Returns drop-ins that WordPress uses. |
483 * Returns drop-ins that WordPress uses. |
461 * |
484 * |
462 * Includes Multisite drop-ins only when is_multisite() |
485 * Includes Multisite drop-ins only when is_multisite() |
463 * |
486 * |
464 * @since 3.0.0 |
487 * @since 3.0.0 |
465 * @return array Key is file name. The value is an array, with the first value the |
488 * @return array[] Key is file name. The value is an array, with the first value the |
466 * purpose of the drop-in and the second value the name of the constant that must be |
489 * purpose of the drop-in and the second value the name of the constant that must be |
467 * true for the drop-in to be used, or true if no constant is required. |
490 * true for the drop-in to be used, or true if no constant is required. |
468 */ |
491 */ |
469 function _get_dropins() { |
492 function _get_dropins() { |
470 $dropins = array( |
493 $dropins = array( |
471 'advanced-cache.php' => array( __( 'Advanced caching plugin.' ), 'WP_CACHE' ), // WP_CACHE |
494 'advanced-cache.php' => array( __( 'Advanced caching plugin.' ), 'WP_CACHE' ), // WP_CACHE |
472 'db.php' => array( __( 'Custom database class.' ), true ), // auto on load |
495 'db.php' => array( __( 'Custom database class.' ), true ), // Auto on load. |
473 'db-error.php' => array( __( 'Custom database error message.' ), true ), // auto on error |
496 'db-error.php' => array( __( 'Custom database error message.' ), true ), // Auto on error. |
474 'install.php' => array( __( 'Custom installation script.' ), true ), // auto on installation |
497 'install.php' => array( __( 'Custom installation script.' ), true ), // Auto on installation. |
475 'maintenance.php' => array( __( 'Custom maintenance message.' ), true ), // auto on maintenance |
498 'maintenance.php' => array( __( 'Custom maintenance message.' ), true ), // Auto on maintenance. |
476 'object-cache.php' => array( __( 'External object cache.' ), true ), // auto on load |
499 'object-cache.php' => array( __( 'External object cache.' ), true ), // Auto on load. |
477 'php-error.php' => array( __( 'Custom PHP error message.' ), true ), // auto on error |
500 'php-error.php' => array( __( 'Custom PHP error message.' ), true ), // Auto on error. |
478 'fatal-error-handler.php' => array( __( 'Custom PHP fatal error handler.' ), true ), // auto on error |
501 'fatal-error-handler.php' => array( __( 'Custom PHP fatal error handler.' ), true ), // Auto on error. |
479 ); |
502 ); |
480 |
503 |
481 if ( is_multisite() ) { |
504 if ( is_multisite() ) { |
482 $dropins['sunrise.php'] = array( __( 'Executed before Multisite is loaded.' ), 'SUNRISE' ); // SUNRISE |
505 $dropins['sunrise.php'] = array( __( 'Executed before Multisite is loaded.' ), 'SUNRISE' ); // SUNRISE |
483 $dropins['blog-deleted.php'] = array( __( 'Custom site deleted message.' ), true ); // auto on deleted blog |
506 $dropins['blog-deleted.php'] = array( __( 'Custom site deleted message.' ), true ); // Auto on deleted blog. |
484 $dropins['blog-inactive.php'] = array( __( 'Custom site inactive message.' ), true ); // auto on inactive blog |
507 $dropins['blog-inactive.php'] = array( __( 'Custom site inactive message.' ), true ); // Auto on inactive blog. |
485 $dropins['blog-suspended.php'] = array( __( 'Custom site suspended message.' ), true ); // auto on archived or spammed blog |
508 $dropins['blog-suspended.php'] = array( __( 'Custom site suspended message.' ), true ); // Auto on archived or spammed blog. |
486 } |
509 } |
487 |
510 |
488 return $dropins; |
511 return $dropins; |
489 } |
512 } |
490 |
513 |
625 $requirements = validate_plugin_requirements( $plugin ); |
649 $requirements = validate_plugin_requirements( $plugin ); |
626 if ( is_wp_error( $requirements ) ) { |
650 if ( is_wp_error( $requirements ) ) { |
627 return $requirements; |
651 return $requirements; |
628 } |
652 } |
629 |
653 |
630 if ( ( $network_wide && ! isset( $current[ $plugin ] ) ) || ( ! $network_wide && ! in_array( $plugin, $current ) ) ) { |
654 if ( ( $network_wide && ! isset( $current[ $plugin ] ) ) || ( ! $network_wide && ! in_array( $plugin, $current, true ) ) ) { |
631 if ( ! empty( $redirect ) ) { |
655 if ( ! empty( $redirect ) ) { |
632 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 |
656 // We'll override this later if the plugin can be included without fatal error. |
|
657 wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) ); |
633 } |
658 } |
634 |
659 |
635 ob_start(); |
660 ob_start(); |
|
661 |
|
662 if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) { |
|
663 define( 'WP_SANDBOX_SCRAPING', true ); |
|
664 } |
|
665 |
636 wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin ); |
666 wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin ); |
637 $_wp_plugin_file = $plugin; |
667 $_wp_plugin_file = $plugin; |
638 if ( ! defined( 'WP_SANDBOX_SCRAPING' ) ) { |
668 include_once WP_PLUGIN_DIR . '/' . $plugin; |
639 define( 'WP_SANDBOX_SCRAPING', true ); |
|
640 } |
|
641 include_once( WP_PLUGIN_DIR . '/' . $plugin ); |
|
642 $plugin = $_wp_plugin_file; // Avoid stomping of the $plugin variable in a plugin. |
669 $plugin = $_wp_plugin_file; // Avoid stomping of the $plugin variable in a plugin. |
643 |
670 |
644 if ( ! $silent ) { |
671 if ( ! $silent ) { |
645 /** |
672 /** |
646 * Fires before a plugin is activated. |
673 * Fires before a plugin is activated. |
715 * The deactivation hook is disabled by the plugin upgrader by using the $silent |
742 * The deactivation hook is disabled by the plugin upgrader by using the $silent |
716 * parameter. |
743 * parameter. |
717 * |
744 * |
718 * @since 2.5.0 |
745 * @since 2.5.0 |
719 * |
746 * |
720 * @param string|array $plugins Single plugin or list of plugins to deactivate. |
747 * @param string|string[] $plugins Single plugin or list of plugins to deactivate. |
721 * @param bool $silent Prevent calling deactivation hooks. Default is false. |
748 * @param bool $silent Prevent calling deactivation hooks. Default false. |
722 * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network. |
749 * @param bool|null $network_wide Whether to deactivate the plugin for all sites in the network. |
723 * A value of null (the default) will deactivate plugins for both the site and the network. |
750 * A value of null will deactivate plugins for both the network |
|
751 * and the current site. Multisite only. Default null. |
724 */ |
752 */ |
725 function deactivate_plugins( $plugins, $silent = false, $network_wide = null ) { |
753 function deactivate_plugins( $plugins, $silent = false, $network_wide = null ) { |
726 if ( is_multisite() ) { |
754 if ( is_multisite() ) { |
727 $network_current = get_site_option( 'active_sitewide_plugins', array() ); |
755 $network_current = get_site_option( 'active_sitewide_plugins', array() ); |
728 } |
756 } |
729 $current = get_option( 'active_plugins', array() ); |
757 $current = get_option( 'active_plugins', array() ); |
730 $do_blog = $do_network = false; |
758 $do_blog = false; |
|
759 $do_network = false; |
731 |
760 |
732 foreach ( (array) $plugins as $plugin ) { |
761 foreach ( (array) $plugins as $plugin ) { |
733 $plugin = plugin_basename( trim( $plugin ) ); |
762 $plugin = plugin_basename( trim( $plugin ) ); |
734 if ( ! is_plugin_active( $plugin ) ) { |
763 if ( ! is_plugin_active( $plugin ) ) { |
735 continue; |
764 continue; |
817 |
846 |
818 /** |
847 /** |
819 * Activate multiple plugins. |
848 * Activate multiple plugins. |
820 * |
849 * |
821 * When WP_Error is returned, it does not mean that one of the plugins had |
850 * When WP_Error is returned, it does not mean that one of the plugins had |
822 * errors. It means that one or more of the plugins file path was invalid. |
851 * errors. It means that one or more of the plugin file paths were invalid. |
823 * |
852 * |
824 * The execution will be halted as soon as one of the plugins has an error. |
853 * The execution will be halted as soon as one of the plugins has an error. |
825 * |
854 * |
826 * @since 2.6.0 |
855 * @since 2.6.0 |
827 * |
856 * |
828 * @param string|array $plugins Single plugin or list of plugins to activate. |
857 * @param string|string[] $plugins Single plugin or list of plugins to activate. |
829 * @param string $redirect Redirect to page after successful activation. |
858 * @param string $redirect Redirect to page after successful activation. |
830 * @param bool $network_wide Whether to enable the plugin for all sites in the network. |
859 * @param bool $network_wide Whether to enable the plugin for all sites in the network. |
831 * @param bool $silent Prevent calling activation hooks. Default is false. |
860 * Default false. |
|
861 * @param bool $silent Prevent calling activation hooks. Default false. |
832 * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation. |
862 * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation. |
833 */ |
863 */ |
834 function activate_plugins( $plugins, $redirect = '', $network_wide = false, $silent = false ) { |
864 function activate_plugins( $plugins, $redirect = '', $network_wide = false, $silent = false ) { |
835 if ( ! is_array( $plugins ) ) { |
865 if ( ! is_array( $plugins ) ) { |
836 $plugins = array( $plugins ); |
866 $plugins = array( $plugins ); |
1074 } |
1107 } |
1075 return 0; |
1108 return 0; |
1076 } |
1109 } |
1077 |
1110 |
1078 /** |
1111 /** |
1079 * Validate the plugin requirements for WP version and PHP version. |
1112 * Validates the plugin requirements for WordPress version and PHP version. |
|
1113 * |
|
1114 * Uses the information from `Requires at least` and `Requires PHP` headers |
|
1115 * defined in the plugin's main PHP file. |
|
1116 * |
|
1117 * If the headers are not present in the plugin's main PHP file, |
|
1118 * `readme.txt` is also checked as a fallback. |
1080 * |
1119 * |
1081 * @since 5.2.0 |
1120 * @since 5.2.0 |
|
1121 * @since 5.3.0 Added support for reading the headers from the plugin's |
|
1122 * main PHP file, with `readme.txt` as a fallback. |
1082 * |
1123 * |
1083 * @param string $plugin Path to the plugin file relative to the plugins directory. |
1124 * @param string $plugin Path to the plugin file relative to the plugins directory. |
1084 * @return true|WP_Error True if requirements are met, WP_Error on failure. |
1125 * @return true|WP_Error True if requirements are met, WP_Error on failure. |
1085 */ |
1126 */ |
1086 function validate_plugin_requirements( $plugin ) { |
1127 function validate_plugin_requirements( $plugin ) { |
|
1128 $plugin_headers = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
|
1129 |
|
1130 $requirements = array( |
|
1131 'requires' => ! empty( $plugin_headers['RequiresWP'] ) ? $plugin_headers['RequiresWP'] : '', |
|
1132 'requires_php' => ! empty( $plugin_headers['RequiresPHP'] ) ? $plugin_headers['RequiresPHP'] : '', |
|
1133 ); |
|
1134 |
1087 $readme_file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/readme.txt'; |
1135 $readme_file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/readme.txt'; |
1088 |
1136 |
1089 if ( file_exists( $readme_file ) ) { |
1137 if ( file_exists( $readme_file ) ) { |
1090 $plugin_data = get_file_data( |
1138 $readme_headers = get_file_data( |
1091 $readme_file, |
1139 $readme_file, |
1092 array( |
1140 array( |
1093 'requires' => 'Requires at least', |
1141 'requires' => 'Requires at least', |
1094 'requires_php' => 'Requires PHP', |
1142 'requires_php' => 'Requires PHP', |
1095 ), |
1143 ), |
1096 'plugin' |
1144 'plugin' |
1097 ); |
1145 ); |
1098 } else { |
1146 |
1099 return true; |
1147 $requirements = array_merge( $readme_headers, $requirements ); |
1100 } |
1148 } |
1101 |
1149 |
1102 $plugin_data['wp_compatible'] = is_wp_version_compatible( $plugin_data['requires'] ); |
1150 $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); |
1103 $plugin_data['php_compatible'] = is_php_version_compatible( $plugin_data['requires_php'] ); |
1151 $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); |
1104 |
1152 |
1105 $plugin_data = array_merge( $plugin_data, get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ) ); |
1153 /* translators: %s: URL to Update PHP page. */ |
1106 |
1154 $php_update_message = '</p><p>' . sprintf( |
1107 if ( ! $plugin_data['wp_compatible'] && ! $plugin_data['php_compatible'] ) { |
1155 __( '<a href="%s">Learn more about updating PHP</a>.' ), |
|
1156 esc_url( wp_get_update_php_url() ) |
|
1157 ); |
|
1158 |
|
1159 $annotation = wp_get_update_php_annotation(); |
|
1160 |
|
1161 if ( $annotation ) { |
|
1162 $php_update_message .= '</p><p><em>' . $annotation . '</em>'; |
|
1163 } |
|
1164 |
|
1165 if ( ! $compatible_wp && ! $compatible_php ) { |
1108 return new WP_Error( |
1166 return new WP_Error( |
1109 'plugin_wp_php_incompatible', |
1167 'plugin_wp_php_incompatible', |
1110 sprintf( |
1168 '<p>' . sprintf( |
1111 /* translators: %s: plugin name */ |
1169 /* translators: 1: Current WordPress version, 2: Current PHP version, 3: Plugin name, 4: Required WordPress version, 5: Required PHP version. */ |
1112 __( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.' ), |
1170 _x( '<strong>Error:</strong> Current versions of WordPress (%1$s) and PHP (%2$s) do not meet minimum requirements for %3$s. The plugin requires WordPress %4$s and PHP %5$s.', 'plugin' ), |
1113 $plugin_data['Name'] |
1171 get_bloginfo( 'version' ), |
1114 ) |
1172 phpversion(), |
|
1173 $plugin_headers['Name'], |
|
1174 $requirements['requires'], |
|
1175 $requirements['requires_php'] |
|
1176 ) . $php_update_message . '</p>' |
1115 ); |
1177 ); |
1116 } elseif ( ! $plugin_data['php_compatible'] ) { |
1178 } elseif ( ! $compatible_php ) { |
1117 return new WP_Error( |
1179 return new WP_Error( |
1118 'plugin_php_incompatible', |
1180 'plugin_php_incompatible', |
1119 sprintf( |
1181 '<p>' . sprintf( |
1120 /* translators: %s: plugin name */ |
1182 /* translators: 1: Current PHP version, 2: Plugin name, 3: Required PHP version. */ |
1121 __( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.' ), |
1183 _x( '<strong>Error:</strong> Current PHP version (%1$s) does not meet minimum requirements for %2$s. The plugin requires PHP %3$s.', 'plugin' ), |
1122 $plugin_data['Name'] |
1184 phpversion(), |
1123 ) |
1185 $plugin_headers['Name'], |
|
1186 $requirements['requires_php'] |
|
1187 ) . $php_update_message . '</p>' |
1124 ); |
1188 ); |
1125 } elseif ( ! $plugin_data['wp_compatible'] ) { |
1189 } elseif ( ! $compatible_wp ) { |
1126 return new WP_Error( |
1190 return new WP_Error( |
1127 'plugin_wp_incompatible', |
1191 'plugin_wp_incompatible', |
1128 sprintf( |
1192 '<p>' . sprintf( |
1129 /* translators: %s: plugin name */ |
1193 /* translators: 1: Current WordPress version, 2: Plugin name, 3: Required WordPress version. */ |
1130 __( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.' ), |
1194 _x( '<strong>Error:</strong> Current WordPress version (%1$s) does not meet minimum requirements for %2$s. The plugin requires WordPress %3$s.', 'plugin' ), |
1131 $plugin_data['Name'] |
1195 get_bloginfo( 'version' ), |
1132 ) |
1196 $plugin_headers['Name'], |
|
1197 $requirements['requires'] |
|
1198 ) . '</p>' |
1133 ); |
1199 ); |
1134 } |
1200 } |
1135 |
1201 |
1136 return true; |
1202 return true; |
1137 } |
1203 } |
1248 * * Pass a base64-encoded SVG using a data URI, which will be colored to match |
1315 * * Pass a base64-encoded SVG using a data URI, which will be colored to match |
1249 * the color scheme. This should begin with 'data:image/svg+xml;base64,'. |
1316 * the color scheme. This should begin with 'data:image/svg+xml;base64,'. |
1250 * * Pass the name of a Dashicons helper class to use a font icon, |
1317 * * Pass the name of a Dashicons helper class to use a font icon, |
1251 * e.g. 'dashicons-chart-pie'. |
1318 * e.g. 'dashicons-chart-pie'. |
1252 * * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS. |
1319 * * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS. |
1253 * @param int $position The position in the menu order this one should appear. |
1320 * @param int $position The position in the menu order this item should appear. |
1254 * @return string The resulting page's hook_suffix. |
1321 * @return string The resulting page's hook_suffix. |
1255 */ |
1322 */ |
1256 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = null ) { |
1323 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = null ) { |
1257 global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages; |
1324 global $menu, $admin_page_hooks, $_registered_pages, $_parent_pages; |
1258 |
1325 |
1319 * @param string $capability The capability required for this menu to be displayed to the user. |
1387 * @param string $capability The capability required for this menu to be displayed to the user. |
1320 * @param string $menu_slug The slug name to refer to this menu by. Should be unique for this menu |
1388 * @param string $menu_slug The slug name to refer to this menu by. Should be unique for this menu |
1321 * and only include lowercase alphanumeric, dashes, and underscores characters |
1389 * and only include lowercase alphanumeric, dashes, and underscores characters |
1322 * to be compatible with sanitize_key(). |
1390 * to be compatible with sanitize_key(). |
1323 * @param callable $function The function to be called to output the content for this page. |
1391 * @param callable $function The function to be called to output the content for this page. |
1324 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1392 * @param int $position The position in the menu order this item should appear. |
1325 */ |
1393 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1326 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1394 */ |
|
1395 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
1327 global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv, |
1396 global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv, |
1328 $_registered_pages, $_parent_pages; |
1397 $_registered_pages, $_parent_pages; |
1329 |
1398 |
1330 $menu_slug = plugin_basename( $menu_slug ); |
1399 $menu_slug = plugin_basename( $menu_slug ); |
1331 $parent_slug = plugin_basename( $parent_slug ); |
1400 $parent_slug = plugin_basename( $parent_slug ); |
1351 $submenu[ $parent_slug ][] = array_slice( $parent_menu, 0, 4 ); |
1420 $submenu[ $parent_slug ][] = array_slice( $parent_menu, 0, 4 ); |
1352 } |
1421 } |
1353 } |
1422 } |
1354 } |
1423 } |
1355 |
1424 |
1356 $submenu[ $parent_slug ][] = array( $menu_title, $capability, $menu_slug, $page_title ); |
1425 $new_sub_menu = array( $menu_title, $capability, $menu_slug, $page_title ); |
|
1426 if ( ! is_int( $position ) ) { |
|
1427 if ( null !== $position ) { |
|
1428 _doing_it_wrong( |
|
1429 __FUNCTION__, |
|
1430 sprintf( |
|
1431 /* translators: %s: add_submenu_page() */ |
|
1432 __( 'The seventh parameter passed to %s should be an integer representing menu position.' ), |
|
1433 '<code>add_submenu_page()</code>' |
|
1434 ), |
|
1435 '5.3.0' |
|
1436 ); |
|
1437 } |
|
1438 |
|
1439 $submenu[ $parent_slug ][] = $new_sub_menu; |
|
1440 } else { |
|
1441 // Append the submenu if the parent item is not present in the submenu, |
|
1442 // or if position is equal or higher than the number of items in the array. |
|
1443 if ( ! isset( $submenu[ $parent_slug ] ) || $position >= count( $submenu[ $parent_slug ] ) ) { |
|
1444 $submenu[ $parent_slug ][] = $new_sub_menu; |
|
1445 } else { |
|
1446 // Test for a negative position. |
|
1447 $position = max( $position, 0 ); |
|
1448 if ( 0 === $position ) { |
|
1449 // For negative or `0` positions, prepend the submenu. |
|
1450 array_unshift( $submenu[ $parent_slug ], $new_sub_menu ); |
|
1451 } else { |
|
1452 // Grab all of the items before the insertion point. |
|
1453 $before_items = array_slice( $submenu[ $parent_slug ], 0, $position, true ); |
|
1454 // Grab all of the items after the insertion point. |
|
1455 $after_items = array_slice( $submenu[ $parent_slug ], $position, null, true ); |
|
1456 // Add the new item. |
|
1457 $before_items[] = $new_sub_menu; |
|
1458 // Merge the items. |
|
1459 $submenu[ $parent_slug ] = array_merge( $before_items, $after_items ); |
|
1460 } |
|
1461 } |
|
1462 } |
|
1463 // Sort the parent array. |
|
1464 ksort( $submenu[ $parent_slug ] ); |
1357 |
1465 |
1358 $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug ); |
1466 $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug ); |
1359 if ( ! empty( $function ) && ! empty( $hookname ) ) { |
1467 if ( ! empty( $function ) && ! empty( $hookname ) ) { |
1360 add_action( $hookname, $function ); |
1468 add_action( $hookname, $function ); |
1361 } |
1469 } |
1384 * |
1492 * |
1385 * The function which is hooked in to handle the output of the page must check |
1493 * The function which is hooked in to handle the output of the page must check |
1386 * that the user has the required capability as well. |
1494 * that the user has the required capability as well. |
1387 * |
1495 * |
1388 * @since 1.5.0 |
1496 * @since 1.5.0 |
|
1497 * @since 5.3.0 Added the `$position` parameter. |
1389 * |
1498 * |
1390 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1499 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1391 * @param string $menu_title The text to be used for the menu. |
1500 * @param string $menu_title The text to be used for the menu. |
1392 * @param string $capability The capability required for this menu to be displayed to the user. |
1501 * @param string $capability The capability required for this menu to be displayed to the user. |
1393 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1502 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1394 * @param callable $function The function to be called to output the content for this page. |
1503 * @param callable $function The function to be called to output the content for this page. |
1395 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1504 * @param int $position The position in the menu order this item should appear. |
1396 */ |
1505 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1397 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1506 */ |
1398 return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1507 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1508 return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1399 } |
1509 } |
1400 |
1510 |
1401 /** |
1511 /** |
1402 * Add submenu page to the Settings main menu. |
1512 * Add submenu page to the Settings main menu. |
1403 * |
1513 * |
1406 * |
1516 * |
1407 * The function which is hooked in to handle the output of the page must check |
1517 * The function which is hooked in to handle the output of the page must check |
1408 * that the user has the required capability as well. |
1518 * that the user has the required capability as well. |
1409 * |
1519 * |
1410 * @since 1.5.0 |
1520 * @since 1.5.0 |
|
1521 * @since 5.3.0 Added the `$position` parameter. |
1411 * |
1522 * |
1412 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1523 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1413 * @param string $menu_title The text to be used for the menu. |
1524 * @param string $menu_title The text to be used for the menu. |
1414 * @param string $capability The capability required for this menu to be displayed to the user. |
1525 * @param string $capability The capability required for this menu to be displayed to the user. |
1415 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1526 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1416 * @param callable $function The function to be called to output the content for this page. |
1527 * @param callable $function The function to be called to output the content for this page. |
1417 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1528 * @param int $position The position in the menu order this item should appear. |
1418 */ |
1529 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1419 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1530 */ |
1420 return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1531 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1532 return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1421 } |
1533 } |
1422 |
1534 |
1423 /** |
1535 /** |
1424 * Add submenu page to the Appearance main menu. |
1536 * Add submenu page to the Appearance main menu. |
1425 * |
1537 * |
1428 * |
1540 * |
1429 * The function which is hooked in to handle the output of the page must check |
1541 * The function which is hooked in to handle the output of the page must check |
1430 * that the user has the required capability as well. |
1542 * that the user has the required capability as well. |
1431 * |
1543 * |
1432 * @since 2.0.0 |
1544 * @since 2.0.0 |
|
1545 * @since 5.3.0 Added the `$position` parameter. |
1433 * |
1546 * |
1434 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1547 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1435 * @param string $menu_title The text to be used for the menu. |
1548 * @param string $menu_title The text to be used for the menu. |
1436 * @param string $capability The capability required for this menu to be displayed to the user. |
1549 * @param string $capability The capability required for this menu to be displayed to the user. |
1437 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1550 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1438 * @param callable $function The function to be called to output the content for this page. |
1551 * @param callable $function The function to be called to output the content for this page. |
1439 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1552 * @param int $position The position in the menu order this item should appear. |
1440 */ |
1553 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1441 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1554 */ |
1442 return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1555 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1556 return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1443 } |
1557 } |
1444 |
1558 |
1445 /** |
1559 /** |
1446 * Add submenu page to the Plugins main menu. |
1560 * Add submenu page to the Plugins main menu. |
1447 * |
1561 * |
1450 * |
1564 * |
1451 * The function which is hooked in to handle the output of the page must check |
1565 * The function which is hooked in to handle the output of the page must check |
1452 * that the user has the required capability as well. |
1566 * that the user has the required capability as well. |
1453 * |
1567 * |
1454 * @since 3.0.0 |
1568 * @since 3.0.0 |
|
1569 * @since 5.3.0 Added the `$position` parameter. |
1455 * |
1570 * |
1456 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1571 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1457 * @param string $menu_title The text to be used for the menu. |
1572 * @param string $menu_title The text to be used for the menu. |
1458 * @param string $capability The capability required for this menu to be displayed to the user. |
1573 * @param string $capability The capability required for this menu to be displayed to the user. |
1459 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1574 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1460 * @param callable $function The function to be called to output the content for this page. |
1575 * @param callable $function The function to be called to output the content for this page. |
1461 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1576 * @param int $position The position in the menu order this item should appear. |
1462 */ |
1577 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1463 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1578 */ |
1464 return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1579 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1580 return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1465 } |
1581 } |
1466 |
1582 |
1467 /** |
1583 /** |
1468 * Add submenu page to the Users/Profile main menu. |
1584 * Add submenu page to the Users/Profile main menu. |
1469 * |
1585 * |
1472 * |
1588 * |
1473 * The function which is hooked in to handle the output of the page must check |
1589 * The function which is hooked in to handle the output of the page must check |
1474 * that the user has the required capability as well. |
1590 * that the user has the required capability as well. |
1475 * |
1591 * |
1476 * @since 2.1.3 |
1592 * @since 2.1.3 |
|
1593 * @since 5.3.0 Added the `$position` parameter. |
1477 * |
1594 * |
1478 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1595 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1479 * @param string $menu_title The text to be used for the menu. |
1596 * @param string $menu_title The text to be used for the menu. |
1480 * @param string $capability The capability required for this menu to be displayed to the user. |
1597 * @param string $capability The capability required for this menu to be displayed to the user. |
1481 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1598 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1482 * @param callable $function The function to be called to output the content for this page. |
1599 * @param callable $function The function to be called to output the content for this page. |
1483 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1600 * @param int $position The position in the menu order this item should appear. |
1484 */ |
1601 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1485 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1602 */ |
|
1603 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
1486 if ( current_user_can( 'edit_users' ) ) { |
1604 if ( current_user_can( 'edit_users' ) ) { |
1487 $parent = 'users.php'; |
1605 $parent = 'users.php'; |
1488 } else { |
1606 } else { |
1489 $parent = 'profile.php'; |
1607 $parent = 'profile.php'; |
1490 } |
1608 } |
1491 return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $function ); |
1609 return add_submenu_page( $parent, $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1492 } |
1610 } |
|
1611 |
1493 /** |
1612 /** |
1494 * Add submenu page to the Dashboard main menu. |
1613 * Add submenu page to the Dashboard main menu. |
1495 * |
1614 * |
1496 * This function takes a capability which will be used to determine whether |
1615 * This function takes a capability which will be used to determine whether |
1497 * or not a page is included in the menu. |
1616 * or not a page is included in the menu. |
1498 * |
1617 * |
1499 * The function which is hooked in to handle the output of the page must check |
1618 * The function which is hooked in to handle the output of the page must check |
1500 * that the user has the required capability as well. |
1619 * that the user has the required capability as well. |
1501 * |
1620 * |
1502 * @since 2.7.0 |
1621 * @since 2.7.0 |
|
1622 * @since 5.3.0 Added the `$position` parameter. |
1503 * |
1623 * |
1504 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1624 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1505 * @param string $menu_title The text to be used for the menu. |
1625 * @param string $menu_title The text to be used for the menu. |
1506 * @param string $capability The capability required for this menu to be displayed to the user. |
1626 * @param string $capability The capability required for this menu to be displayed to the user. |
1507 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1627 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1508 * @param callable $function The function to be called to output the content for this page. |
1628 * @param callable $function The function to be called to output the content for this page. |
1509 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1629 * @param int $position The position in the menu order this item should appear. |
1510 */ |
1630 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1511 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1631 */ |
1512 return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1632 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1633 return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1513 } |
1634 } |
1514 |
1635 |
1515 /** |
1636 /** |
1516 * Add submenu page to the Posts main menu. |
1637 * Add submenu page to the Posts main menu. |
1517 * |
1638 * |
1520 * |
1641 * |
1521 * The function which is hooked in to handle the output of the page must check |
1642 * The function which is hooked in to handle the output of the page must check |
1522 * that the user has the required capability as well. |
1643 * that the user has the required capability as well. |
1523 * |
1644 * |
1524 * @since 2.7.0 |
1645 * @since 2.7.0 |
|
1646 * @since 5.3.0 Added the `$position` parameter. |
1525 * |
1647 * |
1526 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1648 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1527 * @param string $menu_title The text to be used for the menu. |
1649 * @param string $menu_title The text to be used for the menu. |
1528 * @param string $capability The capability required for this menu to be displayed to the user. |
1650 * @param string $capability The capability required for this menu to be displayed to the user. |
1529 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1651 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1530 * @param callable $function The function to be called to output the content for this page. |
1652 * @param callable $function The function to be called to output the content for this page. |
1531 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1653 * @param int $position The position in the menu order this item should appear. |
1532 */ |
1654 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1533 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1655 */ |
1534 return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1656 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1657 return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1535 } |
1658 } |
1536 |
1659 |
1537 /** |
1660 /** |
1538 * Add submenu page to the Media main menu. |
1661 * Add submenu page to the Media main menu. |
1539 * |
1662 * |
1542 * |
1665 * |
1543 * The function which is hooked in to handle the output of the page must check |
1666 * The function which is hooked in to handle the output of the page must check |
1544 * that the user has the required capability as well. |
1667 * that the user has the required capability as well. |
1545 * |
1668 * |
1546 * @since 2.7.0 |
1669 * @since 2.7.0 |
|
1670 * @since 5.3.0 Added the `$position` parameter. |
1547 * |
1671 * |
1548 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1672 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1549 * @param string $menu_title The text to be used for the menu. |
1673 * @param string $menu_title The text to be used for the menu. |
1550 * @param string $capability The capability required for this menu to be displayed to the user. |
1674 * @param string $capability The capability required for this menu to be displayed to the user. |
1551 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1675 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1552 * @param callable $function The function to be called to output the content for this page. |
1676 * @param callable $function The function to be called to output the content for this page. |
1553 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1677 * @param int $position The position in the menu order this item should appear. |
1554 */ |
1678 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1555 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1679 */ |
1556 return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1680 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1681 return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1557 } |
1682 } |
1558 |
1683 |
1559 /** |
1684 /** |
1560 * Add submenu page to the Links main menu. |
1685 * Add submenu page to the Links main menu. |
1561 * |
1686 * |
1564 * |
1689 * |
1565 * The function which is hooked in to handle the output of the page must check |
1690 * The function which is hooked in to handle the output of the page must check |
1566 * that the user has the required capability as well. |
1691 * that the user has the required capability as well. |
1567 * |
1692 * |
1568 * @since 2.7.0 |
1693 * @since 2.7.0 |
|
1694 * @since 5.3.0 Added the `$position` parameter. |
1569 * |
1695 * |
1570 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1696 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1571 * @param string $menu_title The text to be used for the menu. |
1697 * @param string $menu_title The text to be used for the menu. |
1572 * @param string $capability The capability required for this menu to be displayed to the user. |
1698 * @param string $capability The capability required for this menu to be displayed to the user. |
1573 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1699 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1574 * @param callable $function The function to be called to output the content for this page. |
1700 * @param callable $function The function to be called to output the content for this page. |
1575 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1701 * @param int $position The position in the menu order this item should appear. |
1576 */ |
1702 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1577 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1703 */ |
1578 return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1704 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1705 return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1579 } |
1706 } |
1580 |
1707 |
1581 /** |
1708 /** |
1582 * Add submenu page to the Pages main menu. |
1709 * Add submenu page to the Pages main menu. |
1583 * |
1710 * |
1586 * |
1713 * |
1587 * The function which is hooked in to handle the output of the page must check |
1714 * The function which is hooked in to handle the output of the page must check |
1588 * that the user has the required capability as well. |
1715 * that the user has the required capability as well. |
1589 * |
1716 * |
1590 * @since 2.7.0 |
1717 * @since 2.7.0 |
|
1718 * @since 5.3.0 Added the `$position` parameter. |
1591 * |
1719 * |
1592 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1720 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1593 * @param string $menu_title The text to be used for the menu. |
1721 * @param string $menu_title The text to be used for the menu. |
1594 * @param string $capability The capability required for this menu to be displayed to the user. |
1722 * @param string $capability The capability required for this menu to be displayed to the user. |
1595 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1723 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1596 * @param callable $function The function to be called to output the content for this page. |
1724 * @param callable $function The function to be called to output the content for this page. |
1597 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1725 * @param int $position The position in the menu order this item should appear. |
1598 */ |
1726 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1599 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1727 */ |
1600 return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1728 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1729 return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1601 } |
1730 } |
1602 |
1731 |
1603 /** |
1732 /** |
1604 * Add submenu page to the Comments main menu. |
1733 * Add submenu page to the Comments main menu. |
1605 * |
1734 * |
1608 * |
1737 * |
1609 * The function which is hooked in to handle the output of the page must check |
1738 * The function which is hooked in to handle the output of the page must check |
1610 * that the user has the required capability as well. |
1739 * that the user has the required capability as well. |
1611 * |
1740 * |
1612 * @since 2.7.0 |
1741 * @since 2.7.0 |
|
1742 * @since 5.3.0 Added the `$position` parameter. |
1613 * |
1743 * |
1614 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1744 * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected. |
1615 * @param string $menu_title The text to be used for the menu. |
1745 * @param string $menu_title The text to be used for the menu. |
1616 * @param string $capability The capability required for this menu to be displayed to the user. |
1746 * @param string $capability The capability required for this menu to be displayed to the user. |
1617 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1747 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu). |
1618 * @param callable $function The function to be called to output the content for this page. |
1748 * @param callable $function The function to be called to output the content for this page. |
1619 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required. |
1749 * @param int $position The position in the menu order this item should appear. |
1620 */ |
1750 * @return string|false The resulting page's hook_suffix, or false if the user does not have the capability required. |
1621 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) { |
1751 */ |
1622 return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function ); |
1752 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $position = null ) { |
|
1753 return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function, $position ); |
1623 } |
1754 } |
1624 |
1755 |
1625 /** |
1756 /** |
1626 * Remove a top-level admin menu. |
1757 * Remove a top-level admin menu. |
1627 * |
1758 * |
1708 |
1839 |
1709 return $url; |
1840 return $url; |
1710 } |
1841 } |
1711 |
1842 |
1712 // |
1843 // |
1713 // Pluggable Menu Support -- Private |
1844 // Pluggable Menu Support -- Private. |
1714 // |
1845 // |
1715 /** |
1846 /** |
|
1847 * Gets the parent file of the current admin page. |
|
1848 * |
|
1849 * @since 1.5.0 |
|
1850 * |
1716 * @global string $parent_file |
1851 * @global string $parent_file |
1717 * @global array $menu |
1852 * @global array $menu |
1718 * @global array $submenu |
1853 * @global array $submenu |
1719 * @global string $pagenow |
1854 * @global string $pagenow |
1720 * @global string $typenow |
1855 * @global string $typenow |
1721 * @global string $plugin_page |
1856 * @global string $plugin_page |
1722 * @global array $_wp_real_parent_file |
1857 * @global array $_wp_real_parent_file |
1723 * @global array $_wp_menu_nopriv |
1858 * @global array $_wp_menu_nopriv |
1724 * @global array $_wp_submenu_nopriv |
1859 * @global array $_wp_submenu_nopriv |
1725 * |
1860 * |
1726 * @return string |
1861 * @param string $parent The slug name for the parent menu (or the file name of a standard |
|
1862 * WordPress admin page). Default empty string. |
|
1863 * @return string The parent file of the current admin page. |
1727 */ |
1864 */ |
1728 function get_admin_page_parent( $parent = '' ) { |
1865 function get_admin_page_parent( $parent = '' ) { |
1729 global $parent_file, $menu, $submenu, $pagenow, $typenow, |
1866 global $parent_file, $menu, $submenu, $pagenow, $typenow, |
1730 $plugin_page, $_wp_real_parent_file, $_wp_menu_nopriv, $_wp_submenu_nopriv; |
1867 $plugin_page, $_wp_real_parent_file, $_wp_menu_nopriv, $_wp_submenu_nopriv; |
1731 |
1868 |
1732 if ( ! empty( $parent ) && 'admin.php' != $parent ) { |
1869 if ( ! empty( $parent ) && 'admin.php' !== $parent ) { |
1733 if ( isset( $_wp_real_parent_file[ $parent ] ) ) { |
1870 if ( isset( $_wp_real_parent_file[ $parent ] ) ) { |
1734 $parent = $_wp_real_parent_file[ $parent ]; |
1871 $parent = $_wp_real_parent_file[ $parent ]; |
1735 } |
1872 } |
1736 return $parent; |
1873 return $parent; |
1737 } |
1874 } |
1738 |
1875 |
1739 if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) { |
1876 if ( 'admin.php' === $pagenow && isset( $plugin_page ) ) { |
1740 foreach ( (array) $menu as $parent_menu ) { |
1877 foreach ( (array) $menu as $parent_menu ) { |
1741 if ( $parent_menu[2] == $plugin_page ) { |
1878 if ( $parent_menu[2] == $plugin_page ) { |
1742 $parent_file = $plugin_page; |
1879 $parent_file = $plugin_page; |
1743 if ( isset( $_wp_real_parent_file[ $parent_file ] ) ) { |
1880 if ( isset( $_wp_real_parent_file[ $parent_file ] ) ) { |
1744 $parent_file = $_wp_real_parent_file[ $parent_file ]; |
1881 $parent_file = $_wp_real_parent_file[ $parent_file ]; |
1786 } |
1923 } |
1787 return ''; |
1924 return ''; |
1788 } |
1925 } |
1789 |
1926 |
1790 /** |
1927 /** |
|
1928 * Gets the title of the current admin page. |
|
1929 * |
|
1930 * @since 1.5.0 |
|
1931 * |
1791 * @global string $title |
1932 * @global string $title |
1792 * @global array $menu |
1933 * @global array $menu |
1793 * @global array $submenu |
1934 * @global array $submenu |
1794 * @global string $pagenow |
1935 * @global string $pagenow |
1795 * @global string $plugin_page |
1936 * @global string $plugin_page |
1796 * @global string $typenow |
1937 * @global string $typenow |
1797 * |
1938 * |
1798 * @return string |
1939 * @return string The title of the current admin page. |
1799 */ |
1940 */ |
1800 function get_admin_page_title() { |
1941 function get_admin_page_title() { |
1801 global $title, $menu, $submenu, $pagenow, $plugin_page, $typenow; |
1942 global $title, $menu, $submenu, $pagenow, $plugin_page, $typenow; |
1802 |
1943 |
1803 if ( ! empty( $title ) ) { |
1944 if ( ! empty( $title ) ) { |
1804 return $title; |
1945 return $title; |
1805 } |
1946 } |
1806 |
1947 |
1807 $hook = get_plugin_page_hook( $plugin_page, $pagenow ); |
1948 $hook = get_plugin_page_hook( $plugin_page, $pagenow ); |
1808 |
1949 |
1809 $parent = $parent1 = get_admin_page_parent(); |
1950 $parent = get_admin_page_parent(); |
|
1951 $parent1 = $parent; |
1810 |
1952 |
1811 if ( empty( $parent ) ) { |
1953 if ( empty( $parent ) ) { |
1812 foreach ( (array) $menu as $menu_array ) { |
1954 foreach ( (array) $menu as $menu_array ) { |
1813 if ( isset( $menu_array[3] ) ) { |
1955 if ( isset( $menu_array[3] ) ) { |
1814 if ( $menu_array[2] == $pagenow ) { |
1956 if ( $menu_array[2] == $pagenow ) { |
1815 $title = $menu_array[3]; |
1957 $title = $menu_array[3]; |
1816 return $menu_array[3]; |
1958 return $menu_array[3]; |
1817 } elseif ( isset( $plugin_page ) && ( $plugin_page == $menu_array[2] ) && ( $hook == $menu_array[3] ) ) { |
1959 } elseif ( isset( $plugin_page ) && ( $plugin_page == $menu_array[2] ) && ( $hook == $menu_array[5] ) ) { |
1818 $title = $menu_array[3]; |
1960 $title = $menu_array[3]; |
1819 return $menu_array[3]; |
1961 return $menu_array[3]; |
1820 } |
1962 } |
1821 } else { |
1963 } else { |
1822 $title = $menu_array[0]; |
1964 $title = $menu_array[0]; |
1914 |
2062 |
1915 return $page_type . '_page_' . $plugin_name; |
2063 return $page_type . '_page_' . $plugin_name; |
1916 } |
2064 } |
1917 |
2065 |
1918 /** |
2066 /** |
|
2067 * Determines whether the current user can access the current admin page. |
|
2068 * |
|
2069 * @since 1.5.0 |
|
2070 * |
1919 * @global string $pagenow |
2071 * @global string $pagenow |
1920 * @global array $menu |
2072 * @global array $menu |
1921 * @global array $submenu |
2073 * @global array $submenu |
1922 * @global array $_wp_menu_nopriv |
2074 * @global array $_wp_menu_nopriv |
1923 * @global array $_wp_submenu_nopriv |
2075 * @global array $_wp_submenu_nopriv |
1924 * @global string $plugin_page |
2076 * @global string $plugin_page |
1925 * @global array $_registered_pages |
2077 * @global array $_registered_pages |
1926 * |
2078 * |
1927 * @return bool Whether the current user can access the current admin page. |
2079 * @return bool True if the current user can access the admin page, false otherwise. |
1928 */ |
2080 */ |
1929 function user_can_access_admin_page() { |
2081 function user_can_access_admin_page() { |
1930 global $pagenow, $menu, $submenu, $_wp_menu_nopriv, $_wp_submenu_nopriv, |
2082 global $pagenow, $menu, $submenu, $_wp_menu_nopriv, $_wp_submenu_nopriv, |
1931 $plugin_page, $_registered_pages; |
2083 $plugin_page, $_registered_pages; |
1932 |
2084 |
2005 } |
2157 } |
2006 |
2158 |
2007 return true; |
2159 return true; |
2008 } |
2160 } |
2009 |
2161 |
2010 /* Whitelist functions */ |
2162 /* Allowed list functions */ |
2011 |
2163 |
2012 /** |
2164 /** |
2013 * Refreshes the value of the options whitelist available via the 'whitelist_options' hook. |
2165 * Refreshes the value of the allowed options list available via the 'allowed_options' hook. |
2014 * |
2166 * |
2015 * See the {@see 'whitelist_options'} filter. |
2167 * See the {@see 'allowed_options'} filter. |
2016 * |
2168 * |
2017 * @since 2.7.0 |
2169 * @since 2.7.0 |
2018 * |
2170 * @since 5.5.0 `$new_whitelist_options` was renamed to `$new_allowed_options`. |
2019 * @global array $new_whitelist_options |
2171 * Please consider writing more inclusive code. |
|
2172 * |
|
2173 * @global array $new_allowed_options |
2020 * |
2174 * |
2021 * @param array $options |
2175 * @param array $options |
2022 * @return array |
2176 * @return array |
2023 */ |
2177 */ |
2024 function option_update_filter( $options ) { |
2178 function option_update_filter( $options ) { |
2025 global $new_whitelist_options; |
2179 global $new_allowed_options; |
2026 |
2180 |
2027 if ( is_array( $new_whitelist_options ) ) { |
2181 if ( is_array( $new_allowed_options ) ) { |
2028 $options = add_option_whitelist( $new_whitelist_options, $options ); |
2182 $options = add_allowed_options( $new_allowed_options, $options ); |
2029 } |
2183 } |
2030 |
2184 |
2031 return $options; |
2185 return $options; |
2032 } |
2186 } |
2033 |
2187 |
2034 /** |
2188 /** |
2035 * Adds an array of options to the options whitelist. |
2189 * Adds an array of options to the list of allowed options. |
2036 * |
2190 * |
2037 * @since 2.7.0 |
2191 * @since 2.7.0 |
2038 * |
2192 * |
2039 * @global array $whitelist_options |
2193 * @global array $allowed_options |
2040 * |
2194 * |
2041 * @param array $new_options |
2195 * @param array $new_options |
2042 * @param string|array $options |
2196 * @param string|array $options |
2043 * @return array |
2197 * @return array |
2044 */ |
2198 */ |
2045 function add_option_whitelist( $new_options, $options = '' ) { |
2199 function add_allowed_options( $new_options, $options = '' ) { |
2046 if ( $options == '' ) { |
2200 if ( '' === $options ) { |
2047 global $whitelist_options; |
2201 global $allowed_options; |
2048 } else { |
2202 } else { |
2049 $whitelist_options = $options; |
2203 $allowed_options = $options; |
2050 } |
2204 } |
2051 |
2205 |
2052 foreach ( $new_options as $page => $keys ) { |
2206 foreach ( $new_options as $page => $keys ) { |
2053 foreach ( $keys as $key ) { |
2207 foreach ( $keys as $key ) { |
2054 if ( ! isset( $whitelist_options[ $page ] ) || ! is_array( $whitelist_options[ $page ] ) ) { |
2208 if ( ! isset( $allowed_options[ $page ] ) || ! is_array( $allowed_options[ $page ] ) ) { |
2055 $whitelist_options[ $page ] = array(); |
2209 $allowed_options[ $page ] = array(); |
2056 $whitelist_options[ $page ][] = $key; |
2210 $allowed_options[ $page ][] = $key; |
2057 } else { |
2211 } else { |
2058 $pos = array_search( $key, $whitelist_options[ $page ] ); |
2212 $pos = array_search( $key, $allowed_options[ $page ], true ); |
2059 if ( $pos === false ) { |
2213 if ( false === $pos ) { |
2060 $whitelist_options[ $page ][] = $key; |
2214 $allowed_options[ $page ][] = $key; |
2061 } |
2215 } |
2062 } |
2216 } |
2063 } |
2217 } |
2064 } |
2218 } |
2065 |
2219 |
2066 return $whitelist_options; |
2220 return $allowed_options; |
2067 } |
2221 } |
2068 |
2222 |
2069 /** |
2223 /** |
2070 * Removes a list of options from the options whitelist. |
2224 * Removes a list of options from the allowed options list. |
2071 * |
2225 * |
2072 * @since 2.7.0 |
2226 * @since 5.5.0 |
2073 * |
2227 * |
2074 * @global array $whitelist_options |
2228 * @global array $allowed_options |
2075 * |
2229 * |
2076 * @param array $del_options |
2230 * @param array $del_options |
2077 * @param string|array $options |
2231 * @param string|array $options |
2078 * @return array |
2232 * @return array |
2079 */ |
2233 */ |
2080 function remove_option_whitelist( $del_options, $options = '' ) { |
2234 function remove_allowed_options( $del_options, $options = '' ) { |
2081 if ( $options == '' ) { |
2235 if ( '' === $options ) { |
2082 global $whitelist_options; |
2236 global $allowed_options; |
2083 } else { |
2237 } else { |
2084 $whitelist_options = $options; |
2238 $allowed_options = $options; |
2085 } |
2239 } |
2086 |
2240 |
2087 foreach ( $del_options as $page => $keys ) { |
2241 foreach ( $del_options as $page => $keys ) { |
2088 foreach ( $keys as $key ) { |
2242 foreach ( $keys as $key ) { |
2089 if ( isset( $whitelist_options[ $page ] ) && is_array( $whitelist_options[ $page ] ) ) { |
2243 if ( isset( $allowed_options[ $page ] ) && is_array( $allowed_options[ $page ] ) ) { |
2090 $pos = array_search( $key, $whitelist_options[ $page ] ); |
2244 $pos = array_search( $key, $allowed_options[ $page ], true ); |
2091 if ( $pos !== false ) { |
2245 if ( false !== $pos ) { |
2092 unset( $whitelist_options[ $page ][ $pos ] ); |
2246 unset( $allowed_options[ $page ][ $pos ] ); |
2093 } |
2247 } |
2094 } |
2248 } |
2095 } |
2249 } |
2096 } |
2250 } |
2097 |
2251 |
2098 return $whitelist_options; |
2252 return $allowed_options; |
2099 } |
2253 } |
2100 |
2254 |
2101 /** |
2255 /** |
2102 * Output nonce, action, and option_page fields for a settings page. |
2256 * Output nonce, action, and option_page fields for a settings page. |
2103 * |
2257 * |
2104 * @since 2.7.0 |
2258 * @since 2.7.0 |
2105 * |
2259 * |
2106 * @param string $option_group A settings group name. This should match the group name used in register_setting(). |
2260 * @param string $option_group A settings group name. This should match the group name |
|
2261 * used in register_setting(). |
2107 */ |
2262 */ |
2108 function settings_fields( $option_group ) { |
2263 function settings_fields( $option_group ) { |
2109 echo "<input type='hidden' name='option_page' value='" . esc_attr( $option_group ) . "' />"; |
2264 echo "<input type='hidden' name='option_page' value='" . esc_attr( $option_group ) . "' />"; |
2110 echo '<input type="hidden" name="action" value="update" />'; |
2265 echo '<input type="hidden" name="action" value="update" />'; |
2111 wp_nonce_field( "$option_group-options" ); |
2266 wp_nonce_field( "$option_group-options" ); |
2112 } |
2267 } |
2113 |
2268 |
2114 /** |
2269 /** |
2115 * Clears the Plugins cache used by get_plugins() and by default, the Plugin Update cache. |
2270 * Clears the plugins cache used by get_plugins() and by default, the plugin updates cache. |
2116 * |
2271 * |
2117 * @since 3.7.0 |
2272 * @since 3.7.0 |
2118 * |
2273 * |
2119 * @param bool $clear_update_cache Whether to clear the Plugin updates cache |
2274 * @param bool $clear_update_cache Whether to clear the plugin updates cache. Default true. |
2120 */ |
2275 */ |
2121 function wp_clean_plugins_cache( $clear_update_cache = true ) { |
2276 function wp_clean_plugins_cache( $clear_update_cache = true ) { |
2122 if ( $clear_update_cache ) { |
2277 if ( $clear_update_cache ) { |
2123 delete_site_transient( 'update_plugins' ); |
2278 delete_site_transient( 'update_plugins' ); |
2124 } |
2279 } |