Changeset 59461 for trunk/src/wp-admin/includes/plugin.php
- Timestamp:
- 11/26/2024 10:14:07 AM (14 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-admin/includes/plugin.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/plugin.php
r58975 r59461 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 have13 * 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 in24 * load_plugin_textdomain().25 * Domain Path: Optional. Only useful if the translations are located in a26 * folder above the plugin's base path. For example, if .mo files are27 * located in the locale folder then Domain Path will be "/locale/" and28 * must have the first slash. Defaults to the base folder the plugin is29 * located in.30 * Network: Optional. Specify "Network: true" to require that a plugin is activated31 * across all sites in an installation. This will prevent a plugin from being32 * 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 not38 * within that first 8 KB, then the plugin author should correct their plugin39 * and move the plugin data headers to the top.40 *41 * The plugin file is assumed to have permissions to allow for scripts to read42 * the file. This is not checked however and the file is only opened for43 * reading.44 *45 * @since 1.5.046 * @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.0127 *128 * @see get_plugin_data()129 *130 * @access private131 *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.NonSingularStringLiteralDomain163 $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 }223 8 224 9 /**
Note: See TracChangeset
for help on using the changeset viewer.