2007-05-25 03:16:21 -04:00
< ? php
2008-07-17 18:51:26 -04:00
/**
* WordPress Plugin Administration API
*
* @ package WordPress
* @ subpackage Administration
*/
2007-05-25 03:16:21 -04:00
2008-07-17 18:51:26 -04:00
/**
2015-10-04 15:06:27 -04:00
* Parses the plugin contents to retrieve plugin ' s metadata .
2008-07-17 18:51:26 -04:00
*
2019-08-30 12:57:56 -04:00
* All plugin headers must be on their own line . Plugin description must not have
* any newlines , otherwise only parts of the description will be displayed .
* The below is formatted for printing .
2008-07-17 18:51:26 -04:00
*
2014-11-24 01:05:23 -05:00
* /*
2019-08-30 12:16:57 -04:00
* Plugin Name : Name of the plugin .
* Plugin URI : The home page of the plugin .
* Description : Plugin description .
* Author : Plugin author ' s name .
* Author URI : Link to the author ' s website .
* Version : Plugin version .
2014-11-24 01:05:23 -05:00
* Text Domain : Optional . Unique identifier , should be same as the one used in
2019-08-30 12:16:57 -04:00
* load_plugin_textdomain () .
2014-11-24 01:05:23 -05:00
* Domain Path : Optional . Only useful if the translations are located in a
2017-11-30 18:11:00 -05:00
* folder above the plugin ' s base path . For example , if . mo files are
* located in the locale folder then Domain Path will be " /locale/ " and
* must have the first slash . Defaults to the base folder the plugin is
* located in .
2014-11-24 01:05:23 -05:00
* Network : Optional . Specify " Network: true " to require that a plugin is activated
2017-11-30 18:11:00 -05:00
* across all sites in an installation . This will prevent a plugin from being
* activated on a single site when Multisite is enabled .
2019-06-17 23:24:52 -04:00
* Requires at least : Optional . Specify the minimum required WordPress version .
* Requires PHP : Optional . Specify the minimum required PHP version .
2019-08-30 12:57:56 -04:00
* * / # Remove the space to close comment.
2008-07-17 18:51:26 -04:00
*
2019-08-30 12:57:56 -04:00
* The first 8 KB of the file will be pulled in and if the plugin data is not
* within that first 8 KB , then the plugin author should correct their plugin
2008-07-22 15:18:07 -04:00
* and move the plugin data headers to the top .
*
* The plugin file is assumed to have permissions to allow for scripts to read
* the file . This is not checked however and the file is only opened for
* reading .
*
* @ since 1.5 . 0
2019-08-30 12:57:56 -04:00
* @ since 5.3 . 0 Added support for `Requires at least` and `Requires PHP` headers .
Plugins: Add support for `Update URI` header.
This allows third-party plugins to avoid accidentally being overwritten with an update of a plugin of a similar name from the WordPress.org Plugin Directory.
Additionally, introduce the `update_plugins_{$hostname}` filter, which third-party plugins can use to offer updates for a given hostname.
If set, the `Update URI` header field should be a URI and have a unique hostname.
Some examples include:
* `https://wordpress.org/plugins/example-plugin/`
* `https://example.com/my-plugin/`
* `my-custom-plugin-name`
`Update URI: false` also works, and unless there is code handling the `false` hostname, the plugin will never get an update notification.
If the header is present, the WordPress.org API will currently only return updates for the plugin if it matches the following format:
* `https://wordpress.org/plugins/{$slug}/`
* `w.org/plugin/{$slug}`
If the header has any other value, the API will not return a result and will ignore the plugin for update purposes.
Props dd32, DavidAnderson, meloniq, markjaquith, DrewAPicture, mweichert, design_dolphin, filosofo, sean212, nhuja, JeroenReumkens, infolu, dingdang, joyously, earnjam, williampatton, grapplerulrich, markparnell, apedog, afragen, miqrogroove, rmccue, crazycoders, jdgrimes, damonganto, joostdevalk, jorbin, georgestephanis, khromov, GeekStreetWP, jb510, Rarst, juliobox, Ipstenu, mikejolley, Otto42, gMagicScott, TJNowell, GaryJ, knutsp, mordauk, nvartolomei, aspexi, chriscct7, benoitchantre, ryno267, lev0, gregorlove, dougwollison, SergeyBiryukov.
See #14179, #23318, #32101.
Built from https://develop.svn.wordpress.org/trunk@50921
git-svn-id: http://core.svn.wordpress.org/trunk@50530 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2021-05-17 13:04:01 -04:00
* @ since 5.8 . 0 Added support for `Update URI` header .
2008-07-17 18:51:26 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin_file Absolute path to the main plugin file .
2015-10-04 15:06:27 -04:00
* @ param bool $markup Optional . If the returned data should have HTML markup applied .
* Default true .
* @ param bool $translate Optional . If the returned data should be translated . Default true .
* @ return array {
* Plugin data . Values will be empty if not supplied by the plugin .
*
* @ type string $Name Name of the plugin . Should be unique .
* @ type string $Title Title of the plugin and link to the plugin ' s site ( if set ) .
* @ type string $Description Plugin description .
* @ type string $Author Author ' s name .
* @ type string $AuthorURI Author ' s website address ( if set ) .
* @ type string $Version Plugin version .
* @ type string $TextDomain Plugin textdomain .
* @ type string $DomainPath Plugins relative directory path to . mo files .
* @ type bool $Network Whether the plugin can only be activated network - wide .
2019-06-17 23:24:52 -04:00
* @ type string $RequiresWP Minimum required version of WordPress .
* @ type string $RequiresPHP Minimum required version of PHP .
Plugins: Add support for `Update URI` header.
This allows third-party plugins to avoid accidentally being overwritten with an update of a plugin of a similar name from the WordPress.org Plugin Directory.
Additionally, introduce the `update_plugins_{$hostname}` filter, which third-party plugins can use to offer updates for a given hostname.
If set, the `Update URI` header field should be a URI and have a unique hostname.
Some examples include:
* `https://wordpress.org/plugins/example-plugin/`
* `https://example.com/my-plugin/`
* `my-custom-plugin-name`
`Update URI: false` also works, and unless there is code handling the `false` hostname, the plugin will never get an update notification.
If the header is present, the WordPress.org API will currently only return updates for the plugin if it matches the following format:
* `https://wordpress.org/plugins/{$slug}/`
* `w.org/plugin/{$slug}`
If the header has any other value, the API will not return a result and will ignore the plugin for update purposes.
Props dd32, DavidAnderson, meloniq, markjaquith, DrewAPicture, mweichert, design_dolphin, filosofo, sean212, nhuja, JeroenReumkens, infolu, dingdang, joyously, earnjam, williampatton, grapplerulrich, markparnell, apedog, afragen, miqrogroove, rmccue, crazycoders, jdgrimes, damonganto, joostdevalk, jorbin, georgestephanis, khromov, GeekStreetWP, jb510, Rarst, juliobox, Ipstenu, mikejolley, Otto42, gMagicScott, TJNowell, GaryJ, knutsp, mordauk, nvartolomei, aspexi, chriscct7, benoitchantre, ryno267, lev0, gregorlove, dougwollison, SergeyBiryukov.
See #14179, #23318, #32101.
Built from https://develop.svn.wordpress.org/trunk@50921
git-svn-id: http://core.svn.wordpress.org/trunk@50530 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2021-05-17 13:04:01 -04:00
* @ type string $UpdateURI ID of the plugin for update purposes , should be a URI .
2015-10-04 15:06:27 -04:00
* }
2008-07-17 18:51:26 -04:00
*/
2008-10-21 20:08:22 -04:00
function get_plugin_data ( $plugin_file , $markup = true , $translate = true ) {
2008-07-22 15:18:07 -04:00
2010-01-15 17:11:12 -05:00
$default_headers = array (
2017-11-30 18:11:00 -05:00
'Name' => 'Plugin Name' ,
'PluginURI' => 'Plugin URI' ,
'Version' => 'Version' ,
2010-01-15 17:11:12 -05:00
'Description' => 'Description' ,
2017-11-30 18:11:00 -05:00
'Author' => 'Author' ,
'AuthorURI' => 'Author URI' ,
'TextDomain' => 'Text Domain' ,
'DomainPath' => 'Domain Path' ,
'Network' => 'Network' ,
2019-06-17 23:24:52 -04:00
'RequiresWP' => 'Requires at least' ,
'RequiresPHP' => 'Requires PHP' ,
Plugins: Add support for `Update URI` header.
This allows third-party plugins to avoid accidentally being overwritten with an update of a plugin of a similar name from the WordPress.org Plugin Directory.
Additionally, introduce the `update_plugins_{$hostname}` filter, which third-party plugins can use to offer updates for a given hostname.
If set, the `Update URI` header field should be a URI and have a unique hostname.
Some examples include:
* `https://wordpress.org/plugins/example-plugin/`
* `https://example.com/my-plugin/`
* `my-custom-plugin-name`
`Update URI: false` also works, and unless there is code handling the `false` hostname, the plugin will never get an update notification.
If the header is present, the WordPress.org API will currently only return updates for the plugin if it matches the following format:
* `https://wordpress.org/plugins/{$slug}/`
* `w.org/plugin/{$slug}`
If the header has any other value, the API will not return a result and will ignore the plugin for update purposes.
Props dd32, DavidAnderson, meloniq, markjaquith, DrewAPicture, mweichert, design_dolphin, filosofo, sean212, nhuja, JeroenReumkens, infolu, dingdang, joyously, earnjam, williampatton, grapplerulrich, markparnell, apedog, afragen, miqrogroove, rmccue, crazycoders, jdgrimes, damonganto, joostdevalk, jorbin, georgestephanis, khromov, GeekStreetWP, jb510, Rarst, juliobox, Ipstenu, mikejolley, Otto42, gMagicScott, TJNowell, GaryJ, knutsp, mordauk, nvartolomei, aspexi, chriscct7, benoitchantre, ryno267, lev0, gregorlove, dougwollison, SergeyBiryukov.
See #14179, #23318, #32101.
Built from https://develop.svn.wordpress.org/trunk@50921
git-svn-id: http://core.svn.wordpress.org/trunk@50530 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2021-05-17 13:04:01 -04:00
'UpdateURI' => 'Update URI' ,
2010-02-05 16:33:53 -05:00
// Site Wide Only is deprecated in favor of Network.
2017-11-30 18:11:00 -05:00
'_sitewide' => 'Site Wide Only' ,
2010-02-05 16:33:53 -05:00
);
2008-07-22 15:18:07 -04:00
2009-10-15 17:07:00 -04:00
$plugin_data = get_file_data ( $plugin_file , $default_headers , 'plugin' );
2008-07-22 15:18:07 -04:00
2019-10-05 22:23:03 -04:00
// Site Wide Only is the old header for Network.
2012-03-20 19:04:59 -04:00
if ( ! $plugin_data [ 'Network' ] && $plugin_data [ '_sitewide' ] ) {
2015-09-18 16:29:26 -04:00
/* translators: 1: Site Wide Only: true, 2: Network: true */
2016-07-06 08:40:29 -04:00
_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>' ) );
2010-02-05 16:33:53 -05:00
$plugin_data [ 'Network' ] = $plugin_data [ '_sitewide' ];
}
2020-05-16 14:42:12 -04:00
$plugin_data [ 'Network' ] = ( 'true' === strtolower ( $plugin_data [ 'Network' ] ) );
2010-02-05 16:33:53 -05:00
unset ( $plugin_data [ '_sitewide' ] );
2016-05-25 12:54:28 -04:00
// If no text domain is defined fall back to the plugin slug.
if ( ! $plugin_data [ 'TextDomain' ] ) {
$plugin_slug = dirname ( plugin_basename ( $plugin_file ) );
2016-05-26 19:15:31 -04:00
if ( '.' !== $plugin_slug && false === strpos ( $plugin_slug , '/' ) ) {
2016-05-25 12:54:28 -04:00
$plugin_data [ 'TextDomain' ] = $plugin_slug ;
}
}
2012-03-20 19:04:59 -04:00
if ( $markup || $translate ) {
2009-10-15 17:07:00 -04:00
$plugin_data = _get_plugin_data_markup_translate ( $plugin_file , $plugin_data , $markup , $translate );
2012-03-20 19:04:59 -04:00
} else {
$plugin_data [ 'Title' ] = $plugin_data [ 'Name' ];
2010-12-06 16:18:18 -05:00
$plugin_data [ 'AuthorName' ] = $plugin_data [ 'Author' ];
2012-03-20 19:04:59 -04:00
}
2009-02-22 15:05:11 -05:00
2008-10-21 20:08:22 -04:00
return $plugin_data ;
}
2012-03-20 19:04:59 -04:00
/**
* Sanitizes plugin data , optionally adds markup , optionally translates .
*
* @ since 2.7 . 0
2019-01-14 01:54:49 -05:00
*
2012-03-20 19:04:59 -04:00
* @ see get_plugin_data ()
2019-01-14 01:54:49 -05:00
*
* @ access private
*
* @ param string $plugin_file Path to the main plugin file .
* @ param array $plugin_data An array of plugin data . See `get_plugin_data()` .
* @ param bool $markup Optional . If the returned data should have HTML markup applied .
* Default true .
* @ param bool $translate Optional . If the returned data should be translated . Default true .
* @ return array {
* Plugin data . Values will be empty if not supplied by the plugin .
*
* @ type string $Name Name of the plugin . Should be unique .
* @ type string $Title Title of the plugin and link to the plugin ' s site ( if set ) .
* @ type string $Description Plugin description .
* @ type string $Author Author ' s name .
* @ type string $AuthorURI Author ' s website address ( if set ) .
* @ type string $Version Plugin version .
* @ type string $TextDomain Plugin textdomain .
* @ type string $DomainPath Plugins relative directory path to . mo files .
* @ type bool $Network Whether the plugin can only be activated network - wide .
* }
2012-03-20 19:04:59 -04:00
*/
function _get_plugin_data_markup_translate ( $plugin_file , $plugin_data , $markup = true , $translate = true ) {
2008-10-21 20:08:22 -04:00
2019-10-05 22:23:03 -04:00
// Sanitize the plugin filename to a WP_PLUGIN_DIR relative path.
2013-08-22 00:03:09 -04:00
$plugin_file = plugin_basename ( $plugin_file );
2019-10-05 22:23:03 -04:00
// Translate fields.
2012-02-21 10:26:08 -05:00
if ( $translate ) {
2019-07-01 08:52:01 -04:00
$textdomain = $plugin_data [ 'TextDomain' ];
if ( $textdomain ) {
2016-01-13 08:04:27 -05:00
if ( ! is_textdomain_loaded ( $textdomain ) ) {
if ( $plugin_data [ 'DomainPath' ] ) {
load_plugin_textdomain ( $textdomain , false , dirname ( $plugin_file ) . $plugin_data [ 'DomainPath' ] );
} else {
load_plugin_textdomain ( $textdomain , false , dirname ( $plugin_file ) );
}
}
2020-05-16 14:42:12 -04:00
} elseif ( 'hello.php' === basename ( $plugin_file ) ) {
2012-02-21 10:26:08 -05:00
$textdomain = 'default' ;
}
if ( $textdomain ) {
2017-11-30 18:11:00 -05:00
foreach ( array ( 'Name' , 'PluginURI' , 'Description' , 'Author' , 'AuthorURI' , 'Version' ) as $field ) {
2019-01-11 01:04:49 -05:00
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain
2012-02-21 10:26:08 -05:00
$plugin_data [ $field ] = translate ( $plugin_data [ $field ], $textdomain );
2017-11-30 18:11:00 -05:00
}
2012-02-21 10:26:08 -05:00
}
2008-10-21 20:08:22 -04:00
}
2019-10-05 22:23:03 -04:00
// Sanitize fields.
2019-01-14 21:41:50 -05:00
$allowed_tags_in_links = array (
2012-03-20 19:04:59 -04:00
'abbr' => array ( 'title' => true ),
'acronym' => array ( 'title' => true ),
'code' => true ,
'em' => true ,
'strong' => true ,
2010-12-06 15:49:54 -05:00
);
2019-01-14 21:41:50 -05:00
$allowed_tags = $allowed_tags_in_links ;
2017-11-30 18:11:00 -05:00
$allowed_tags [ 'a' ] = array (
'href' => true ,
'title' => true ,
);
2010-12-06 15:49:54 -05:00
2012-03-20 19:04:59 -04:00
// Name is marked up inside <a> tags. Don't allow these.
// Author is too, but some plugins have used <a> here (omitting Author URI).
2017-11-30 18:11:00 -05:00
$plugin_data [ 'Name' ] = wp_kses ( $plugin_data [ 'Name' ], $allowed_tags_in_links );
$plugin_data [ 'Author' ] = wp_kses ( $plugin_data [ 'Author' ], $allowed_tags );
2010-12-06 15:49:54 -05:00
2012-03-20 19:04:59 -04:00
$plugin_data [ 'Description' ] = wp_kses ( $plugin_data [ 'Description' ], $allowed_tags );
2017-11-30 18:11:00 -05:00
$plugin_data [ 'Version' ] = wp_kses ( $plugin_data [ 'Version' ], $allowed_tags );
2012-03-20 19:04:59 -04:00
2017-11-30 18:11:00 -05:00
$plugin_data [ 'PluginURI' ] = esc_url ( $plugin_data [ 'PluginURI' ] );
$plugin_data [ 'AuthorURI' ] = esc_url ( $plugin_data [ 'AuthorURI' ] );
2012-03-20 19:04:59 -04:00
$plugin_data [ 'Title' ] = $plugin_data [ 'Name' ];
$plugin_data [ 'AuthorName' ] = $plugin_data [ 'Author' ];
2019-10-05 22:23:03 -04:00
// Apply markup.
2008-10-21 20:08:22 -04:00
if ( $markup ) {
2017-11-30 18:11:00 -05:00
if ( $plugin_data [ 'PluginURI' ] && $plugin_data [ 'Name' ] ) {
2014-06-05 00:52:16 -04:00
$plugin_data [ 'Title' ] = '<a href="' . $plugin_data [ 'PluginURI' ] . '">' . $plugin_data [ 'Name' ] . '</a>' ;
2017-11-30 18:11:00 -05:00
}
2008-10-21 20:08:22 -04:00
2017-11-30 18:11:00 -05:00
if ( $plugin_data [ 'AuthorURI' ] && $plugin_data [ 'Author' ] ) {
2014-06-05 00:52:16 -04:00
$plugin_data [ 'Author' ] = '<a href="' . $plugin_data [ 'AuthorURI' ] . '">' . $plugin_data [ 'Author' ] . '</a>' ;
2017-11-30 18:11:00 -05:00
}
2008-10-21 20:08:22 -04:00
$plugin_data [ 'Description' ] = wptexturize ( $plugin_data [ 'Description' ] );
2017-11-30 18:11:00 -05:00
if ( $plugin_data [ 'Author' ] ) {
I18N: Improve translator comments.
* Add missing translator comments.
* Fix placement of some translator comments. Translator comments should be on the line directly above the line containing the translation function call for optimal compatibility with various `.pot` file generation tools. The CS auto-fixing, which changed some inconsistent function calls to multi-line function calls, is part of the reason why this was no longer the case for a select group of translator comments.
Includes minor code layout fixes.
Polyglots, rejoice! All WordPress core files now have translator comments for all strings with placeholders!
Props jrf, subrataemfluence, GaryJ, webdados, Dency, swissspidy, alvarogois, marcomartins, mihaiiceyro, vladwtz, niq1982, flipkeijzer, michielatyoast, chandrapatel, thrijith, joshuanoyce, FesoVik, tessak22, bhaktirajdev, cleancoded, dhavalkasvala, garrett-eclipse, bibliofille, socalchristina, priyankkpatel, 5hel2l2y, adamsilverstein, JeffPaul, pierlo, SergeyBiryukov.
Fixes #44360.
Built from https://develop.svn.wordpress.org/trunk@45926
git-svn-id: http://core.svn.wordpress.org/trunk@45737 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-01 13:13:59 -04:00
$plugin_data [ 'Description' ] .= sprintf (
2019-09-02 20:41:05 -04:00
/* translators: %s: Plugin author. */
I18N: Improve translator comments.
* Add missing translator comments.
* Fix placement of some translator comments. Translator comments should be on the line directly above the line containing the translation function call for optimal compatibility with various `.pot` file generation tools. The CS auto-fixing, which changed some inconsistent function calls to multi-line function calls, is part of the reason why this was no longer the case for a select group of translator comments.
Includes minor code layout fixes.
Polyglots, rejoice! All WordPress core files now have translator comments for all strings with placeholders!
Props jrf, subrataemfluence, GaryJ, webdados, Dency, swissspidy, alvarogois, marcomartins, mihaiiceyro, vladwtz, niq1982, flipkeijzer, michielatyoast, chandrapatel, thrijith, joshuanoyce, FesoVik, tessak22, bhaktirajdev, cleancoded, dhavalkasvala, garrett-eclipse, bibliofille, socalchristina, priyankkpatel, 5hel2l2y, adamsilverstein, JeffPaul, pierlo, SergeyBiryukov.
Fixes #44360.
Built from https://develop.svn.wordpress.org/trunk@45926
git-svn-id: http://core.svn.wordpress.org/trunk@45737 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-01 13:13:59 -04:00
' <cite>' . __ ( 'By %s.' ) . '</cite>' ,
$plugin_data [ 'Author' ]
);
2017-11-30 18:11:00 -05:00
}
2012-03-20 19:04:59 -04:00
}
2008-10-21 20:08:22 -04:00
return $plugin_data ;
2007-05-25 03:16:21 -04:00
}
2009-02-22 15:05:11 -05:00
/**
* Get a list of a plugin ' s files .
*
* @ since 2.8 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2019-11-05 16:30:03 -05:00
* @ return string [] Array of file names relative to the plugin root .
2009-02-22 15:05:11 -05:00
*/
2017-10-10 01:34:49 -04:00
function get_plugin_files ( $plugin ) {
2009-02-22 15:05:11 -05:00
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin ;
2017-11-30 18:11:00 -05:00
$dir = dirname ( $plugin_file );
2017-10-10 01:34:49 -04:00
$plugin_files = array ( plugin_basename ( $plugin_file ) );
if ( is_dir ( $dir ) && WP_PLUGIN_DIR !== $dir ) {
/**
* Filters the array of excluded directories and files while scanning the folder .
*
* @ since 4.9 . 0
*
2018-03-25 14:10:32 -04:00
* @ param string [] $exclusions Array of excluded directories and files .
2017-10-10 01:34:49 -04:00
*/
$exclusions = ( array ) apply_filters ( 'plugin_files_exclusions' , array ( 'CVS' , 'node_modules' , 'vendor' , 'bower_components' ) );
$list_files = list_files ( $dir , 100 , $exclusions );
$list_files = array_map ( 'plugin_basename' , $list_files );
$plugin_files = array_merge ( $plugin_files , $list_files );
$plugin_files = array_values ( array_unique ( $plugin_files ) );
}
2009-02-22 15:05:11 -05:00
return $plugin_files ;
}
2008-09-16 20:40:10 -04:00
/**
* Check the plugins directory and retrieve all plugin files with plugin data .
*
* WordPress only supports plugin files in the base plugins directory
* ( wp - content / plugins ) and in one directory above the plugins directory
2015-06-24 08:22:27 -04:00
* ( wp - content / plugins / my - plugin ) . The file it looks for has the plugin data
* and must be found in those two locations . It is recommended to keep your
* plugin files in their own directories .
2008-09-16 20:40:10 -04:00
*
* The file with the plugin data is the file that will be included and therefore
* needs to have the main execution for the plugin . This does not mean
* everything must be contained in the file and it is recommended that the file
* be split for maintainability . Keep everything in one file for extreme
* optimization purposes .
*
2010-12-01 14:24:38 -05:00
* @ since 1.5 . 0
2008-09-16 20:40:10 -04:00
*
* @ param string $plugin_folder Optional . Relative path to single plugin folder .
2019-11-05 16:30:03 -05:00
* @ return array [] Array of arrays of plugin data , keyed by plugin file name . See `get_plugin_data()` .
2008-09-16 20:40:10 -04:00
*/
2017-11-30 18:11:00 -05:00
function get_plugins ( $plugin_folder = '' ) {
2008-08-09 01:36:14 -04:00
2019-01-16 19:49:48 -05:00
$cache_plugins = wp_cache_get ( 'plugins' , 'plugins' );
if ( ! $cache_plugins ) {
2008-08-01 00:26:32 -04:00
$cache_plugins = array ();
2017-11-30 18:11:00 -05:00
}
2008-08-09 01:36:14 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $cache_plugins [ $plugin_folder ] ) ) {
2008-06-10 12:57:33 -04:00
return $cache_plugins [ $plugin_folder ];
2017-11-30 18:11:00 -05:00
}
2008-08-09 01:36:14 -04:00
2017-11-30 18:11:00 -05:00
$wp_plugins = array ();
2008-05-27 13:55:24 -04:00
$plugin_root = WP_PLUGIN_DIR ;
2017-11-30 18:11:00 -05:00
if ( ! empty ( $plugin_folder ) ) {
2008-03-21 19:02:00 -04:00
$plugin_root .= $plugin_folder ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2019-10-05 22:23:03 -04:00
// Files in wp-content/plugins directory.
2021-03-11 10:19:08 -05:00
$plugins_dir = @ opendir ( $plugin_root );
2009-04-19 15:36:28 -04:00
$plugin_files = array ();
2020-05-16 14:42:12 -04:00
2007-05-25 03:16:21 -04:00
if ( $plugins_dir ) {
2017-11-30 18:11:00 -05:00
while ( ( $file = readdir ( $plugins_dir ) ) !== false ) {
2020-05-16 14:42:12 -04:00
if ( '.' === substr ( $file , 0 , 1 ) ) {
2007-05-25 03:16:21 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2020-05-16 14:42:12 -04:00
2017-11-30 18:11:00 -05:00
if ( is_dir ( $plugin_root . '/' . $file ) ) {
2021-03-11 10:19:08 -05:00
$plugins_subdir = @ opendir ( $plugin_root . '/' . $file );
2020-05-16 14:42:12 -04:00
2007-05-25 03:16:21 -04:00
if ( $plugins_subdir ) {
2017-11-30 18:11:00 -05:00
while ( ( $subfile = readdir ( $plugins_subdir ) ) !== false ) {
2020-05-16 14:42:12 -04:00
if ( '.' === substr ( $subfile , 0 , 1 ) ) {
2007-05-25 03:16:21 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2020-05-16 14:42:12 -04:00
if ( '.php' === substr ( $subfile , - 4 ) ) {
2007-05-25 03:16:21 -04:00
$plugin_files [] = " $file / $subfile " ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
}
2020-05-16 14:42:12 -04:00
2011-04-07 05:07:56 -04:00
closedir ( $plugins_subdir );
2007-05-25 03:16:21 -04:00
}
} else {
2020-05-16 14:42:12 -04:00
if ( '.php' === substr ( $file , - 4 ) ) {
2007-05-25 03:16:21 -04:00
$plugin_files [] = $file ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
}
}
2020-05-16 14:42:12 -04:00
2011-04-07 05:07:56 -04:00
closedir ( $plugins_dir );
2007-05-25 03:16:21 -04:00
}
2010-05-10 12:06:46 -04:00
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_files ) ) {
2007-05-25 03:16:21 -04:00
return $wp_plugins ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
foreach ( $plugin_files as $plugin_file ) {
2017-11-30 18:11:00 -05:00
if ( ! is_readable ( " $plugin_root / $plugin_file " ) ) {
2007-05-25 03:16:21 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2020-01-28 19:35:08 -05:00
// Do not apply markup/translate as it will be cached.
$plugin_data = get_plugin_data ( " $plugin_root / $plugin_file " , false , false );
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_data [ 'Name' ] ) ) {
2007-05-25 03:16:21 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
$wp_plugins [ plugin_basename ( $plugin_file ) ] = $plugin_data ;
2007-05-25 03:16:21 -04:00
}
2010-11-11 17:50:36 -05:00
uasort ( $wp_plugins , '_sort_uname_callback' );
2007-05-25 03:16:21 -04:00
2008-08-09 01:36:14 -04:00
$cache_plugins [ $plugin_folder ] = $wp_plugins ;
2017-11-30 18:11:00 -05:00
wp_cache_set ( 'plugins' , $cache_plugins , 'plugins' );
2008-06-10 12:57:33 -04:00
2007-05-25 03:16:21 -04:00
return $wp_plugins ;
}
2010-02-19 16:16:14 -05:00
/**
* Check the mu - plugins directory and retrieve all mu - plugin files with any plugin data .
*
* WordPress only includes mu - plugin files in the base mu - plugins directory ( wp - content / mu - plugins ) .
*
* @ since 3.0 . 0
2019-11-05 16:30:03 -05:00
* @ return array [] Array of arrays of mu - plugin data , keyed by plugin file name . See `get_plugin_data()` .
2010-02-19 16:16:14 -05:00
*/
function get_mu_plugins () {
2020-01-28 19:35:08 -05:00
$wp_plugins = array ();
2010-02-19 16:16:14 -05:00
$plugin_files = array ();
2017-11-30 18:11:00 -05:00
if ( ! is_dir ( WPMU_PLUGIN_DIR ) ) {
2010-02-19 16:16:14 -05:00
return $wp_plugins ;
2017-11-30 18:11:00 -05:00
}
2020-01-28 19:35:08 -05:00
// Files in wp-content/mu-plugins directory.
2019-07-01 08:52:01 -04:00
$plugins_dir = @ opendir ( WPMU_PLUGIN_DIR );
if ( $plugins_dir ) {
2010-02-19 16:16:14 -05:00
while ( ( $file = readdir ( $plugins_dir ) ) !== false ) {
2020-05-16 14:42:12 -04:00
if ( '.php' === substr ( $file , - 4 ) ) {
2010-02-19 16:16:14 -05:00
$plugin_files [] = $file ;
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
}
2010-05-10 16:40:15 -04:00
} else {
return $wp_plugins ;
2010-02-19 16:16:14 -05:00
}
2019-07-09 01:45:58 -04:00
closedir ( $plugins_dir );
2010-02-19 16:16:14 -05:00
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_files ) ) {
2010-02-19 16:16:14 -05:00
return $wp_plugins ;
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
foreach ( $plugin_files as $plugin_file ) {
2017-11-30 18:11:00 -05:00
if ( ! is_readable ( WPMU_PLUGIN_DIR . " / $plugin_file " ) ) {
2010-02-19 16:16:14 -05:00
continue ;
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
2020-01-28 19:35:08 -05:00
// Do not apply markup/translate as it will be cached.
$plugin_data = get_plugin_data ( WPMU_PLUGIN_DIR . " / $plugin_file " , false , false );
2010-02-19 16:16:14 -05:00
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_data [ 'Name' ] ) ) {
2010-02-19 16:16:14 -05:00
$plugin_data [ 'Name' ] = $plugin_file ;
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
$wp_plugins [ $plugin_file ] = $plugin_data ;
}
2020-01-28 19:35:08 -05:00
if ( isset ( $wp_plugins [ 'index.php' ] ) && filesize ( WPMU_PLUGIN_DIR . '/index.php' ) <= 30 ) {
// Silence is golden.
2010-02-19 16:16:14 -05:00
unset ( $wp_plugins [ 'index.php' ] );
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
2010-11-11 17:50:36 -05:00
uasort ( $wp_plugins , '_sort_uname_callback' );
2010-02-19 16:16:14 -05:00
return $wp_plugins ;
}
2010-11-11 17:50:36 -05:00
/**
* Callback to sort array by a 'Name' key .
*
* @ since 3.1 . 0
2019-01-14 01:54:49 -05:00
*
2010-11-11 17:50:36 -05:00
* @ access private
2019-01-14 01:54:49 -05:00
*
* @ param array $a array with 'Name' key .
* @ param array $b array with 'Name' key .
* @ return int Return 0 or 1 based on two string comparison .
2010-11-11 17:50:36 -05:00
*/
function _sort_uname_callback ( $a , $b ) {
return strnatcasecmp ( $a [ 'Name' ], $b [ 'Name' ] );
}
2010-02-19 16:16:14 -05:00
/**
* Check the wp - content directory and retrieve all drop - ins with any plugin data .
*
* @ since 3.0 . 0
2019-11-05 16:30:03 -05:00
* @ return array [] Array of arrays of dropin plugin data , keyed by plugin file name . See `get_plugin_data()` .
2010-02-19 16:16:14 -05:00
*/
function get_dropins () {
2017-11-30 18:11:00 -05:00
$dropins = array ();
2010-02-19 16:16:14 -05:00
$plugin_files = array ();
$_dropins = _get_dropins ();
2020-01-28 19:35:08 -05:00
// Files in wp-content directory.
2019-07-01 08:52:01 -04:00
$plugins_dir = @ opendir ( WP_CONTENT_DIR );
if ( $plugins_dir ) {
2010-02-19 16:16:14 -05:00
while ( ( $file = readdir ( $plugins_dir ) ) !== false ) {
2017-11-30 18:11:00 -05:00
if ( isset ( $_dropins [ $file ] ) ) {
2010-02-19 16:16:14 -05:00
$plugin_files [] = $file ;
2017-11-30 18:11:00 -05:00
}
2010-05-10 16:41:14 -04:00
}
2010-05-10 16:40:15 -04:00
} else {
return $dropins ;
2010-02-19 16:16:14 -05:00
}
2019-07-09 01:45:58 -04:00
closedir ( $plugins_dir );
2010-02-19 16:16:14 -05:00
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_files ) ) {
2010-05-10 16:40:15 -04:00
return $dropins ;
2017-11-30 18:11:00 -05:00
}
2010-02-19 16:16:14 -05:00
foreach ( $plugin_files as $plugin_file ) {
2017-11-30 18:11:00 -05:00
if ( ! is_readable ( WP_CONTENT_DIR . " / $plugin_file " ) ) {
2010-05-10 16:41:14 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2020-01-28 19:35:08 -05:00
// Do not apply markup/translate as it will be cached.
$plugin_data = get_plugin_data ( WP_CONTENT_DIR . " / $plugin_file " , false , false );
2017-11-30 18:11:00 -05:00
if ( empty ( $plugin_data [ 'Name' ] ) ) {
2010-05-10 16:41:14 -04:00
$plugin_data [ 'Name' ] = $plugin_file ;
2017-11-30 18:11:00 -05:00
}
2020-01-28 19:35:08 -05:00
2010-05-10 16:41:14 -04:00
$dropins [ $plugin_file ] = $plugin_data ;
2010-02-19 16:16:14 -05:00
}
2010-11-11 17:50:36 -05:00
uksort ( $dropins , 'strnatcasecmp' );
2010-02-19 16:16:14 -05:00
return $dropins ;
}
/**
* Returns drop - ins that WordPress uses .
*
* Includes Multisite drop - ins only when is_multisite ()
*
* @ since 3.0 . 0
2019-11-05 16:30:03 -05:00
* @ return array [] Key is file name . The value is an array , with the first value the
2017-11-30 18:11:00 -05:00
* purpose of the drop - in and the second value the name of the constant that must be
* true for the drop - in to be used , or true if no constant is required .
2010-02-19 16:16:14 -05:00
*/
function _get_dropins () {
$dropins = array (
2020-01-28 19:35:08 -05:00
'advanced-cache.php' => array ( __ ( 'Advanced caching plugin.' ), 'WP_CACHE' ), // WP_CACHE
'db.php' => array ( __ ( 'Custom database class.' ), true ), // Auto on load.
'db-error.php' => array ( __ ( 'Custom database error message.' ), true ), // Auto on error.
'install.php' => array ( __ ( 'Custom installation script.' ), true ), // Auto on installation.
'maintenance.php' => array ( __ ( 'Custom maintenance message.' ), true ), // Auto on maintenance.
'object-cache.php' => array ( __ ( 'External object cache.' ), true ), // Auto on load.
'php-error.php' => array ( __ ( 'Custom PHP error message.' ), true ), // Auto on error.
'fatal-error-handler.php' => array ( __ ( 'Custom PHP fatal error handler.' ), true ), // Auto on error.
2010-02-19 16:16:14 -05:00
);
if ( is_multisite () ) {
2017-11-30 18:11:00 -05:00
$dropins [ 'sunrise.php' ] = array ( __ ( 'Executed before Multisite is loaded.' ), 'SUNRISE' ); // SUNRISE
2020-01-28 19:35:08 -05:00
$dropins [ 'blog-deleted.php' ] = array ( __ ( 'Custom site deleted message.' ), true ); // Auto on deleted blog.
$dropins [ 'blog-inactive.php' ] = array ( __ ( 'Custom site inactive message.' ), true ); // Auto on inactive blog.
$dropins [ 'blog-suspended.php' ] = array ( __ ( 'Custom site suspended message.' ), true ); // Auto on archived or spammed blog.
2010-02-19 16:16:14 -05:00
}
return $dropins ;
}
2008-08-07 19:39:27 -04:00
/**
2018-02-13 11:54:31 -05:00
* Determines whether a plugin is active .
2016-01-25 19:32:27 -05:00
*
* Only plugins installed in the plugins / folder can be active .
*
* Plugins in the mu - plugins / folder can ' t be " activated, " so this function will
* return false for those plugins .
2018-03-18 10:23:33 -04:00
*
2018-02-13 11:54:31 -05:00
* For more information on this and similar theme functions , check out
2018-03-18 10:23:33 -04:00
* the { @ link https :// developer . wordpress . org / themes / basics / conditional - tags /
2018-02-13 11:54:31 -05:00
* Conditional Tags } article in the Theme Developer Handbook .
2018-03-18 10:23:33 -04:00
*
2008-08-07 19:39:27 -04:00
* @ since 2.5 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2008-08-07 19:39:27 -04:00
* @ return bool True , if in the active plugins list . False , not in the list .
*/
2010-01-26 13:39:12 -05:00
function is_plugin_active ( $plugin ) {
2020-04-04 23:02:11 -04:00
return in_array ( $plugin , ( array ) get_option ( 'active_plugins' , array () ), true ) || is_plugin_active_for_network ( $plugin );
2008-03-21 19:02:00 -04:00
}
2010-11-11 17:21:04 -05:00
/**
2018-02-13 11:54:31 -05:00
* Determines whether the plugin is inactive .
2010-11-11 17:21:04 -05:00
*
* Reverse of is_plugin_active () . Used as a callback .
2018-03-18 10:23:33 -04:00
*
2018-02-13 11:54:31 -05:00
* For more information on this and similar theme functions , check out
2018-03-18 10:23:33 -04:00
* the { @ link https :// developer . wordpress . org / themes / basics / conditional - tags /
2018-02-13 11:54:31 -05:00
* Conditional Tags } article in the Theme Developer Handbook .
2018-03-18 10:23:33 -04:00
*
2010-11-11 17:21:04 -05:00
* @ since 3.1 . 0
2020-06-16 17:07:14 -04:00
*
2010-11-11 17:21:04 -05:00
* @ see is_plugin_active ()
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2010-11-11 17:21:04 -05:00
* @ return bool True if inactive . False if active .
*/
function is_plugin_inactive ( $plugin ) {
return ! is_plugin_active ( $plugin );
}
2010-01-29 16:45:32 -05:00
/**
2018-02-13 11:54:31 -05:00
* Determines whether the plugin is active for the entire network .
2010-01-29 16:45:32 -05:00
*
2016-01-25 19:32:27 -05:00
* Only plugins installed in the plugins / folder can be active .
*
* Plugins in the mu - plugins / folder can ' t be " activated, " so this function will
* return false for those plugins .
2018-03-18 10:23:33 -04:00
*
2018-02-13 11:54:31 -05:00
* For more information on this and similar theme functions , check out
2018-03-18 10:23:33 -04:00
* the { @ link https :// developer . wordpress . org / themes / basics / conditional - tags /
2018-02-13 11:54:31 -05:00
* Conditional Tags } article in the Theme Developer Handbook .
2018-03-18 10:23:33 -04:00
*
2010-01-29 16:45:32 -05:00
* @ since 3.0 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2018-02-13 11:54:31 -05:00
* @ return bool True if active for the network , otherwise false .
2010-01-29 16:45:32 -05:00
*/
2010-02-04 13:50:36 -05:00
function is_plugin_active_for_network ( $plugin ) {
2017-11-30 18:11:00 -05:00
if ( ! is_multisite () ) {
2010-01-29 16:45:32 -05:00
return false ;
2017-11-30 18:11:00 -05:00
}
2010-01-29 16:45:32 -05:00
2017-11-30 18:11:00 -05:00
$plugins = get_site_option ( 'active_sitewide_plugins' );
if ( isset ( $plugins [ $plugin ] ) ) {
2010-01-29 16:45:32 -05:00
return true ;
2017-11-30 18:11:00 -05:00
}
2010-01-29 16:45:32 -05:00
return false ;
}
/**
2010-02-05 16:33:53 -05:00
* Checks for " Network: true " in the plugin header to see if this should
* be activated only as a network wide plugin . The plugin would also work
* when Multisite is not enabled .
2010-01-29 16:45:32 -05:00
*
2016-05-13 14:41:31 -04:00
* Checks for " Site Wide Only: true " for backward compatibility .
2010-01-29 16:45:32 -05:00
*
2010-02-05 16:33:53 -05:00
* @ since 3.0 . 0
2010-01-29 16:45:32 -05:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2010-09-07 07:21:11 -04:00
* @ return bool True if plugin is network only , false otherwise .
2010-01-29 16:45:32 -05:00
*/
2010-02-05 16:33:53 -05:00
function is_network_only_plugin ( $plugin ) {
$plugin_data = get_plugin_data ( WP_PLUGIN_DIR . '/' . $plugin );
2017-11-30 18:11:00 -05:00
if ( $plugin_data ) {
2010-02-05 16:33:53 -05:00
return $plugin_data [ 'Network' ];
2017-11-30 18:11:00 -05:00
}
2010-01-29 16:45:32 -05:00
return false ;
}
2008-09-16 20:40:10 -04:00
/**
* Attempts activation of plugin in a " sandbox " and redirects on success .
*
* A plugin that is already activated will not attempt to be activated again .
*
* The way it works is by setting the redirection to the error before trying to
* include the plugin file . If the plugin fails , then the redirection will not
* be overwritten with the success message . Also , the options will not be
* updated and the activation hook will not be called on plugin error .
*
* It should be noted that in no way the below code will actually prevent errors
* within the file . The code should not be used elsewhere to replicate the
* " sandbox " , which uses redirection to work .
* { @ source 13 1 }
*
* If any errors are found or text is outputted , then it will be captured to
* ensure that the success redirection will update the error redirection .
*
2010-12-01 14:24:38 -05:00
* @ since 2.5 . 0
2019-03-21 20:37:50 -04:00
* @ since 5.2 . 0 Test for WordPress version and PHP version compatibility .
2008-09-16 20:40:10 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2015-12-23 02:00:27 -05:00
* @ param string $redirect Optional . URL to redirect to .
* @ param bool $network_wide Optional . Whether to enable the plugin for all sites in the network
* or just the current site . Multisite only . Default false .
* @ param bool $silent Optional . Whether to prevent calling activation hooks . Default false .
2020-01-11 13:32:05 -05:00
* @ return null | WP_Error Null on success , WP_Error on invalid file .
2008-09-16 20:40:10 -04:00
*/
2010-10-27 09:40:14 -04:00
function activate_plugin ( $plugin , $redirect = '' , $network_wide = false , $silent = false ) {
2010-10-27 09:20:53 -04:00
$plugin = plugin_basename ( trim ( $plugin ) );
2008-09-16 20:40:10 -04:00
2017-11-30 18:11:00 -05:00
if ( is_multisite () && ( $network_wide || is_network_only_plugin ( $plugin ) ) ) {
$network_wide = true ;
$current = get_site_option ( 'active_sitewide_plugins' , array () );
2012-06-25 15:32:34 -04:00
$_GET [ 'networkwide' ] = 1 ; // Back compat for plugins looking for this value.
2010-01-29 16:45:32 -05:00
} else {
$current = get_option ( 'active_plugins' , array () );
}
2017-11-30 18:11:00 -05:00
$valid = validate_plugin ( $plugin );
if ( is_wp_error ( $valid ) ) {
2008-09-16 20:40:10 -04:00
return $valid ;
2017-11-30 18:11:00 -05:00
}
2007-10-17 13:14:58 -04:00
2019-03-21 20:37:50 -04:00
$requirements = validate_plugin_requirements ( $plugin );
if ( is_wp_error ( $requirements ) ) {
return $requirements ;
}
2020-08-08 17:04:04 -04:00
if ( $network_wide && ! isset ( $current [ $plugin ] )
|| ! $network_wide && ! in_array ( $plugin , $current , true )
) {
2017-11-30 18:11:00 -05:00
if ( ! empty ( $redirect ) ) {
2020-01-28 19:35:08 -05:00
// We'll override this later if the plugin can be included without fatal error.
wp_redirect ( add_query_arg ( '_error_nonce' , wp_create_nonce ( 'plugin-activation-error_' . $plugin ), $redirect ) );
2017-11-30 18:11:00 -05:00
}
Bootstrap/Load: Ensure `WP_Fatal_Error_Handler` does not conflict with existing mechanisms treating fatal errors.
Prior to this change, resuming or activating a plugin or theme that is still broken would result in a redirect loop if in recovery mode. If outside recovery mode, it would cause the error template to be displayed.
Furthermore this applies to breaking a plugin or theme when editing from the backend.
Props aandrewdixon, azaozz, dhanukanuwan, henrywright, ocean90, ohiosierra, PandelisZ, xkon.
Fixes #46045, #46751.
Built from https://develop.svn.wordpress.org/trunk@45114
git-svn-id: http://core.svn.wordpress.org/trunk@44923 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-04-05 11:20:55 -04:00
2008-09-16 20:40:10 -04:00
ob_start ();
2020-07-05 16:32:03 -04:00
2021-04-24 14:04:04 -04:00
// Load the plugin to test whether it throws any errors.
plugin_sandbox_scrape ( $plugin );
2010-10-27 09:40:14 -04:00
if ( ! $silent ) {
2013-09-18 03:38:12 -04:00
/**
2014-03-26 22:02:14 -04:00
* Fires before a plugin is activated .
*
* If a plugin is silently activated ( such as during an update ),
* this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.9 . 0
2013-09-18 03:38:12 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2013-09-18 15:36:09 -04:00
* @ param bool $network_wide Whether to enable the plugin for all sites in the network
2020-06-20 08:14:09 -04:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2010-10-27 09:40:14 -04:00
do_action ( 'activate_plugin' , $plugin , $network_wide );
2013-09-18 03:38:12 -04:00
/**
2014-10-20 17:35:18 -04:00
* Fires as a specific plugin is being activated .
2014-03-26 22:02:14 -04:00
*
2016-05-02 00:00:28 -04:00
* This hook is the " activation " hook used internally by register_activation_hook () .
* The dynamic portion of the hook name , `$plugin` , refers to the plugin basename .
2013-10-24 22:29:52 -04:00
*
2016-05-02 00:00:28 -04:00
* If a plugin is silently activated ( such as during an update ), this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.0 . 0
2013-09-18 03:38:12 -04:00
*
2013-09-18 15:36:09 -04:00
* @ param bool $network_wide Whether to enable the plugin for all sites in the network
2020-06-20 08:14:09 -04:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2016-08-22 14:25:31 -04:00
do_action ( " activate_ { $plugin } " , $network_wide );
2010-10-27 09:40:14 -04:00
}
2010-01-29 16:45:32 -05:00
if ( $network_wide ) {
2017-11-30 18:11:00 -05:00
$current = get_site_option ( 'active_sitewide_plugins' , array () );
$current [ $plugin ] = time ();
2015-10-07 13:11:25 -04:00
update_site_option ( 'active_sitewide_plugins' , $current );
2010-01-29 16:45:32 -05:00
} else {
2017-11-30 18:11:00 -05:00
$current = get_option ( 'active_plugins' , array () );
2010-01-29 16:45:32 -05:00
$current [] = $plugin ;
2017-11-30 18:11:00 -05:00
sort ( $current );
update_option ( 'active_plugins' , $current );
2010-01-29 16:45:32 -05:00
}
2010-10-27 09:40:14 -04:00
if ( ! $silent ) {
2013-09-18 03:38:12 -04:00
/**
2014-03-26 22:02:14 -04:00
* Fires after a plugin has been activated .
*
* If a plugin is silently activated ( such as during an update ),
* this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.9 . 0
2013-09-18 03:38:12 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2013-09-18 15:36:09 -04:00
* @ param bool $network_wide Whether to enable the plugin for all sites in the network
2020-06-20 08:14:09 -04:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2010-10-27 09:40:14 -04:00
do_action ( 'activated_plugin' , $plugin , $network_wide );
}
2010-05-27 20:18:00 -04:00
if ( ob_get_length () > 0 ) {
$output = ob_get_clean ();
2017-11-30 18:11:00 -05:00
return new WP_Error ( 'unexpected_output' , __ ( 'The plugin generated unexpected output.' ), $output );
2010-05-27 20:18:00 -04:00
}
2021-04-24 14:04:04 -04:00
2008-09-16 20:40:10 -04:00
ob_end_clean ();
}
return null ;
2007-10-17 13:14:58 -04:00
}
2008-09-16 20:40:10 -04:00
/**
* Deactivate a single plugin or multiple plugins .
*
* The deactivation hook is disabled by the plugin upgrader by using the $silent
* parameter .
*
2010-12-01 14:24:38 -05:00
* @ since 2.5 . 0
2008-09-16 20:40:10 -04:00
*
2019-11-10 18:05:03 -05:00
* @ param string | string [] $plugins Single plugin or list of plugins to deactivate .
* @ param bool $silent Prevent calling deactivation hooks . Default false .
* @ param bool | null $network_wide Whether to deactivate the plugin for all sites in the network .
* A value of null will deactivate plugins for both the network
* and the current site . Multisite only . Default null .
2008-09-16 20:40:10 -04:00
*/
2012-04-18 23:41:29 -04:00
function deactivate_plugins ( $plugins , $silent = false , $network_wide = null ) {
2017-11-30 18:11:00 -05:00
if ( is_multisite () ) {
2015-10-07 13:11:25 -04:00
$network_current = get_site_option ( 'active_sitewide_plugins' , array () );
2017-11-30 18:11:00 -05:00
}
2019-07-01 08:52:01 -04:00
$current = get_option ( 'active_plugins' , array () );
$do_blog = false ;
$do_network = false ;
2007-10-17 13:14:58 -04:00
2010-01-26 13:39:12 -05:00
foreach ( ( array ) $plugins as $plugin ) {
2010-10-27 09:20:53 -04:00
$plugin = plugin_basename ( trim ( $plugin ) );
2017-11-30 18:11:00 -05:00
if ( ! is_plugin_active ( $plugin ) ) {
2008-03-20 13:24:44 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2010-10-27 09:20:53 -04:00
2020-08-08 17:04:04 -04:00
$network_deactivating = ( false !== $network_wide ) && is_plugin_active_for_network ( $plugin );
2010-10-27 09:20:53 -04:00
2013-12-01 18:13:09 -05:00
if ( ! $silent ) {
2013-09-18 03:38:12 -04:00
/**
2014-03-26 22:02:14 -04:00
* Fires before a plugin is deactivated .
*
* If a plugin is silently deactivated ( such as during an update ),
* this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.9 . 0
2013-09-18 03:38:12 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2013-10-24 22:29:52 -04:00
* @ param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
2019-11-10 18:05:03 -05:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2012-04-18 23:41:29 -04:00
do_action ( 'deactivate_plugin' , $plugin , $network_deactivating );
2013-12-01 18:13:09 -05:00
}
2009-09-24 13:19:13 -04:00
2012-04-18 23:41:29 -04:00
if ( false !== $network_wide ) {
2012-04-20 20:45:53 -04:00
if ( is_plugin_active_for_network ( $plugin ) ) {
$do_network = true ;
unset ( $network_current [ $plugin ] );
} elseif ( $network_wide ) {
2012-04-18 23:41:29 -04:00
continue ;
2012-04-20 20:45:53 -04:00
}
2012-04-18 23:41:29 -04:00
}
if ( true !== $network_wide ) {
2020-04-04 23:02:11 -04:00
$key = array_search ( $plugin , $current , true );
2010-02-05 13:10:30 -05:00
if ( false !== $key ) {
$do_blog = true ;
2012-09-10 22:12:34 -04:00
unset ( $current [ $key ] );
2010-02-05 13:10:30 -05:00
}
2010-01-29 16:45:32 -05:00
}
2009-09-24 13:19:13 -04:00
2019-04-05 11:33:52 -04:00
if ( $do_blog && wp_is_recovery_mode () ) {
list ( $extension ) = explode ( '/' , $plugin );
wp_paused_plugins () -> delete ( $extension );
}
2009-09-10 10:43:45 -04:00
if ( ! $silent ) {
2013-09-18 03:38:12 -04:00
/**
2014-03-26 22:02:14 -04:00
* Fires as a specific plugin is being deactivated .
2014-03-10 17:34:17 -04:00
*
2016-05-02 00:00:28 -04:00
* This hook is the " deactivation " hook used internally by register_deactivation_hook () .
* The dynamic portion of the hook name , `$plugin` , refers to the plugin basename .
2013-10-24 22:29:52 -04:00
*
2016-05-02 00:00:28 -04:00
* If a plugin is silently deactivated ( such as during an update ), this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.0 . 0
2013-09-18 03:38:12 -04:00
*
2013-10-24 22:29:52 -04:00
* @ param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
2019-11-10 18:05:03 -05:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2016-08-22 14:25:31 -04:00
do_action ( " deactivate_ { $plugin } " , $network_deactivating );
2013-09-18 03:38:12 -04:00
/**
2014-03-26 22:02:14 -04:00
* Fires after a plugin is deactivated .
2014-03-10 17:34:17 -04:00
*
2014-03-26 22:02:14 -04:00
* If a plugin is silently deactivated ( such as during an update ),
* this hook does not fire .
2013-10-24 22:29:52 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.9 . 0
2013-09-18 03:38:12 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2019-11-10 18:05:03 -05:00
* @ param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
2014-03-10 17:34:17 -04:00
* or just the current site . Multisite only . Default false .
2013-09-18 03:38:12 -04:00
*/
2012-04-18 23:41:29 -04:00
do_action ( 'deactivated_plugin' , $plugin , $network_deactivating );
2009-09-10 10:43:45 -04:00
}
2007-10-17 13:14:58 -04:00
}
2017-11-30 18:11:00 -05:00
if ( $do_blog ) {
update_option ( 'active_plugins' , $current );
}
if ( $do_network ) {
2015-10-07 13:11:25 -04:00
update_site_option ( 'active_sitewide_plugins' , $network_current );
2017-11-30 18:11:00 -05:00
}
2007-10-17 13:14:58 -04:00
}
2008-09-16 20:40:10 -04:00
/**
* Activate multiple plugins .
*
* When WP_Error is returned , it does not mean that one of the plugins had
2019-11-10 18:05:03 -05:00
* errors . It means that one or more of the plugin file paths were invalid .
2008-09-16 20:40:10 -04:00
*
* The execution will be halted as soon as one of the plugins has an error .
*
2010-12-01 14:24:38 -05:00
* @ since 2.6 . 0
2008-09-16 20:40:10 -04:00
*
2019-11-10 18:05:03 -05:00
* @ param string | string [] $plugins Single plugin or list of plugins to activate .
* @ param string $redirect Redirect to page after successful activation .
* @ param bool $network_wide Whether to enable the plugin for all sites in the network .
* Default false .
2020-07-22 20:52:05 -04:00
* @ param bool $silent Prevent calling activation hooks . Default false .
2008-09-16 20:40:10 -04:00
* @ return bool | WP_Error True when finished or WP_Error if there were errors during a plugin activation .
*/
2010-10-27 09:40:14 -04:00
function activate_plugins ( $plugins , $redirect = '' , $network_wide = false , $silent = false ) {
2017-11-30 18:11:00 -05:00
if ( ! is_array ( $plugins ) ) {
$plugins = array ( $plugins );
}
2008-01-09 04:37:27 -05:00
2008-06-04 14:09:31 -04:00
$errors = array ();
2010-10-27 09:40:14 -04:00
foreach ( $plugins as $plugin ) {
2017-11-30 18:11:00 -05:00
if ( ! empty ( $redirect ) ) {
$redirect = add_query_arg ( 'plugin' , $plugin , $redirect );
}
$result = activate_plugin ( $plugin , $redirect , $network_wide , $silent );
if ( is_wp_error ( $result ) ) {
$errors [ $plugin ] = $result ;
}
2008-06-04 14:09:31 -04:00
}
2008-01-09 04:37:27 -05:00
2017-11-30 18:11:00 -05:00
if ( ! empty ( $errors ) ) {
return new WP_Error ( 'plugins_invalid' , __ ( 'One of the plugins is invalid.' ), $errors );
}
2008-01-09 04:37:27 -05:00
2008-06-04 14:09:31 -04:00
return true ;
}
2008-01-09 04:37:27 -05:00
2008-09-16 20:40:10 -04:00
/**
2014-05-05 06:24:15 -04:00
* Remove directory and files of a plugin for a list of plugins .
2008-09-16 20:40:10 -04:00
*
2010-12-01 14:24:38 -05:00
* @ since 2.6 . 0
2008-09-16 20:40:10 -04:00
*
2018-03-04 16:58:30 -05:00
* @ global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass .
2015-05-28 17:41:30 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string [] $plugins List of plugin paths to delete , relative to the plugins directory .
* @ param string $deprecated Not used .
* @ return bool | null | WP_Error True on success , false if `$plugins` is empty , `WP_Error` on failure .
* `null` if filesystem credentials are required to proceed .
2008-09-16 20:40:10 -04:00
*/
2014-05-05 06:24:15 -04:00
function delete_plugins ( $plugins , $deprecated = '' ) {
2008-06-04 14:09:31 -04:00
global $wp_filesystem ;
2017-11-30 18:11:00 -05:00
if ( empty ( $plugins ) ) {
2008-06-04 14:09:31 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2008-06-04 14:09:31 -04:00
$checked = array ();
2017-11-30 18:11:00 -05:00
foreach ( $plugins as $plugin ) {
2008-06-04 14:09:31 -04:00
$checked [] = 'checked[]=' . $plugin ;
2017-11-30 18:11:00 -05:00
}
2008-06-04 14:09:31 -04:00
2017-11-30 18:11:00 -05:00
$url = wp_nonce_url ( 'plugins.php?action=delete-selected&verify-delete=1&' . implode ( '&' , $checked ), 'bulk-plugins' );
2015-06-26 21:12:24 -04:00
2016-07-27 13:11:56 -04:00
ob_start ();
$credentials = request_filesystem_credentials ( $url );
2017-11-30 18:11:00 -05:00
$data = ob_get_clean ();
2016-07-27 13:11:56 -04:00
if ( false === $credentials ) {
2017-11-30 18:11:00 -05:00
if ( ! empty ( $data ) ) {
2020-02-06 01:33:11 -05:00
require_once ABSPATH . 'wp-admin/admin-header.php' ;
2008-06-04 14:09:31 -04:00
echo $data ;
2020-02-06 01:33:11 -05:00
require_once ABSPATH . 'wp-admin/admin-footer.php' ;
2008-06-04 14:09:31 -04:00
exit ;
}
2008-01-09 04:37:27 -05:00
return ;
2008-06-04 14:09:31 -04:00
}
2008-01-09 04:37:27 -05:00
2016-07-27 13:11:56 -04:00
if ( ! WP_Filesystem ( $credentials ) ) {
ob_start ();
2020-01-28 19:35:08 -05:00
// Failed to connect. Error and request again.
request_filesystem_credentials ( $url , '' , true );
2015-06-26 21:12:24 -04:00
$data = ob_get_clean ();
2017-11-30 18:11:00 -05:00
if ( ! empty ( $data ) ) {
2020-02-06 01:33:11 -05:00
require_once ABSPATH . 'wp-admin/admin-header.php' ;
2008-06-04 14:09:31 -04:00
echo $data ;
2020-02-06 01:33:11 -05:00
require_once ABSPATH . 'wp-admin/admin-footer.php' ;
2008-06-04 14:09:31 -04:00
exit ;
}
return ;
}
2008-01-09 04:37:27 -05:00
2017-11-30 18:11:00 -05:00
if ( ! is_object ( $wp_filesystem ) ) {
return new WP_Error ( 'fs_unavailable' , __ ( 'Could not access filesystem.' ) );
}
2008-01-09 04:37:27 -05:00
2018-02-26 21:31:31 -05:00
if ( is_wp_error ( $wp_filesystem -> errors ) && $wp_filesystem -> errors -> has_errors () ) {
2017-11-30 18:11:00 -05:00
return new WP_Error ( 'fs_error' , __ ( 'Filesystem error.' ), $wp_filesystem -> errors );
}
2008-06-04 14:09:31 -04:00
2014-10-08 15:05:20 -04:00
// Get the base plugin folder.
2008-06-04 14:09:31 -04:00
$plugins_dir = $wp_filesystem -> wp_plugins_dir ();
2014-10-08 15:05:20 -04:00
if ( empty ( $plugins_dir ) ) {
2016-07-17 09:29:29 -04:00
return new WP_Error ( 'fs_no_plugins_dir' , __ ( 'Unable to locate WordPress plugin directory.' ) );
2014-10-08 15:05:20 -04:00
}
2008-08-09 01:36:14 -04:00
2008-06-04 14:09:31 -04:00
$plugins_dir = trailingslashit ( $plugins_dir );
2008-01-09 04:37:27 -05:00
2014-10-08 15:05:20 -04:00
$plugin_translations = wp_get_installed_translations ( 'plugins' );
2008-06-04 14:09:31 -04:00
$errors = array ();
2015-08-25 16:28:22 -04:00
foreach ( $plugins as $plugin_file ) {
2014-10-08 15:05:20 -04:00
// Run Uninstall hook.
if ( is_uninstallable_plugin ( $plugin_file ) ) {
2017-11-30 18:11:00 -05:00
uninstall_plugin ( $plugin_file );
2014-10-08 15:05:20 -04:00
}
2008-08-07 19:39:27 -04:00
2015-11-18 12:58:26 -05:00
/**
* Fires immediately before a plugin deletion attempt .
*
* @ since 4.4 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin_file Path to the plugin file relative to the plugins directory .
2015-11-18 12:58:26 -05:00
*/
do_action ( 'delete_plugin' , $plugin_file );
2014-10-08 15:05:20 -04:00
$this_plugin_dir = trailingslashit ( dirname ( $plugins_dir . $plugin_file ) );
2015-11-18 12:58:26 -05:00
2008-06-04 14:09:31 -04:00
// If plugin is in its own directory, recursively delete the directory.
2020-01-28 19:35:08 -05:00
// Base check on if plugin includes directory separator AND that it's not the root plugin folder.
2020-08-08 17:04:04 -04:00
if ( strpos ( $plugin_file , '/' ) && $this_plugin_dir !== $plugins_dir ) {
2014-10-08 15:05:20 -04:00
$deleted = $wp_filesystem -> delete ( $this_plugin_dir , true );
} else {
$deleted = $wp_filesystem -> delete ( $plugins_dir . $plugin_file );
}
2008-08-09 01:36:14 -04:00
2015-10-12 20:57:25 -04:00
/**
* Fires immediately after a plugin deletion attempt .
*
* @ since 4.4 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin_file Path to the plugin file relative to the plugins directory .
2015-10-12 20:57:25 -04:00
* @ param bool $deleted Whether the plugin deletion was successful .
*/
2015-11-18 12:58:26 -05:00
do_action ( 'deleted_plugin' , $plugin_file , $deleted );
2015-10-12 20:57:25 -04:00
2014-10-08 15:05:20 -04:00
if ( ! $deleted ) {
2008-06-04 14:09:31 -04:00
$errors [] = $plugin_file ;
2014-10-08 15:05:20 -04:00
continue ;
}
$plugin_slug = dirname ( $plugin_file );
2021-06-02 11:12:58 -04:00
if ( 'hello.php' === $plugin_file ) {
$plugin_slug = 'hello-dolly' ;
}
// Remove language files, silently.
2014-10-08 15:05:20 -04:00
if ( '.' !== $plugin_slug && ! empty ( $plugin_translations [ $plugin_slug ] ) ) {
$translations = $plugin_translations [ $plugin_slug ];
foreach ( $translations as $translation => $data ) {
$wp_filesystem -> delete ( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '.po' );
$wp_filesystem -> delete ( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '.mo' );
2019-01-21 15:41:50 -05:00
$json_translation_files = glob ( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '-*.json' );
if ( $json_translation_files ) {
array_map ( array ( $wp_filesystem , 'delete' ), $json_translation_files );
}
2014-10-08 15:05:20 -04:00
}
}
2008-06-04 14:09:31 -04:00
}
2008-08-09 01:36:14 -04:00
2013-11-18 23:08:09 -05:00
// Remove deleted plugins from the plugin updates list.
2019-07-01 08:52:01 -04:00
$current = get_site_transient ( 'update_plugins' );
if ( $current ) {
2013-11-18 23:08:09 -05:00
// Don't remove the plugins that weren't deleted.
$deleted = array_diff ( $plugins , $errors );
2013-12-11 14:49:11 -05:00
2013-11-18 23:08:09 -05:00
foreach ( $deleted as $plugin_file ) {
unset ( $current -> response [ $plugin_file ] );
}
set_site_transient ( 'update_plugins' , $current );
2009-05-05 16:48:46 -04:00
}
2008-12-04 13:39:11 -05:00
2017-10-03 13:13:46 -04:00
if ( ! empty ( $errors ) ) {
if ( 1 === count ( $errors ) ) {
2019-09-02 20:41:05 -04:00
/* translators: %s: Plugin filename. */
2017-10-03 13:13:46 -04:00
$message = __ ( 'Could not fully remove the plugin %s.' );
} else {
2019-09-02 20:41:05 -04:00
/* translators: %s: Comma-separated list of plugin filenames. */
2017-10-03 13:13:46 -04:00
$message = __ ( 'Could not fully remove the plugins %s.' );
}
return new WP_Error ( 'could_not_remove_plugin' , sprintf ( $message , implode ( ', ' , $errors ) ) );
}
2013-11-18 23:08:09 -05:00
2008-01-09 04:37:27 -05:00
return true ;
}
2010-01-26 13:39:12 -05:00
/**
2010-02-02 16:41:17 -05:00
* Validate active plugins
2010-01-26 17:49:05 -05:00
*
2010-02-02 16:41:17 -05:00
* Validate all active plugins , deactivates invalid and
* returns an array of deactivated ones .
2010-01-26 17:49:05 -05:00
*
2010-12-01 14:24:38 -05:00
* @ since 2.5 . 0
2019-11-05 16:30:03 -05:00
* @ return WP_Error [] Array of plugin errors keyed by plugin file name .
2010-01-26 13:39:12 -05:00
*/
2008-01-09 04:37:27 -05:00
function validate_active_plugins () {
2010-02-04 13:50:36 -05:00
$plugins = get_option ( 'active_plugins' , array () );
2014-07-17 05:14:16 -04:00
// Validate vartype: array.
2010-02-02 16:41:17 -05:00
if ( ! is_array ( $plugins ) ) {
update_option ( 'active_plugins' , array () );
$plugins = array ();
2008-01-09 04:37:27 -05:00
}
2013-12-03 16:12:10 -05:00
if ( is_multisite () && current_user_can ( 'manage_network_plugins' ) ) {
2015-10-07 13:11:25 -04:00
$network_plugins = ( array ) get_site_option ( 'active_sitewide_plugins' , array () );
2017-11-30 18:11:00 -05:00
$plugins = array_merge ( $plugins , array_keys ( $network_plugins ) );
2010-02-02 16:41:17 -05:00
}
2017-11-30 18:11:00 -05:00
if ( empty ( $plugins ) ) {
2014-12-30 14:31:22 -05:00
return array ();
2017-11-30 18:11:00 -05:00
}
2010-02-02 16:41:17 -05:00
2008-08-09 01:36:14 -04:00
$invalid = array ();
2008-07-29 19:10:12 -04:00
2014-07-17 05:14:16 -04:00
// Invalid plugins get deactivated.
2010-01-26 13:39:12 -05:00
foreach ( $plugins as $plugin ) {
$result = validate_plugin ( $plugin );
2008-06-16 14:35:48 -04:00
if ( is_wp_error ( $result ) ) {
2017-11-30 18:11:00 -05:00
$invalid [ $plugin ] = $result ;
2010-01-26 13:39:12 -05:00
deactivate_plugins ( $plugin , true );
2008-01-09 04:37:27 -05:00
}
}
2008-07-29 19:10:12 -04:00
return $invalid ;
2008-01-09 04:37:27 -05:00
}
2008-09-16 20:40:10 -04:00
/**
* Validate the plugin path .
*
2017-01-12 01:15:42 -05:00
* Checks that the main plugin file exists and is a valid plugin . See validate_file () .
2008-09-16 20:40:10 -04:00
*
2010-12-01 14:24:38 -05:00
* @ since 2.5 . 0
2008-09-16 20:40:10 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2019-11-10 21:43:03 -05:00
* @ return int | WP_Error 0 on success , WP_Error on failure .
2008-09-16 20:40:10 -04:00
*/
2017-11-30 18:11:00 -05:00
function validate_plugin ( $plugin ) {
if ( validate_file ( $plugin ) ) {
return new WP_Error ( 'plugin_invalid' , __ ( 'Invalid plugin path.' ) );
}
if ( ! file_exists ( WP_PLUGIN_DIR . '/' . $plugin ) ) {
return new WP_Error ( 'plugin_not_found' , __ ( 'Plugin file does not exist.' ) );
}
2008-01-09 04:37:27 -05:00
2009-02-19 13:39:04 -05:00
$installed_plugins = get_plugins ();
2017-11-30 18:11:00 -05:00
if ( ! isset ( $installed_plugins [ $plugin ] ) ) {
return new WP_Error ( 'no_plugin_header' , __ ( 'The plugin does not have a valid header.' ) );
}
2008-01-09 04:37:27 -05:00
return 0 ;
2007-10-17 13:14:58 -04:00
}
2019-03-21 20:37:50 -04:00
/**
2020-04-13 11:31:05 -04:00
* Validates the plugin requirements for WordPress version and PHP version .
*
* Uses the information from `Requires at least` and `Requires PHP` headers
* defined in the plugin ' s main PHP file .
*
2019-03-21 20:37:50 -04:00
* @ since 5.2 . 0
2020-04-13 11:31:05 -04:00
* @ since 5.3 . 0 Added support for reading the headers from the plugin ' s
* main PHP file , with `readme.txt` as a fallback .
Upgrade/Install: Remove parsing of `readme.txt` files for plugin or theme requirements.
This affects:
* `validate_plugin_requirements()`
* `validate_theme_requirements()`
Historically, the `Requires PHP` header was introduced in #meta2952 for the Plugin Directory first, so at the time it made sense to have it defined in the same place as `Requires at least`, which only existed in `readme.txt`.
Since parsing of PHP and WordPress requirements was later added to WordPress core, the core should retrieve all the necessary data from the main plugin or theme file and not from `readme.txt`, which only contains the data meant for the Plugin or Theme Directory.
The recommended place for `Requires PHP` and `Requires at least` headers is as follows:
* The plugin's main PHP file
* The theme's `style.css` file
The place for the `Tested up to` header remains in `readme.txt` for the time being, as it's not used by WordPress core.
Follow-up to [44978], [45546], [47573], [47574], [meta5841], [meta9050].
Props afragen, Otto42, joyously, williampatton, audrasjb.
Fixes #48520. See #48515, #meta2952, #meta4514, #meta4621.
Built from https://develop.svn.wordpress.org/trunk@51092
git-svn-id: http://core.svn.wordpress.org/trunk@50701 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2021-06-08 06:13:00 -04:00
* @ since 5.8 . 0 Removed support for using `readme.txt` as a fallback .
2019-03-21 20:37:50 -04:00
*
* @ param string $plugin Path to the plugin file relative to the plugins directory .
* @ return true | WP_Error True if requirements are met , WP_Error on failure .
*/
function validate_plugin_requirements ( $plugin ) {
2020-04-13 11:31:05 -04:00
$plugin_headers = get_plugin_data ( WP_PLUGIN_DIR . '/' . $plugin );
$requirements = array (
'requires' => ! empty ( $plugin_headers [ 'RequiresWP' ] ) ? $plugin_headers [ 'RequiresWP' ] : '' ,
'requires_php' => ! empty ( $plugin_headers [ 'RequiresPHP' ] ) ? $plugin_headers [ 'RequiresPHP' ] : '' ,
2019-06-17 23:24:52 -04:00
);
2019-03-21 20:37:50 -04:00
2020-04-13 11:31:05 -04:00
$compatible_wp = is_wp_version_compatible ( $requirements [ 'requires' ] );
$compatible_php = is_php_version_compatible ( $requirements [ 'requires_php' ] );
2019-03-21 20:37:50 -04:00
2020-06-25 20:27:09 -04:00
$php_update_message = '</p><p>' . sprintf (
2020-08-08 17:04:04 -04:00
/* translators: %s: URL to Update PHP page. */
2020-06-25 20:27:09 -04:00
__ ( '<a href="%s">Learn more about updating PHP</a>.' ),
esc_url ( wp_get_update_php_url () )
);
$annotation = wp_get_update_php_annotation ();
if ( $annotation ) {
$php_update_message .= '</p><p><em>' . $annotation . '</em>' ;
}
2020-04-13 11:31:05 -04:00
if ( ! $compatible_wp && ! $compatible_php ) {
2019-03-21 21:00:52 -04:00
return new WP_Error (
'plugin_wp_php_incompatible' ,
2020-06-25 20:27:09 -04:00
'<p>' . sprintf (
/* translators: 1: Current WordPress version, 2: Current PHP version, 3: Plugin name, 4: Required WordPress version, 5: Required PHP version. */
_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' ),
get_bloginfo ( 'version' ),
phpversion (),
$plugin_headers [ 'Name' ],
$requirements [ 'requires' ],
$requirements [ 'requires_php' ]
) . $php_update_message . '</p>'
2019-03-21 20:37:50 -04:00
);
2020-04-13 11:31:05 -04:00
} elseif ( ! $compatible_php ) {
2019-03-21 21:00:52 -04:00
return new WP_Error (
'plugin_php_incompatible' ,
2020-06-25 20:27:09 -04:00
'<p>' . sprintf (
/* translators: 1: Current PHP version, 2: Plugin name, 3: Required PHP version. */
_x ( '<strong>Error:</strong> Current PHP version (%1$s) does not meet minimum requirements for %2$s. The plugin requires PHP %3$s.' , 'plugin' ),
phpversion (),
$plugin_headers [ 'Name' ],
$requirements [ 'requires_php' ]
) . $php_update_message . '</p>'
2019-03-21 20:37:50 -04:00
);
2020-04-13 11:31:05 -04:00
} elseif ( ! $compatible_wp ) {
2019-03-21 21:00:52 -04:00
return new WP_Error (
'plugin_wp_incompatible' ,
2020-06-25 20:27:09 -04:00
'<p>' . sprintf (
/* translators: 1: Current WordPress version, 2: Plugin name, 3: Required WordPress version. */
_x ( '<strong>Error:</strong> Current WordPress version (%1$s) does not meet minimum requirements for %2$s. The plugin requires WordPress %3$s.' , 'plugin' ),
get_bloginfo ( 'version' ),
$plugin_headers [ 'Name' ],
$requirements [ 'requires' ]
) . '</p>'
2019-03-21 20:37:50 -04:00
);
}
return true ;
}
2008-08-07 19:39:27 -04:00
/**
* Whether the plugin can be uninstalled .
*
2008-09-16 20:40:10 -04:00
* @ since 2.7 . 0
2008-08-07 19:39:27 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2008-08-07 19:39:27 -04:00
* @ return bool Whether plugin can be uninstalled .
*/
2017-11-30 18:11:00 -05:00
function is_uninstallable_plugin ( $plugin ) {
$file = plugin_basename ( $plugin );
2008-08-07 19:39:27 -04:00
2017-11-30 18:11:00 -05:00
$uninstallable_plugins = ( array ) get_option ( 'uninstall_plugins' );
if ( isset ( $uninstallable_plugins [ $file ] ) || file_exists ( WP_PLUGIN_DIR . '/' . dirname ( $file ) . '/uninstall.php' ) ) {
2008-08-07 19:39:27 -04:00
return true ;
2017-11-30 18:11:00 -05:00
}
2008-08-07 19:39:27 -04:00
return false ;
}
/**
* Uninstall a single plugin .
*
* Calls the uninstall hook , if it is available .
*
2008-09-16 20:40:10 -04:00
* @ since 2.7 . 0
2008-08-08 00:15:03 -04:00
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2021-01-05 12:16:11 -05:00
* @ return true | void True if a plugin ' s uninstall . php file has been found and included .
* Void otherwise .
2008-08-07 19:39:27 -04:00
*/
2017-11-30 18:11:00 -05:00
function uninstall_plugin ( $plugin ) {
$file = plugin_basename ( $plugin );
2008-08-07 19:39:27 -04:00
2017-11-30 18:11:00 -05:00
$uninstallable_plugins = ( array ) get_option ( 'uninstall_plugins' );
2015-12-30 17:38:26 -05:00
/**
2016-03-03 03:58:26 -05:00
* Fires in uninstall_plugin () immediately before the plugin is uninstalled .
2015-12-30 17:38:26 -05:00
*
* @ since 4.5 . 0
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2015-12-30 17:38:26 -05:00
* @ param array $uninstallable_plugins Uninstallable plugins .
*/
do_action ( 'pre_uninstall_plugin' , $plugin , $uninstallable_plugins );
2017-11-30 18:11:00 -05:00
if ( file_exists ( WP_PLUGIN_DIR . '/' . dirname ( $file ) . '/uninstall.php' ) ) {
if ( isset ( $uninstallable_plugins [ $file ] ) ) {
unset ( $uninstallable_plugins [ $file ] );
update_option ( 'uninstall_plugins' , $uninstallable_plugins );
2008-08-07 19:39:27 -04:00
}
2017-11-30 18:11:00 -05:00
unset ( $uninstallable_plugins );
2008-08-07 19:39:27 -04:00
2017-11-30 18:11:00 -05:00
define ( 'WP_UNINSTALL_PLUGIN' , $file );
2020-07-05 16:32:03 -04:00
2016-04-30 11:04:27 -04:00
wp_register_plugin_realpath ( WP_PLUGIN_DIR . '/' . $file );
2020-07-05 16:32:03 -04:00
include_once WP_PLUGIN_DIR . '/' . dirname ( $file ) . '/uninstall.php' ;
2008-08-07 19:39:27 -04:00
return true ;
}
2017-11-30 18:11:00 -05:00
if ( isset ( $uninstallable_plugins [ $file ] ) ) {
$callable = $uninstallable_plugins [ $file ];
unset ( $uninstallable_plugins [ $file ] );
update_option ( 'uninstall_plugins' , $uninstallable_plugins );
unset ( $uninstallable_plugins );
2008-08-07 19:39:27 -04:00
2014-02-10 18:00:15 -05:00
wp_register_plugin_realpath ( WP_PLUGIN_DIR . '/' . $file );
2020-07-05 16:32:03 -04:00
include_once WP_PLUGIN_DIR . '/' . $file ;
2008-08-07 19:39:27 -04:00
2016-12-13 23:18:42 -05:00
add_action ( " uninstall_ { $file } " , $callable );
2013-09-18 03:38:12 -04:00
/**
* Fires in uninstall_plugin () once the plugin has been uninstalled .
2013-10-24 22:29:52 -04:00
*
2013-09-18 03:38:12 -04:00
* The action concatenates the 'uninstall_' prefix with the basename of the
2016-05-02 00:00:28 -04:00
* plugin passed to uninstall_plugin () to create a dynamically - named action .
2013-09-18 03:38:12 -04:00
*
2013-09-18 07:58:10 -04:00
* @ since 2.7 . 0
2013-09-18 03:38:12 -04:00
*/
2016-12-13 23:18:42 -05:00
do_action ( " uninstall_ { $file } " );
2008-08-07 19:39:27 -04:00
}
}
2007-05-25 03:16:21 -04:00
//
2020-01-28 19:35:08 -05:00
// Menu.
2007-05-25 03:16:21 -04:00
//
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add a top - level menu page .
2010-02-02 16:41:17 -05:00
*
2010-01-31 12:36:00 -05:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
2010-02-02 16:41:17 -05:00
*
2010-01-31 12:36:00 -05:00
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 1.5 . 0
*
2015-05-28 22:06:31 -04:00
* @ global array $menu
* @ global array $admin_page_hooks
* @ global array $_registered_pages
* @ global array $_parent_pages
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
2017-06-30 00:18:43 -04:00
* @ param string $menu_slug The slug name to refer to this menu by . Should be unique for this menu page and only
* include lowercase alphanumeric , dashes , and underscores characters to be compatible
* with sanitize_key () .
2015-11-23 12:56:26 -05:00
* @ param callable $function The function to be called to output the content for this page .
* @ param string $icon_url The URL to the icon to be used for this menu .
* * Pass a base64 - encoded SVG using a data URI , which will be colored to match
* the color scheme . This should begin with 'data:image/svg+xml;base64,' .
* * Pass the name of a Dashicons helper class to use a font icon ,
* e . g . 'dashicons-chart-pie' .
* * Pass 'none' to leave div . wp - menu - image empty so an icon can be added via CSS .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2015-11-23 12:56:26 -05:00
* @ return string The resulting page ' s hook_suffix .
2010-01-31 12:36:00 -05:00
*/
2012-01-05 15:50:54 -05:00
function add_menu_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $icon_url = '' , $position = null ) {
2010-06-10 17:38:41 -04:00
global $menu , $admin_page_hooks , $_registered_pages , $_parent_pages ;
2007-05-25 03:16:21 -04:00
2010-01-31 12:36:00 -05:00
$menu_slug = plugin_basename ( $menu_slug );
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
$admin_page_hooks [ $menu_slug ] = sanitize_title ( $menu_title );
2007-05-25 03:16:21 -04:00
2010-01-31 12:36:00 -05:00
$hookname = get_plugin_page_hookname ( $menu_slug , '' );
2010-03-03 19:15:55 -05:00
2017-11-30 18:11:00 -05:00
if ( ! empty ( $function ) && ! empty ( $hookname ) && current_user_can ( $capability ) ) {
2007-05-25 03:16:21 -04:00
add_action ( $hookname , $function );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( empty ( $icon_url ) ) {
$icon_url = 'dashicons-admin-generic' ;
2012-11-05 19:25:18 -05:00
$icon_class = 'menu-icon-generic ' ;
} else {
2017-11-30 18:11:00 -05:00
$icon_url = set_url_scheme ( $icon_url );
2012-11-05 19:25:18 -05:00
$icon_class = '' ;
}
2008-12-09 13:03:31 -05:00
2012-11-05 19:25:18 -05:00
$new_menu = array ( $menu_title , $capability , $menu_slug , $page_title , 'menu-top ' . $icon_class . $hookname , $hookname , $icon_url );
2008-10-14 18:44:56 -04:00
2015-10-31 16:31:24 -04:00
if ( null === $position ) {
2009-08-20 17:00:52 -04:00
$menu [] = $new_menu ;
2020-10-13 15:59:08 -04:00
} elseif ( isset ( $menu [ " $position " ] ) ) {
$position = $position + substr ( base_convert ( md5 ( $menu_slug . $menu_title ), 16 , 10 ), - 5 ) * 0.00001 ;
$menu [ " $position " ] = $new_menu ;
2015-10-31 16:31:24 -04:00
} else {
$menu [ $position ] = $new_menu ;
}
2009-09-14 10:03:32 -04:00
2017-11-30 18:11:00 -05:00
$_registered_pages [ $hookname ] = true ;
2009-06-19 02:08:03 -04:00
2020-01-28 19:35:08 -05:00
// No parent as top level.
2017-11-30 18:11:00 -05:00
$_parent_pages [ $menu_slug ] = false ;
2010-06-11 16:19:35 -04:00
2007-05-25 03:16:21 -04:00
return $hookname ;
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add a submenu page .
2010-02-02 16:41:17 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
*
2017-12-14 19:15:52 -05:00
* @ since 1.5 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-05-28 22:06:31 -04:00
* @ global array $submenu
* @ global array $menu
2015-11-03 15:13:26 -05:00
* @ global array $_wp_real_parent_file
2015-11-23 12:56:26 -05:00
* @ global bool $_wp_submenu_nopriv
2015-05-28 22:06:31 -04:00
* @ global array $_registered_pages
* @ global array $_parent_pages
*
2017-06-30 00:18:43 -04:00
* @ param string $parent_slug The slug name for the parent menu ( or the file name of a standard
* WordPress admin page ) .
* @ param string $page_title The text to be displayed in the title tags of the page when the menu
* is selected .
2015-11-23 12:56:26 -05:00
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
2017-06-30 00:18:43 -04:00
* @ param string $menu_slug The slug name to refer to this menu by . Should be unique for this menu
* and only include lowercase alphanumeric , dashes , and underscores characters
* to be compatible with sanitize_key () .
2015-11-23 12:56:26 -05:00
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_submenu_page ( $parent_slug , $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
2015-05-28 22:06:31 -04:00
global $submenu , $menu , $_wp_real_parent_file , $_wp_submenu_nopriv ,
$_registered_pages , $_parent_pages ;
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
$menu_slug = plugin_basename ( $menu_slug );
$parent_slug = plugin_basename ( $parent_slug );
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_real_parent_file [ $parent_slug ] ) ) {
$parent_slug = $_wp_real_parent_file [ $parent_slug ];
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( ! current_user_can ( $capability ) ) {
$_wp_submenu_nopriv [ $parent_slug ][ $menu_slug ] = true ;
2007-05-25 03:16:21 -04:00
return false ;
}
2014-07-17 05:14:16 -04:00
/*
* If the parent doesn ' t already have a submenu , add a link to the parent
* as the first item in the submenu . If the submenu file is the same as the
* parent file someone is trying to link back to the parent manually . In
* this case , don ' t automatically add a link back to avoid duplication .
*/
2020-08-08 17:04:04 -04:00
if ( ! isset ( $submenu [ $parent_slug ] ) && $menu_slug !== $parent_slug ) {
2017-11-30 18:11:00 -05:00
foreach ( ( array ) $menu as $parent_menu ) {
2020-08-08 17:04:04 -04:00
if ( $parent_menu [ 2 ] === $parent_slug && current_user_can ( $parent_menu [ 1 ] ) ) {
2017-11-30 18:11:00 -05:00
$submenu [ $parent_slug ][] = array_slice ( $parent_menu , 0 , 4 );
}
2007-05-25 03:16:21 -04:00
}
}
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
$new_sub_menu = array ( $menu_title , $capability , $menu_slug , $page_title );
2019-10-22 13:52:04 -04:00
if ( ! is_int ( $position ) ) {
if ( null !== $position ) {
_doing_it_wrong (
__FUNCTION__ ,
sprintf (
/* translators: %s: add_submenu_page() */
__ ( 'The seventh parameter passed to %s should be an integer representing menu position.' ),
'<code>add_submenu_page()</code>'
),
'5.3.0'
);
}
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
$submenu [ $parent_slug ][] = $new_sub_menu ;
} else {
2019-12-09 16:03:02 -05:00
// Append the submenu if the parent item is not present in the submenu,
// or if position is equal or higher than the number of items in the array.
if ( ! isset ( $submenu [ $parent_slug ] ) || $position >= count ( $submenu [ $parent_slug ] ) ) {
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
$submenu [ $parent_slug ][] = $new_sub_menu ;
} else {
// Test for a negative position.
$position = max ( $position , 0 );
if ( 0 === $position ) {
// For negative or `0` positions, prepend the submenu.
array_unshift ( $submenu [ $parent_slug ], $new_sub_menu );
} else {
// Grab all of the items before the insertion point.
$before_items = array_slice ( $submenu [ $parent_slug ], 0 , $position , true );
// Grab all of the items after the insertion point.
$after_items = array_slice ( $submenu [ $parent_slug ], $position , null , true );
// Add the new item.
$before_items [] = $new_sub_menu ;
// Merge the items.
$submenu [ $parent_slug ] = array_merge ( $before_items , $after_items );
}
}
}
2020-01-28 19:35:08 -05:00
// Sort the parent array.
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
ksort ( $submenu [ $parent_slug ] );
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
$hookname = get_plugin_page_hookname ( $menu_slug , $parent_slug );
if ( ! empty ( $function ) && ! empty ( $hookname ) ) {
2007-05-25 03:16:21 -04:00
add_action ( $hookname , $function );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
$_registered_pages [ $hookname ] = true ;
2014-07-17 05:14:16 -04:00
/*
2019-04-01 10:09:52 -04:00
* Backward - compatibility for plugins using add_management_page () .
* See wp - admin / admin . php for redirect from edit . php to tools . php .
2014-07-17 05:14:16 -04:00
*/
2020-05-16 14:42:12 -04:00
if ( 'tools.php' === $parent_slug ) {
2017-11-30 18:11:00 -05:00
$_registered_pages [ get_plugin_page_hookname ( $menu_slug , 'edit.php' ) ] = true ;
}
2009-06-19 02:08:03 -04:00
2014-07-17 05:14:16 -04:00
// No parent as top level.
2017-11-30 18:11:00 -05:00
$_parent_pages [ $menu_slug ] = $parent_slug ;
2010-06-11 16:19:35 -04:00
2007-05-25 03:16:21 -04:00
return $hookname ;
}
2008-09-16 20:40:10 -04:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Tools main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 1.5 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2008-09-16 20:40:10 -04:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_management_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'tools.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2007-05-25 03:16:21 -04:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Settings main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 1.5 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_options_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'options-general.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2007-05-25 03:16:21 -04:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Appearance main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.0 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_theme_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'themes.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2007-05-25 03:16:21 -04:00
}
2010-02-12 23:04:01 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Plugins main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-12 23:04:01 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 3.0 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-02-12 23:04:01 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_plugins_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'plugins.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2010-02-12 23:04:01 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Users / Profile main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.1 . 3
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_users_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
2017-11-30 18:11:00 -05:00
if ( current_user_can ( 'edit_users' ) ) {
2007-05-25 03:16:21 -04:00
$parent = 'users.php' ;
2017-11-30 18:11:00 -05:00
} else {
2007-05-25 03:16:21 -04:00
$parent = 'profile.php' ;
2017-11-30 18:11:00 -05:00
}
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
return add_submenu_page ( $parent , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2007-05-25 03:16:21 -04:00
}
2019-10-05 22:23:03 -04:00
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Dashboard main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_dashboard_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'index.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-18 14:30:50 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Posts main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_posts_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'edit.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-14 15:53:43 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Media main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_media_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'upload.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-14 15:53:43 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Links main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2010-01-31 12:36:00 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_links_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'link-manager.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-14 15:53:43 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Pages main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2015-12-12 10:37:28 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_pages_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'edit.php?post_type=page' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-14 15:53:43 -05:00
}
2010-01-31 12:36:00 -05:00
/**
2015-11-23 12:56:26 -05:00
* Add submenu page to the Comments main menu .
2010-12-08 23:02:37 -05:00
*
2010-10-07 18:58:45 -04:00
* This function takes a capability which will be used to determine whether
* or not a page is included in the menu .
*
* The function which is hooked in to handle the output of the page must check
* that the user has the required capability as well .
2010-02-02 16:41:17 -05:00
*
2017-12-14 19:15:52 -05:00
* @ since 2.7 . 0
2019-09-20 13:06:57 -04:00
* @ since 5.3 . 0 Added the `$position` parameter .
2017-12-14 19:15:52 -05:00
*
2015-11-23 12:56:26 -05:00
* @ param string $page_title The text to be displayed in the title tags of the page when the menu is selected .
* @ param string $menu_title The text to be used for the menu .
* @ param string $capability The capability required for this menu to be displayed to the user .
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param callable $function The function to be called to output the content for this page .
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
* @ param int $position The position in the menu order this item should appear .
2020-01-11 13:32:05 -05:00
* @ return string | false The resulting page ' s hook_suffix , or false if the user does not have the capability required .
2015-12-12 10:37:28 -05:00
*/
Menus: add a position argument to `add_submenu_page` and the helper functions that use it.
Add a position argument to the `add_submenu_page` function similar to the one already in `add_menu_page`. When adding sub menus enables setting the position in the sub menu where the item should appear.
In addition, add the position argument to functions that call `add_submenu_page` under the hood: `add_management_page`, `add_options_page`, `add_theme_page`, `add_plugins_page`, `add_users_page`, `add_dashboard_page`, `add_posts_page`, `add_media_page`, `add_links_page`, `add_pages_page` and `add_comments_page`.
Props welcher, birgire, alexvorn2.
Fixes #39776.
Built from https://develop.svn.wordpress.org/trunk@46197
git-svn-id: http://core.svn.wordpress.org/trunk@46009 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-20 11:00:59 -04:00
function add_comments_page ( $page_title , $menu_title , $capability , $menu_slug , $function = '' , $position = null ) {
return add_submenu_page ( 'edit-comments.php' , $page_title , $menu_title , $capability , $menu_slug , $function , $position );
2008-11-14 15:53:43 -05:00
}
2010-10-07 18:35:31 -04:00
/**
2015-11-23 12:56:26 -05:00
* Remove a top - level admin menu .
2010-10-07 18:35:31 -04:00
*
* @ since 3.1 . 0
*
2015-05-28 22:06:31 -04:00
* @ global array $menu
*
2015-11-23 12:56:26 -05:00
* @ param string $menu_slug The slug of the menu .
2021-01-03 17:04:04 -05:00
* @ return array | false The removed menu on success , false if not found .
2010-10-07 18:35:31 -04:00
*/
function remove_menu_page ( $menu_slug ) {
global $menu ;
foreach ( $menu as $i => $item ) {
2020-08-08 17:04:04 -04:00
if ( $menu_slug === $item [ 2 ] ) {
2017-11-30 18:11:00 -05:00
unset ( $menu [ $i ] );
2010-10-07 18:35:31 -04:00
return $item ;
}
}
return false ;
}
/**
2015-11-23 12:56:26 -05:00
* Remove an admin submenu .
2010-10-07 18:35:31 -04:00
*
* @ since 3.1 . 0
*
2015-05-28 22:06:31 -04:00
* @ global array $submenu
*
2015-11-23 12:56:26 -05:00
* @ param string $menu_slug The slug for the parent menu .
* @ param string $submenu_slug The slug of the submenu .
2021-01-03 17:04:04 -05:00
* @ return array | false The removed submenu on success , false if not found .
2010-10-07 18:35:31 -04:00
*/
function remove_submenu_page ( $menu_slug , $submenu_slug ) {
global $submenu ;
2017-11-30 18:11:00 -05:00
if ( ! isset ( $submenu [ $menu_slug ] ) ) {
2010-10-07 18:35:31 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2010-10-07 18:35:31 -04:00
2017-11-30 18:11:00 -05:00
foreach ( $submenu [ $menu_slug ] as $i => $item ) {
2020-08-08 17:04:04 -04:00
if ( $submenu_slug === $item [ 2 ] ) {
2017-11-30 18:11:00 -05:00
unset ( $submenu [ $menu_slug ][ $i ] );
2010-10-07 18:35:31 -04:00
return $item ;
}
}
return false ;
}
2010-06-10 17:38:41 -04:00
/**
2019-11-10 19:05:01 -05:00
* Get the URL to access a particular menu page based on the slug it was registered with .
2010-06-11 16:19:35 -04:00
*
2019-11-10 19:05:01 -05:00
* If the slug hasn ' t been registered properly , no URL will be returned .
2010-06-11 16:19:35 -04:00
*
2013-12-24 13:57:12 -05:00
* @ since 3.0 . 0
2010-06-11 16:19:35 -04:00
*
2015-05-28 22:06:31 -04:00
* @ global array $_parent_pages
*
2019-11-10 19:05:01 -05:00
* @ param string $menu_slug The slug name to refer to this menu by ( should be unique for this menu ) .
* @ param bool $echo Whether or not to echo the URL . Default true .
* @ return string The menu page URL .
2010-06-10 17:38:41 -04:00
*/
2017-11-30 18:11:00 -05:00
function menu_page_url ( $menu_slug , $echo = true ) {
2010-06-10 17:38:41 -04:00
global $_parent_pages ;
2010-06-11 16:19:35 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_parent_pages [ $menu_slug ] ) ) {
$parent_slug = $_parent_pages [ $menu_slug ];
2020-08-08 17:04:04 -04:00
2017-11-30 18:11:00 -05:00
if ( $parent_slug && ! isset ( $_parent_pages [ $parent_slug ] ) ) {
2010-12-08 23:02:37 -05:00
$url = admin_url ( add_query_arg ( 'page' , $menu_slug , $parent_slug ) );
2010-06-10 17:38:41 -04:00
} else {
2010-12-08 23:02:37 -05:00
$url = admin_url ( 'admin.php?page=' . $menu_slug );
2010-06-10 17:38:41 -04:00
}
} else {
$url = '' ;
}
2010-06-11 16:19:35 -04:00
2017-11-30 18:11:00 -05:00
$url = esc_url ( $url );
2010-06-11 16:19:35 -04:00
2017-11-30 18:11:00 -05:00
if ( $echo ) {
2010-06-10 17:38:41 -04:00
echo $url ;
2017-11-30 18:11:00 -05:00
}
2010-06-11 16:19:35 -04:00
2010-06-10 17:38:41 -04:00
return $url ;
}
2007-05-25 03:16:21 -04:00
//
2020-01-28 19:35:08 -05:00
// Pluggable Menu Support -- Private.
2007-05-25 03:16:21 -04:00
//
2015-05-28 22:06:31 -04:00
/**
2019-12-23 09:36:04 -05:00
* Gets the parent file of the current admin page .
*
* @ since 1.5 . 0
*
2015-05-28 22:06:31 -04:00
* @ global string $parent_file
2020-04-03 13:23:11 -04:00
* @ global array $menu
* @ global array $submenu
2015-05-28 22:06:31 -04:00
* @ global string $pagenow
* @ global string $typenow
* @ global string $plugin_page
2020-04-03 13:23:11 -04:00
* @ global array $_wp_real_parent_file
* @ global array $_wp_menu_nopriv
* @ global array $_wp_submenu_nopriv
2019-04-01 10:09:52 -04:00
*
2020-04-03 13:23:11 -04:00
* @ param string $parent The slug name for the parent menu ( or the file name of a standard
* WordPress admin page ) . Default empty string .
2019-12-23 09:36:04 -05:00
* @ return string The parent file of the current admin page .
2015-05-28 22:06:31 -04:00
*/
2008-08-25 20:54:21 -04:00
function get_admin_page_parent ( $parent = '' ) {
2015-05-28 22:06:31 -04:00
global $parent_file , $menu , $submenu , $pagenow , $typenow ,
$plugin_page , $_wp_real_parent_file , $_wp_menu_nopriv , $_wp_submenu_nopriv ;
2007-05-25 03:16:21 -04:00
2020-05-16 14:42:12 -04:00
if ( ! empty ( $parent ) && 'admin.php' !== $parent ) {
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_real_parent_file [ $parent ] ) ) {
$parent = $_wp_real_parent_file [ $parent ];
}
2020-08-08 17:04:04 -04:00
2008-08-25 20:54:21 -04:00
return $parent ;
}
2010-01-04 11:58:43 -05:00
2020-02-09 11:55:09 -05:00
if ( 'admin.php' === $pagenow && isset ( $plugin_page ) ) {
2017-11-30 18:11:00 -05:00
foreach ( ( array ) $menu as $parent_menu ) {
2020-08-08 17:04:04 -04:00
if ( $parent_menu [ 2 ] === $plugin_page ) {
2007-05-25 03:16:21 -04:00
$parent_file = $plugin_page ;
2020-08-08 17:04:04 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_real_parent_file [ $parent_file ] ) ) {
$parent_file = $_wp_real_parent_file [ $parent_file ];
}
2020-08-08 17:04:04 -04:00
2007-05-25 03:16:21 -04:00
return $parent_file ;
}
}
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_menu_nopriv [ $plugin_page ] ) ) {
2007-05-25 03:16:21 -04:00
$parent_file = $plugin_page ;
2020-08-08 17:04:04 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_real_parent_file [ $parent_file ] ) ) {
$parent_file = $_wp_real_parent_file [ $parent_file ];
}
2020-08-08 17:04:04 -04:00
2007-05-25 03:16:21 -04:00
return $parent_file ;
}
}
2017-11-30 18:11:00 -05:00
if ( isset ( $plugin_page ) && isset ( $_wp_submenu_nopriv [ $pagenow ][ $plugin_page ] ) ) {
2007-05-25 03:16:21 -04:00
$parent_file = $pagenow ;
2020-08-08 17:04:04 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_real_parent_file [ $parent_file ] ) ) {
$parent_file = $_wp_real_parent_file [ $parent_file ];
}
2020-08-08 17:04:04 -04:00
2007-05-25 03:16:21 -04:00
return $parent_file ;
}
2017-11-30 18:11:00 -05:00
foreach ( array_keys ( ( array ) $submenu ) as $parent ) {
foreach ( $submenu [ $parent ] as $submenu_array ) {
if ( isset ( $_wp_real_parent_file [ $parent ] ) ) {
$parent = $_wp_real_parent_file [ $parent ];
}
2020-08-08 17:04:04 -04:00
if ( ! empty ( $typenow ) && " $pagenow ?post_type= $typenow " === $submenu_array [ 2 ] ) {
2010-03-03 19:15:55 -05:00
$parent_file = $parent ;
return $parent ;
2020-08-08 17:04:04 -04:00
} elseif ( empty ( $typenow ) && $pagenow === $submenu_array [ 2 ]
&& ( empty ( $parent_file ) || false === strpos ( $parent_file , '?' ) )
) {
2007-05-25 03:16:21 -04:00
$parent_file = $parent ;
return $parent ;
2020-08-08 17:04:04 -04:00
} elseif ( isset ( $plugin_page ) && $plugin_page === $submenu_array [ 2 ] ) {
2015-01-08 02:13:24 -05:00
$parent_file = $parent ;
return $parent ;
}
2007-05-25 03:16:21 -04:00
}
}
2017-11-30 18:11:00 -05:00
if ( empty ( $parent_file ) ) {
2008-11-28 20:56:09 -05:00
$parent_file = '' ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
return '' ;
}
2015-05-28 22:06:31 -04:00
/**
2019-12-23 09:36:04 -05:00
* Gets the title of the current admin page .
*
* @ since 1.5 . 0
*
2015-05-28 22:06:31 -04:00
* @ global string $title
* @ global array $menu
* @ global array $submenu
* @ global string $pagenow
* @ global string $plugin_page
* @ global string $typenow
2019-04-01 10:09:52 -04:00
*
2019-12-23 09:36:04 -05:00
* @ return string The title of the current admin page .
2015-05-28 22:06:31 -04:00
*/
2007-05-25 03:16:21 -04:00
function get_admin_page_title () {
2015-05-28 22:06:31 -04:00
global $title , $menu , $submenu , $pagenow , $plugin_page , $typenow ;
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( ! empty ( $title ) ) {
2007-05-25 03:16:21 -04:00
return $title ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
$hook = get_plugin_page_hook ( $plugin_page , $pagenow );
2019-07-01 08:52:01 -04:00
$parent = get_admin_page_parent ();
$parent1 = $parent ;
2008-10-14 18:44:56 -04:00
2017-11-30 18:11:00 -05:00
if ( empty ( $parent ) ) {
foreach ( ( array ) $menu as $menu_array ) {
2007-05-25 03:16:21 -04:00
if ( isset ( $menu_array [ 3 ] ) ) {
2020-08-08 17:04:04 -04:00
if ( $menu_array [ 2 ] === $pagenow ) {
2007-05-25 03:16:21 -04:00
$title = $menu_array [ 3 ];
return $menu_array [ 3 ];
2020-08-08 17:04:04 -04:00
} elseif ( isset ( $plugin_page ) && $plugin_page === $menu_array [ 2 ] && $hook === $menu_array [ 5 ] ) {
2015-01-08 02:13:24 -05:00
$title = $menu_array [ 3 ];
return $menu_array [ 3 ];
}
2007-05-25 03:16:21 -04:00
} else {
$title = $menu_array [ 0 ];
return $title ;
}
}
} else {
2010-04-17 22:56:00 -04:00
foreach ( array_keys ( $submenu ) as $parent ) {
2017-11-30 18:11:00 -05:00
foreach ( $submenu [ $parent ] as $submenu_array ) {
2020-08-08 17:04:04 -04:00
if ( isset ( $plugin_page )
2020-08-08 21:56:05 -04:00
&& $plugin_page === $submenu_array [ 2 ]
2020-08-08 17:04:04 -04:00
&& ( $pagenow === $parent
|| $plugin_page === $parent
|| $plugin_page === $hook
|| 'admin.php' === $pagenow && $parent1 !== $submenu_array [ 2 ]
|| ! empty ( $typenow ) && " $pagenow ?post_type= $typenow " === $parent )
2007-05-25 03:16:21 -04:00
) {
$title = $submenu_array [ 3 ];
return $submenu_array [ 3 ];
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2020-08-08 17:04:04 -04:00
if ( $submenu_array [ 2 ] !== $pagenow || isset ( $_GET [ 'page' ] ) ) { // Not the current page.
2007-05-25 03:16:21 -04:00
continue ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
if ( isset ( $submenu_array [ 3 ] ) ) {
$title = $submenu_array [ 3 ];
return $submenu_array [ 3 ];
} else {
$title = $submenu_array [ 0 ];
return $title ;
}
}
}
2017-11-30 18:11:00 -05:00
if ( empty ( $title ) ) {
2009-04-16 19:42:42 -04:00
foreach ( $menu as $menu_array ) {
2020-08-08 17:04:04 -04:00
if ( isset ( $plugin_page )
&& $plugin_page === $menu_array [ 2 ]
&& 'admin.php' === $pagenow
&& $parent1 === $menu_array [ 2 ]
) {
2009-04-16 19:42:42 -04:00
$title = $menu_array [ 3 ];
return $menu_array [ 3 ];
2017-11-30 18:11:00 -05:00
}
2009-04-16 19:42:42 -04:00
}
}
2007-05-25 03:16:21 -04:00
}
return $title ;
}
2015-05-30 23:18:25 -04:00
/**
2019-12-23 09:36:04 -05:00
* Gets the hook attached to the administrative page of a plugin .
*
* @ since 1.5 . 0
2015-05-30 23:18:25 -04:00
*
2019-04-01 10:09:52 -04:00
* @ param string $plugin_page The slug name of the plugin page .
* @ param string $parent_page The slug name for the parent menu ( or the file name of a standard
* WordPress admin page ) .
* @ return string | null Hook attached to the plugin page , null otherwise .
2015-05-30 23:18:25 -04:00
*/
2007-05-25 03:16:21 -04:00
function get_plugin_page_hook ( $plugin_page , $parent_page ) {
$hook = get_plugin_page_hookname ( $plugin_page , $parent_page );
2017-11-30 18:11:00 -05:00
if ( has_action ( $hook ) ) {
2007-05-25 03:16:21 -04:00
return $hook ;
2017-11-30 18:11:00 -05:00
} else {
2007-07-15 13:59:05 -04:00
return null ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
}
2015-05-28 22:06:31 -04:00
/**
2019-12-23 09:36:04 -05:00
* Gets the hook name for the administrative page of a plugin .
*
* @ since 1.5 . 0
*
2015-05-28 22:06:31 -04:00
* @ global array $admin_page_hooks
2019-04-01 10:09:52 -04:00
*
* @ param string $plugin_page The slug name of the plugin page .
* @ param string $parent_page The slug name for the parent menu ( or the file name of a standard
* WordPress admin page ) .
* @ return string Hook name for the plugin page .
2015-05-28 22:06:31 -04:00
*/
2007-05-25 03:16:21 -04:00
function get_plugin_page_hookname ( $plugin_page , $parent_page ) {
global $admin_page_hooks ;
2008-08-25 20:54:21 -04:00
$parent = get_admin_page_parent ( $parent_page );
2007-05-25 03:16:21 -04:00
2008-07-07 10:21:47 -04:00
$page_type = 'admin' ;
2020-05-16 14:42:12 -04:00
if ( empty ( $parent_page ) || 'admin.php' === $parent_page || isset ( $admin_page_hooks [ $plugin_page ] ) ) {
2017-11-30 18:11:00 -05:00
if ( isset ( $admin_page_hooks [ $plugin_page ] ) ) {
2007-05-25 03:16:21 -04:00
$page_type = 'toplevel' ;
2017-11-30 18:11:00 -05:00
} elseif ( isset ( $admin_page_hooks [ $parent ] ) ) {
$page_type = $admin_page_hooks [ $parent ];
2015-01-08 02:13:24 -05:00
}
2017-11-30 18:11:00 -05:00
} elseif ( isset ( $admin_page_hooks [ $parent ] ) ) {
$page_type = $admin_page_hooks [ $parent ];
2008-07-07 10:21:47 -04:00
}
2007-05-25 03:16:21 -04:00
$plugin_name = preg_replace ( '!\.php!' , '' , $plugin_page );
2010-04-17 22:56:00 -04:00
return $page_type . '_page_' . $plugin_name ;
2007-05-25 03:16:21 -04:00
}
2015-05-28 22:06:31 -04:00
/**
2019-12-23 09:36:04 -05:00
* Determines whether the current user can access the current admin page .
*
* @ since 1.5 . 0
*
2015-05-28 22:06:31 -04:00
* @ global string $pagenow
2019-12-23 09:36:04 -05:00
* @ global array $menu
* @ global array $submenu
* @ global array $_wp_menu_nopriv
* @ global array $_wp_submenu_nopriv
2015-05-28 22:06:31 -04:00
* @ global string $plugin_page
2019-12-23 09:36:04 -05:00
* @ global array $_registered_pages
2019-04-01 10:09:52 -04:00
*
2019-12-23 09:36:04 -05:00
* @ return bool True if the current user can access the admin page , false otherwise .
2015-05-28 22:06:31 -04:00
*/
2007-05-25 03:16:21 -04:00
function user_can_access_admin_page () {
2015-05-28 22:06:31 -04:00
global $pagenow , $menu , $submenu , $_wp_menu_nopriv , $_wp_submenu_nopriv ,
$plugin_page , $_registered_pages ;
2007-05-25 03:16:21 -04:00
$parent = get_admin_page_parent ();
2017-11-30 18:11:00 -05:00
if ( ! isset ( $plugin_page ) && isset ( $_wp_submenu_nopriv [ $parent ][ $pagenow ] ) ) {
2007-05-25 03:16:21 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2015-01-08 17:52:22 -05:00
if ( isset ( $plugin_page ) ) {
2017-11-30 18:11:00 -05:00
if ( isset ( $_wp_submenu_nopriv [ $parent ][ $plugin_page ] ) ) {
2009-06-19 02:08:03 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2009-06-19 02:08:03 -04:00
2017-11-30 18:11:00 -05:00
$hookname = get_plugin_page_hookname ( $plugin_page , $parent );
2010-03-03 19:15:55 -05:00
2017-11-30 18:11:00 -05:00
if ( ! isset ( $_registered_pages [ $hookname ] ) ) {
2009-06-19 02:08:03 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2009-06-19 02:08:03 -04:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( empty ( $parent ) ) {
if ( isset ( $_wp_menu_nopriv [ $pagenow ] ) ) {
2007-05-25 03:16:21 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
if ( isset ( $_wp_submenu_nopriv [ $pagenow ][ $pagenow ] ) ) {
2007-05-25 03:16:21 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
if ( isset ( $plugin_page ) && isset ( $_wp_submenu_nopriv [ $pagenow ][ $plugin_page ] ) ) {
2007-05-25 03:16:21 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
if ( isset ( $plugin_page ) && isset ( $_wp_menu_nopriv [ $plugin_page ] ) ) {
2009-06-17 15:50:38 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2020-08-08 16:24:05 -04:00
2017-11-30 18:11:00 -05:00
foreach ( array_keys ( $_wp_submenu_nopriv ) as $key ) {
if ( isset ( $_wp_submenu_nopriv [ $key ][ $pagenow ] ) ) {
2007-05-25 03:16:21 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
if ( isset ( $plugin_page ) && isset ( $_wp_submenu_nopriv [ $key ][ $plugin_page ] ) ) {
return false ;
}
2007-05-25 03:16:21 -04:00
}
2020-08-08 16:24:05 -04:00
2007-05-25 03:16:21 -04:00
return true ;
}
2020-08-08 21:56:05 -04:00
if ( isset ( $plugin_page ) && $plugin_page === $parent && isset ( $_wp_menu_nopriv [ $plugin_page ] ) ) {
2009-06-14 20:22:53 -04:00
return false ;
2017-11-30 18:11:00 -05:00
}
2009-06-14 20:22:53 -04:00
2017-11-30 18:11:00 -05:00
if ( isset ( $submenu [ $parent ] ) ) {
foreach ( $submenu [ $parent ] as $submenu_array ) {
2020-08-08 21:56:05 -04:00
if ( isset ( $plugin_page ) && $submenu_array [ 2 ] === $plugin_page ) {
2020-08-08 16:24:05 -04:00
return current_user_can ( $submenu_array [ 1 ] );
2020-08-08 17:04:04 -04:00
} elseif ( $submenu_array [ 2 ] === $pagenow ) {
2020-08-08 16:24:05 -04:00
return current_user_can ( $submenu_array [ 1 ] );
2007-05-25 03:16:21 -04:00
}
}
}
foreach ( $menu as $menu_array ) {
2020-08-08 17:04:04 -04:00
if ( $menu_array [ 2 ] === $parent ) {
2020-08-08 16:24:05 -04:00
return current_user_can ( $menu_array [ 1 ] );
2007-05-25 03:16:21 -04:00
}
}
return true ;
}
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
/* Allowed list functions */
2008-10-19 19:35:09 -04:00
/**
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* Refreshes the value of the allowed options list available via the 'allowed_options' hook .
2016-05-23 13:28:27 -04:00
*
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* See the { @ see 'allowed_options' } filter .
2008-10-19 19:35:09 -04:00
*
2010-12-01 14:24:38 -05:00
* @ since 2.7 . 0
2020-07-14 08:33:02 -04:00
* @ since 5.5 . 0 `$new_whitelist_options` was renamed to `$new_allowed_options` .
* Please consider writing more inclusive code .
2008-10-19 19:35:09 -04:00
*
2020-07-14 08:33:02 -04:00
* @ global array $new_allowed_options
2015-05-28 22:06:31 -04:00
*
2014-11-03 00:59:22 -05:00
* @ param array $options
* @ return array
2008-10-19 19:35:09 -04:00
*/
function option_update_filter ( $options ) {
2020-07-14 08:33:02 -04:00
global $new_allowed_options ;
2008-10-19 19:35:09 -04:00
2020-07-14 08:33:02 -04:00
if ( is_array ( $new_allowed_options ) ) {
$options = add_allowed_options ( $new_allowed_options , $options );
2017-11-30 18:11:00 -05:00
}
2008-10-19 19:35:09 -04:00
return $options ;
}
/**
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* Adds an array of options to the list of allowed options .
2008-10-19 19:35:09 -04:00
*
2020-10-06 11:55:05 -04:00
* @ since 5.5 . 0
2008-10-19 19:35:09 -04:00
*
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* @ global array $allowed_options
2015-05-28 22:06:31 -04:00
*
2014-11-03 00:59:22 -05:00
* @ param array $new_options
* @ param string | array $options
* @ return array
2008-10-19 19:35:09 -04:00
*/
2020-06-23 14:54:16 -04:00
function add_allowed_options ( $new_options , $options = '' ) {
2020-05-16 14:42:12 -04:00
if ( '' === $options ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
global $allowed_options ;
2017-11-30 18:11:00 -05:00
} else {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
$allowed_options = $options ;
2017-11-30 18:11:00 -05:00
}
2010-01-25 16:33:49 -05:00
foreach ( $new_options as $page => $keys ) {
foreach ( $keys as $key ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
if ( ! isset ( $allowed_options [ $page ] ) || ! is_array ( $allowed_options [ $page ] ) ) {
$allowed_options [ $page ] = array ();
$allowed_options [ $page ][] = $key ;
2008-12-04 18:20:41 -05:00
} else {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
$pos = array_search ( $key , $allowed_options [ $page ], true );
2020-02-09 11:55:09 -05:00
if ( false === $pos ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
$allowed_options [ $page ][] = $key ;
2017-11-30 18:11:00 -05:00
}
2008-12-04 18:20:41 -05:00
}
2008-10-19 19:35:09 -04:00
}
}
2010-01-25 16:33:49 -05:00
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
return $allowed_options ;
2008-10-19 19:35:09 -04:00
}
/**
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* Removes a list of options from the allowed options list .
2008-10-19 19:35:09 -04:00
*
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* @ since 5.5 . 0
2008-10-19 19:35:09 -04:00
*
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
* @ global array $allowed_options
2015-05-28 22:06:31 -04:00
*
2014-11-03 00:59:22 -05:00
* @ param array $del_options
* @ param string | array $options
* @ return array
2008-10-19 19:35:09 -04:00
*/
2020-07-22 14:52:02 -04:00
function remove_allowed_options ( $del_options , $options = '' ) {
2020-05-16 14:42:12 -04:00
if ( '' === $options ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
global $allowed_options ;
2017-11-30 18:11:00 -05:00
} else {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
$allowed_options = $options ;
2017-11-30 18:11:00 -05:00
}
2010-01-25 16:33:49 -05:00
foreach ( $del_options as $page => $keys ) {
foreach ( $keys as $key ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
if ( isset ( $allowed_options [ $page ] ) && is_array ( $allowed_options [ $page ] ) ) {
$pos = array_search ( $key , $allowed_options [ $page ], true );
2020-02-09 11:55:09 -05:00
if ( false !== $pos ) {
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
unset ( $allowed_options [ $page ][ $pos ] );
2017-11-30 18:11:00 -05:00
}
2008-12-18 17:26:03 -05:00
}
2008-10-19 19:35:09 -04:00
}
}
2010-01-25 16:33:49 -05:00
General: Remove “whitelist” and “blacklist” in favor of more clear and inclusive language.
“The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included.”
With this commit, all occurrences of “whitelist” and “blacklist” (with the single exception of the `$new_whitelist_options` global variable) are removed. A new ticket has been opened to explore renaming the `$new_whitelist_options` variable (#50434).
Changing to more specific names or rewording sentences containing these terms not only makes the code more inclusive, but also helps provide clarity. These terms are often ambiguous. What is being blocked or allowed is not always immediately clear. This can make it more difficult for non-native English speakers to read through the codebase.
Words matter. If one contributor feels more welcome because these terms are removed, this was worth the effort.
Props strangerstudios, jorbin, desrosj, joemcgill, timothyblynjacobs, ocean90, ayeshrajans, davidbaumwald, earnjam.
See #48900, #50434.
Fixes #50413.
Built from https://develop.svn.wordpress.org/trunk@48121
git-svn-id: http://core.svn.wordpress.org/trunk@47890 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-06-22 13:26:13 -04:00
return $allowed_options ;
2008-10-19 19:35:09 -04:00
}
/**
* Output nonce , action , and option_page fields for a settings page .
*
* @ since 2.7 . 0
*
2019-11-10 19:05:01 -05:00
* @ param string $option_group A settings group name . This should match the group name
* used in register_setting () .
2008-10-19 19:35:09 -04:00
*/
2017-11-30 18:11:00 -05:00
function settings_fields ( $option_group ) {
echo " <input type='hidden' name='option_page' value=' " . esc_attr ( $option_group ) . " ' /> " ;
2008-10-19 19:35:09 -04:00
echo '<input type="hidden" name="action" value="update" />' ;
2017-11-30 18:11:00 -05:00
wp_nonce_field ( " $option_group -options " );
2008-10-19 19:35:09 -04:00
}
2013-09-05 21:33:09 -04:00
/**
2019-11-10 19:05:01 -05:00
* Clears the plugins cache used by get_plugins () and by default , the plugin updates cache .
2013-09-05 21:33:09 -04:00
*
* @ since 3.7 . 0
*
2019-11-10 19:05:01 -05:00
* @ param bool $clear_update_cache Whether to clear the plugin updates cache . Default true .
2013-09-05 21:33:09 -04:00
*/
function wp_clean_plugins_cache ( $clear_update_cache = true ) {
2017-11-30 18:11:00 -05:00
if ( $clear_update_cache ) {
2013-09-05 21:33:09 -04:00
delete_site_transient ( 'update_plugins' );
2017-11-30 18:11:00 -05:00
}
2013-09-05 21:33:09 -04:00
wp_cache_delete ( 'plugins' , 'plugins' );
}
2015-09-10 17:24:24 -04:00
/**
2017-10-10 20:03:48 -04:00
* Load a given plugin attempt to generate errors .
2017-09-21 21:36:48 -04:00
*
* @ since 3.0 . 0
* @ since 4.4 . 0 Function was moved into the `wp-admin/includes/plugin.php` file .
*
2018-03-05 16:50:31 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2015-09-10 17:24:24 -04:00
*/
function plugin_sandbox_scrape ( $plugin ) {
2019-04-05 11:53:50 -04:00
if ( ! defined ( 'WP_SANDBOX_SCRAPING' ) ) {
define ( 'WP_SANDBOX_SCRAPING' , true );
}
2020-07-05 16:32:03 -04:00
2015-09-10 17:24:24 -04:00
wp_register_plugin_realpath ( WP_PLUGIN_DIR . '/' . $plugin );
2021-04-25 09:21:05 -04:00
include_once WP_PLUGIN_DIR . '/' . $plugin ;
2015-09-18 16:29:26 -04:00
}
2018-04-16 04:53:20 -04:00
/**
2018-06-27 22:36:09 -04:00
* Helper function for adding content to the Privacy Policy Guide .
2018-04-25 14:10:21 -04:00
*
* Plugins and themes should suggest text for inclusion in the site ' s privacy policy .
* The suggested text should contain information about any functionality that affects user privacy ,
2018-06-27 22:36:09 -04:00
* and will be shown on the Privacy Policy Guide screen .
2018-04-25 14:10:21 -04:00
*
* A plugin or theme can use this function multiple times as long as it will help to better present
* the suggested policy content . For example modular plugins such as WooCommerse or Jetpack
* can add or remove suggested content depending on the modules / extensions that are enabled .
2018-06-27 22:36:09 -04:00
* For more information see the Plugin Handbook :
* https :// developer . wordpress . org / plugins / privacy / suggesting - text - for - the - site - privacy - policy /.
2018-04-16 04:53:20 -04:00
*
2020-01-26 20:06:04 -05:00
* The HTML contents of the `$policy_text` supports use of a specialized `.privacy-policy-tutorial`
* CSS class which can be used to provide supplemental information . Any content contained within
* HTML elements that have the `.privacy-policy-tutorial` CSS class applied will be omitted
* from the clipboard when the section content is copied .
2020-01-26 18:02:03 -05:00
*
2018-04-16 04:53:20 -04:00
* Intended for use with the `'admin_init'` action .
*
* @ since 4.9 . 6
*
2019-11-10 19:05:01 -05:00
* @ param string $plugin_name The name of the plugin or theme that is suggesting content
* for the site ' s privacy policy .
2018-04-25 14:10:21 -04:00
* @ param string $policy_text The suggested content for inclusion in the policy .
2018-04-16 04:53:20 -04:00
*/
function wp_add_privacy_policy_content ( $plugin_name , $policy_text ) {
2018-06-27 22:36:09 -04:00
if ( ! is_admin () ) {
_doing_it_wrong (
__FUNCTION__ ,
sprintf (
/* translators: %s: admin_init */
__ ( 'The suggested privacy policy content should be added only in wp-admin by using the %s (or later) action.' ),
'<code>admin_init</code>'
),
'4.9.7'
);
return ;
} elseif ( ! doing_action ( 'admin_init' ) && ! did_action ( 'admin_init' ) ) {
_doing_it_wrong (
__FUNCTION__ ,
sprintf (
/* translators: %s: admin_init */
__ ( 'The suggested privacy policy content should be added by using the %s (or later) action. Please see the inline documentation.' ),
'<code>admin_init</code>'
),
'4.9.7'
);
return ;
}
2018-04-16 04:53:20 -04:00
if ( ! class_exists ( 'WP_Privacy_Policy_Content' ) ) {
2020-02-06 01:33:11 -05:00
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-policy-content.php' ;
2018-04-16 04:53:20 -04:00
}
WP_Privacy_Policy_Content :: add ( $plugin_name , $policy_text );
}
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 17:53:51 -04:00
/**
* Determines whether a plugin is technically active but was paused while
* loading .
*
* For more information on this and similar theme functions , check out
* the { @ link https :// developer . wordpress . org / themes / basics / conditional - tags /
* Conditional Tags } article in the Theme Developer Handbook .
*
* @ since 5.2 . 0
*
* @ param string $plugin Path to the plugin file relative to the plugins directory .
2019-11-10 19:05:01 -05:00
* @ return bool True , if in the list of paused plugins . False , if not in the list .
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 17:53:51 -04:00
*/
function is_plugin_paused ( $plugin ) {
if ( ! isset ( $GLOBALS [ '_paused_plugins' ] ) ) {
return false ;
}
if ( ! is_plugin_active ( $plugin ) ) {
return false ;
}
list ( $plugin ) = explode ( '/' , $plugin );
return array_key_exists ( $plugin , $GLOBALS [ '_paused_plugins' ] );
}
/**
* Gets the error that was recorded for a paused plugin .
*
* @ since 5.2 . 0
*
2019-11-10 19:05:01 -05:00
* @ param string $plugin Path to the plugin file relative to the plugins directory .
* @ return array | false Array of error information as returned by `error_get_last()` ,
* or false if none was recorded .
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 17:53:51 -04:00
*/
function wp_get_plugin_error ( $plugin ) {
if ( ! isset ( $GLOBALS [ '_paused_plugins' ] ) ) {
return false ;
}
list ( $plugin ) = explode ( '/' , $plugin );
if ( ! array_key_exists ( $plugin , $GLOBALS [ '_paused_plugins' ] ) ) {
return false ;
}
return $GLOBALS [ '_paused_plugins' ][ $plugin ];
}
/**
* Tries to resume a single plugin .
*
* If a redirect was provided , we first ensure the plugin does not throw fatal
* errors anymore .
*
* The way it works is by setting the redirection to the error before trying to
* include the plugin file . If the plugin fails , then the redirection will not
* be overwritten with the success message and the plugin will not be resumed .
*
* @ since 5.2 . 0
*
2019-11-10 19:05:01 -05:00
* @ param string $plugin Single plugin to resume .
* @ param string $redirect Optional . URL to redirect to . Default empty string .
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 17:53:51 -04:00
* @ return bool | WP_Error True on success , false if `$plugin` was not paused ,
* `WP_Error` on failure .
*/
function resume_plugin ( $plugin , $redirect = '' ) {
/*
* We ' ll override this later if the plugin could be resumed without
* creating a fatal error .
*/
if ( ! empty ( $redirect ) ) {
wp_redirect (
add_query_arg (
'_error_nonce' ,
wp_create_nonce ( 'plugin-resume-error_' . $plugin ),
$redirect
)
);
// Load the plugin to test whether it throws a fatal error.
ob_start ();
plugin_sandbox_scrape ( $plugin );
ob_clean ();
}
list ( $extension ) = explode ( '/' , $plugin );
$result = wp_paused_plugins () -> delete ( $extension );
if ( ! $result ) {
return new WP_Error (
'could_not_resume_plugin' ,
__ ( 'Could not resume the plugin.' )
);
}
return true ;
}
/**
* Renders an admin notice in case some plugins have been paused due to errors .
*
* @ since 5.2 . 0
2021-02-22 14:18:12 -05:00
*
* @ global string $pagenow
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 17:53:51 -04:00
*/
function paused_plugins_notice () {
if ( 'plugins.php' === $GLOBALS [ 'pagenow' ] ) {
return ;
}
if ( ! current_user_can ( 'resume_plugins' ) ) {
return ;
}
if ( ! isset ( $GLOBALS [ '_paused_plugins' ] ) || empty ( $GLOBALS [ '_paused_plugins' ] ) ) {
return ;
}
printf (
'<div class="notice notice-error"><p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p></div>' ,
__ ( 'One or more plugins failed to load properly.' ),
__ ( 'You can find more details and make changes on the Plugins screen.' ),
esc_url ( admin_url ( 'plugins.php?plugin_status=paused' ) ),
__ ( 'Go to the Plugins screen' )
);
}
2021-06-29 20:21:58 -04:00
/**
* Renders an admin notice when a plugin was deactivated during an update .
*
* Displays an admin notice in case a plugin has been deactivated during an
* upgrade due to incompatibility with the current version of WordPress .
*
* @ since 5.8 . 0
* @ access private
*
* @ global string $pagenow
* @ global string $wp_version
*/
function deactivated_plugins_notice () {
if ( 'plugins.php' === $GLOBALS [ 'pagenow' ] ) {
return ;
}
if ( ! current_user_can ( 'activate_plugins' ) ) {
return ;
}
$blog_deactivated_plugins = get_option ( 'wp_force_deactivated_plugins' );
$site_deactivated_plugins = array ();
if ( false === $blog_deactivated_plugins ) {
// Option not in database, add an empty array to avoid extra DB queries on subsequent loads.
update_option ( 'wp_force_deactivated_plugins' , array () );
}
if ( is_multisite () ) {
$site_deactivated_plugins = get_site_option ( 'wp_force_deactivated_plugins' );
if ( false === $site_deactivated_plugins ) {
// Option not in database, add an empty array to avoid extra DB queries on subsequent loads.
update_site_option ( 'wp_force_deactivated_plugins' , array () );
}
}
if ( empty ( $blog_deactivated_plugins ) && empty ( $site_deactivated_plugins ) ) {
// No deactivated plugins.
return ;
}
$deactivated_plugins = array_merge ( $blog_deactivated_plugins , $site_deactivated_plugins );
foreach ( $deactivated_plugins as $plugin ) {
if ( ! empty ( $plugin [ 'version_compatible' ] ) && ! empty ( $plugin [ 'version_deactivated' ] ) ) {
$explanation = sprintf (
/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version, 4: Compatible plugin version */
__ ( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s, please upgrade to %1$s %4$s or later.' ),
$plugin [ 'plugin_name' ],
$plugin [ 'version_deactivated' ],
$GLOBALS [ 'wp_version' ],
$plugin [ 'version_compatible' ]
);
} else {
$explanation = sprintf (
/* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version */
__ ( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s.' ),
$plugin [ 'plugin_name' ],
! empty ( $plugin [ 'version_deactivated' ] ) ? $plugin [ 'version_deactivated' ] : '' ,
$GLOBALS [ 'wp_version' ],
$plugin [ 'version_compatible' ]
);
}
printf (
'<div class="notice notice-warning"><p><strong>%s</strong><br>%s</p><p><a href="%s">%s</a></p></div>' ,
sprintf (
/* translators: %s: Name of deactivated plugin */
__ ( '%s plugin deactivated during WordPress upgrade.' ),
$plugin [ 'plugin_name' ]
),
$explanation ,
esc_url ( admin_url ( 'plugins.php?plugin_status=inactive' ) ),
__ ( 'Go to the Plugins screen' )
);
}
// Empty the options.
update_option ( 'wp_force_deactivated_plugins' , array () );
if ( is_multisite () ) {
update_site_option ( 'wp_force_deactivated_plugins' , array () );
}
}