Changeset 59488 for trunk/src/wp-admin/includes/plugin.php
- Timestamp:
- 12/05/2024 12:11:27 PM (16 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-admin/includes/plugin.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/plugin.php
r59479 r59488 6 6 * @subpackage Administration 7 7 */ 8 9 /** 10 * Parses the plugin contents to retrieve plugin's metadata. 11 * 12 * All plugin headers must be on their own line. Plugin description must not have 13 * any newlines, otherwise only parts of the description will be displayed. 14 * The below is formatted for printing. 15 * 16 * /* 17 * Plugin Name: Name of the plugin. 18 * Plugin URI: The home page of the plugin. 19 * Description: Plugin description. 20 * Author: Plugin author's name. 21 * Author URI: Link to the author's website. 22 * Version: Plugin version. 23 * Text Domain: Optional. Unique identifier, should be same as the one used in 24 * load_plugin_textdomain(). 25 * Domain Path: Optional. Only useful if the translations are located in a 26 * folder above the plugin's base path. For example, if .mo files are 27 * located in the locale folder then Domain Path will be "/locale/" and 28 * must have the first slash. Defaults to the base folder the plugin is 29 * located in. 30 * Network: Optional. Specify "Network: true" to require that a plugin is activated 31 * across all sites in an installation. This will prevent a plugin from being 32 * activated on a single site when Multisite is enabled. 33 * Requires at least: Optional. Specify the minimum required WordPress version. 34 * Requires PHP: Optional. Specify the minimum required PHP version. 35 * * / # Remove the space to close comment. 36 * 37 * The first 8 KB of the file will be pulled in and if the plugin data is not 38 * within that first 8 KB, then the plugin author should correct their plugin 39 * and move the plugin data headers to the top. 40 * 41 * The plugin file is assumed to have permissions to allow for scripts to read 42 * the file. This is not checked however and the file is only opened for 43 * reading. 44 * 45 * @since 1.5.0 46 * @since 5.3.0 Added support for `Requires at least` and `Requires PHP` headers. 47 * @since 5.8.0 Added support for `Update URI` header. 48 * @since 6.5.0 Added support for `Requires Plugins` header. 49 * 50 * @param string $plugin_file Absolute path to the main plugin file. 51 * @param bool $markup Optional. If the returned data should have HTML markup applied. 52 * Default true. 53 * @param bool $translate Optional. If the returned data should be translated. Default true. 54 * @return array { 55 * Plugin data. Values will be empty if not supplied by the plugin. 56 * 57 * @type string $Name Name of the plugin. Should be unique. 58 * @type string $PluginURI Plugin URI. 59 * @type string $Version Plugin version. 60 * @type string $Description Plugin description. 61 * @type string $Author Plugin author's name. 62 * @type string $AuthorURI Plugin author's website address (if set). 63 * @type string $TextDomain Plugin textdomain. 64 * @type string $DomainPath Plugin's relative directory path to .mo files. 65 * @type bool $Network Whether the plugin can only be activated network-wide. 66 * @type string $RequiresWP Minimum required version of WordPress. 67 * @type string $RequiresPHP Minimum required version of PHP. 68 * @type string $UpdateURI ID of the plugin for update purposes, should be a URI. 69 * @type string $RequiresPlugins Comma separated list of dot org plugin slugs. 70 * @type string $Title Title of the plugin and link to the plugin's site (if set). 71 * @type string $AuthorName Plugin author's name. 72 * } 73 */ 74 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { 75 76 $default_headers = array( 77 'Name' => 'Plugin Name', 78 'PluginURI' => 'Plugin URI', 79 'Version' => 'Version', 80 'Description' => 'Description', 81 'Author' => 'Author', 82 'AuthorURI' => 'Author URI', 83 'TextDomain' => 'Text Domain', 84 'DomainPath' => 'Domain Path', 85 'Network' => 'Network', 86 'RequiresWP' => 'Requires at least', 87 'RequiresPHP' => 'Requires PHP', 88 'UpdateURI' => 'Update URI', 89 'RequiresPlugins' => 'Requires Plugins', 90 // Site Wide Only is deprecated in favor of Network. 91 '_sitewide' => 'Site Wide Only', 92 ); 93 94 $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' ); 95 96 // Site Wide Only is the old header for Network. 97 if ( ! $plugin_data['Network'] && $plugin_data['_sitewide'] ) { 98 /* translators: 1: Site Wide Only: true, 2: Network: true */ 99 _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>' ) ); 100 $plugin_data['Network'] = $plugin_data['_sitewide']; 101 } 102 $plugin_data['Network'] = ( 'true' === strtolower( $plugin_data['Network'] ) ); 103 unset( $plugin_data['_sitewide'] ); 104 105 // If no text domain is defined fall back to the plugin slug. 106 if ( ! $plugin_data['TextDomain'] ) { 107 $plugin_slug = dirname( plugin_basename( $plugin_file ) ); 108 if ( '.' !== $plugin_slug && ! str_contains( $plugin_slug, '/' ) ) { 109 $plugin_data['TextDomain'] = $plugin_slug; 110 } 111 } 112 113 if ( $markup || $translate ) { 114 $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate ); 115 } else { 116 $plugin_data['Title'] = $plugin_data['Name']; 117 $plugin_data['AuthorName'] = $plugin_data['Author']; 118 } 119 120 return $plugin_data; 121 } 122 123 /** 124 * Sanitizes plugin data, optionally adds markup, optionally translates. 125 * 126 * @since 2.7.0 127 * 128 * @see get_plugin_data() 129 * 130 * @access private 131 * 132 * @param string $plugin_file Path to the main plugin file. 133 * @param array $plugin_data An array of plugin data. See get_plugin_data(). 134 * @param bool $markup Optional. If the returned data should have HTML markup applied. 135 * Default true. 136 * @param bool $translate Optional. If the returned data should be translated. Default true. 137 * @return array Plugin data. Values will be empty if not supplied by the plugin. 138 * See get_plugin_data() for the list of possible values. 139 */ 140 function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) { 141 142 // Sanitize the plugin filename to a WP_PLUGIN_DIR relative path. 143 $plugin_file = plugin_basename( $plugin_file ); 144 145 // Translate fields. 146 if ( $translate ) { 147 $textdomain = $plugin_data['TextDomain']; 148 if ( $textdomain ) { 149 if ( ! is_textdomain_loaded( $textdomain ) ) { 150 if ( $plugin_data['DomainPath'] ) { 151 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) . $plugin_data['DomainPath'] ); 152 } else { 153 load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) ); 154 } 155 } 156 } elseif ( 'hello.php' === basename( $plugin_file ) ) { 157 $textdomain = 'default'; 158 } 159 if ( $textdomain ) { 160 foreach ( array( 'Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field ) { 161 if ( ! empty( $plugin_data[ $field ] ) ) { 162 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain 163 $plugin_data[ $field ] = translate( $plugin_data[ $field ], $textdomain ); 164 } 165 } 166 } 167 } 168 169 // Sanitize fields. 170 $allowed_tags_in_links = array( 171 'abbr' => array( 'title' => true ), 172 'acronym' => array( 'title' => true ), 173 'code' => true, 174 'em' => true, 175 'strong' => true, 176 ); 177 178 $allowed_tags = $allowed_tags_in_links; 179 $allowed_tags['a'] = array( 180 'href' => true, 181 'title' => true, 182 ); 183 184 /* 185 * Name is marked up inside <a> tags. Don't allow these. 186 * Author is too, but some plugins have used <a> here (omitting Author URI). 187 */ 188 $plugin_data['Name'] = wp_kses( $plugin_data['Name'], $allowed_tags_in_links ); 189 $plugin_data['Author'] = wp_kses( $plugin_data['Author'], $allowed_tags ); 190 191 $plugin_data['Description'] = wp_kses( $plugin_data['Description'], $allowed_tags ); 192 $plugin_data['Version'] = wp_kses( $plugin_data['Version'], $allowed_tags ); 193 194 $plugin_data['PluginURI'] = esc_url( $plugin_data['PluginURI'] ); 195 $plugin_data['AuthorURI'] = esc_url( $plugin_data['AuthorURI'] ); 196 197 $plugin_data['Title'] = $plugin_data['Name']; 198 $plugin_data['AuthorName'] = $plugin_data['Author']; 199 200 // Apply markup. 201 if ( $markup ) { 202 if ( $plugin_data['PluginURI'] && $plugin_data['Name'] ) { 203 $plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '">' . $plugin_data['Name'] . '</a>'; 204 } 205 206 if ( $plugin_data['AuthorURI'] && $plugin_data['Author'] ) { 207 $plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '">' . $plugin_data['Author'] . '</a>'; 208 } 209 210 $plugin_data['Description'] = wptexturize( $plugin_data['Description'] ); 211 212 if ( $plugin_data['Author'] ) { 213 $plugin_data['Description'] .= sprintf( 214 /* translators: %s: Plugin author. */ 215 ' <cite>' . __( 'By %s.' ) . '</cite>', 216 $plugin_data['Author'] 217 ); 218 } 219 } 220 221 return $plugin_data; 222 } 8 223 9 224 /** … … 303 518 304 519 return $dropins; 520 } 521 522 /** 523 * Determines whether a plugin is active. 524 * 525 * Only plugins installed in the plugins/ folder can be active. 526 * 527 * Plugins in the mu-plugins/ folder can't be "activated," so this function will 528 * return false for those plugins. 529 * 530 * For more information on this and similar theme functions, check out 531 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 532 * Conditional Tags} article in the Theme Developer Handbook. 533 * 534 * @since 2.5.0 535 * 536 * @param string $plugin Path to the plugin file relative to the plugins directory. 537 * @return bool True, if in the active plugins list. False, not in the list. 538 */ 539 function is_plugin_active( $plugin ) { 540 return in_array( $plugin, (array) get_option( 'active_plugins', array() ), true ) || is_plugin_active_for_network( $plugin ); 541 } 542 543 /** 544 * Determines whether the plugin is inactive. 545 * 546 * Reverse of is_plugin_active(). Used as a callback. 547 * 548 * For more information on this and similar theme functions, check out 549 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 550 * Conditional Tags} article in the Theme Developer Handbook. 551 * 552 * @since 3.1.0 553 * 554 * @see is_plugin_active() 555 * 556 * @param string $plugin Path to the plugin file relative to the plugins directory. 557 * @return bool True if inactive. False if active. 558 */ 559 function is_plugin_inactive( $plugin ) { 560 return ! is_plugin_active( $plugin ); 561 } 562 563 /** 564 * Determines whether the plugin is active for the entire network. 565 * 566 * Only plugins installed in the plugins/ folder can be active. 567 * 568 * Plugins in the mu-plugins/ folder can't be "activated," so this function will 569 * return false for those plugins. 570 * 571 * For more information on this and similar theme functions, check out 572 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 573 * Conditional Tags} article in the Theme Developer Handbook. 574 * 575 * @since 3.0.0 576 * 577 * @param string $plugin Path to the plugin file relative to the plugins directory. 578 * @return bool True if active for the network, otherwise false. 579 */ 580 function is_plugin_active_for_network( $plugin ) { 581 if ( ! is_multisite() ) { 582 return false; 583 } 584 585 $plugins = get_site_option( 'active_sitewide_plugins' ); 586 if ( isset( $plugins[ $plugin ] ) ) { 587 return true; 588 } 589 590 return false; 591 } 592 593 /** 594 * Checks for "Network: true" in the plugin header to see if this should 595 * be activated only as a network wide plugin. The plugin would also work 596 * when Multisite is not enabled. 597 * 598 * Checks for "Site Wide Only: true" for backward compatibility. 599 * 600 * @since 3.0.0 601 * 602 * @param string $plugin Path to the plugin file relative to the plugins directory. 603 * @return bool True if plugin is network only, false otherwise. 604 */ 605 function is_network_only_plugin( $plugin ) { 606 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); 607 if ( $plugin_data ) { 608 return $plugin_data['Network']; 609 } 610 return false; 305 611 } 306 612
Note: See TracChangeset
for help on using the changeset viewer.