diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/l10n.php --- a/wp/wp-includes/l10n.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/l10n.php Tue Dec 15 13:49:49 2020 +0100 @@ -22,8 +22,8 @@ * * @since 1.5.0 * - * @global string $locale - * @global string $wp_local_package + * @global string $locale The current locale. + * @global string $wp_local_package Locale code of the package. * * @return string The locale of the blog or from the {@see 'locale'} hook. */ @@ -53,16 +53,21 @@ // If multisite, check options. if ( is_multisite() ) { // Don't check blog option when installing. - if ( wp_installing() || ( false === $ms_locale = get_option( 'WPLANG' ) ) ) { + if ( wp_installing() ) { $ms_locale = get_site_option( 'WPLANG' ); + } else { + $ms_locale = get_option( 'WPLANG' ); + if ( false === $ms_locale ) { + $ms_locale = get_site_option( 'WPLANG' ); + } } - if ( $ms_locale !== false ) { + if ( false !== $ms_locale ) { $locale = $ms_locale; } } else { $db_locale = get_option( 'WPLANG' ); - if ( $db_locale !== false ) { + if ( false !== $db_locale ) { $locale = $db_locale; } } @@ -121,9 +126,10 @@ * * @since 5.0.0 * - * @param string|null The locale to return and short-circuit, or null as default. + * @param string|null $locale The locale to return and short-circuit. Default null. */ $determined_locale = apply_filters( 'pre_determine_locale', null ); + if ( ! empty( $determined_locale ) && is_string( $determined_locale ) ) { return $determined_locale; } @@ -160,11 +166,12 @@ * *Note:* Don't use translate() directly, use __() or related functions. * * @since 2.2.0 + * @since 5.5.0 Introduced gettext-{$domain} filter. * * @param string $text Text to translate. * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. * Default 'default'. - * @return string Translated text + * @return string Translated text. */ function translate( $text, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); @@ -175,11 +182,26 @@ * * @since 2.0.11 * - * @param string $translation Translated text. - * @param string $text Text to translate. - * @param string $domain Text domain. Unique identifier for retrieving translated strings. + * @param string $translation Translated text. + * @param string $text Text to translate. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. */ - return apply_filters( 'gettext', $translation, $text, $domain ); + $translation = apply_filters( 'gettext', $translation, $text, $domain ); + + /** + * Filters text with its translation for a domain. + * + * The dynamic portion of the hook, `$domain`, refers to the text domain. + * + * @since 5.5.0 + * + * @param string $translation Translated text. + * @param string $text Text to translate. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + */ + $translation = apply_filters( "gettext_{$domain}", $translation, $text, $domain ); + + return $translation; } /** @@ -205,12 +227,12 @@ /** * Retrieve the translation of $text in the context defined in $context. * - * If there is no translation, or the text domain isn't loaded the original - * text is returned. + * If there is no translation, or the text domain isn't loaded, the original text is returned. * * *Note:* Don't use translate_with_gettext_context() directly, use _x() or related functions. * * @since 2.8.0 + * @since 5.5.0 Introduced gettext_with_context-{$domain} filter. * * @param string $text Text to translate. * @param string $context Context information for the translators. @@ -221,17 +243,34 @@ function translate_with_gettext_context( $text, $context, $domain = 'default' ) { $translations = get_translations_for_domain( $domain ); $translation = $translations->translate( $text, $context ); + /** * Filters text with its translation based on context information. * * @since 2.8.0 * - * @param string $translation Translated text. - * @param string $text Text to translate. - * @param string $context Context information for the translators. - * @param string $domain Text domain. Unique identifier for retrieving translated strings. + * @param string $translation Translated text. + * @param string $text Text to translate. + * @param string $context Context information for the translators. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. */ - return apply_filters( 'gettext_with_context', $translation, $text, $context, $domain ); + $translation = apply_filters( 'gettext_with_context', $translation, $text, $context, $domain ); + + /** + * Filters text with its translation based on context information for a domain. + * + * The dynamic portion of the hook, `$domain`, refers to the text domain. + * + * @since 5.5.0 + * + * @param string $translation Translated text. + * @param string $text Text to translate. + * @param string $context Context information for the translators. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + */ + $translation = apply_filters( "gettext_with_context_{$domain}", $translation, $text, $context, $domain ); + + return $translation; } /** @@ -277,7 +316,7 @@ * @param string $text Text to translate. * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. * Default 'default'. - * @return string Translated text + * @return string Translated text. */ function esc_html__( $text, $domain = 'default' ) { return esc_html( translate( $text, $domain ) ); @@ -299,6 +338,11 @@ /** * Display translated text that has been escaped for safe use in an attribute. * + * Encodes `< > & " '` (less than, greater than, ampersand, double quote, single quote). + * Will never double encode entities. + * + * If you need the value for use in PHP, use esc_attr__(). + * * @since 2.8.0 * * @param string $text Text to translate. @@ -312,6 +356,11 @@ /** * Display translated text that has been escaped for safe use in HTML output. * + * If there is no translation, or the text domain isn't loaded, the original text + * is escaped and displayed. + * + * If you need the value for use in PHP, use esc_html__(). + * * @since 2.8.0 * * @param string $text Text to translate. @@ -361,13 +410,16 @@ /** * Translate string with gettext context, and escapes it for safe use in an attribute. * + * If there is no translation, or the text domain isn't loaded, the original text + * is escaped and returned. + * * @since 2.8.0 * * @param string $text Text to translate. * @param string $context Context information for the translators. * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. * Default 'default'. - * @return string Translated text + * @return string Translated text. */ function esc_attr_x( $text, $context, $domain = 'default' ) { return esc_attr( translate_with_gettext_context( $text, $context, $domain ) ); @@ -376,6 +428,9 @@ /** * Translate string with gettext context, and escapes it for safe use in HTML output. * + * If there is no translation, or the text domain isn't loaded, the original text + * is escaped and returned. + * * @since 2.9.0 * * @param string $text Text to translate. @@ -399,6 +454,7 @@ * printf( _n( '%s person', '%s people', $count, 'text-domain' ), number_format_i18n( $count ) ); * * @since 2.8.0 + * @since 5.5.0 Introduced ngettext-{$domain} filter. * * @param string $single The text to be used if the number is singular. * @param string $plural The text to be used if the number is plural. @@ -422,7 +478,24 @@ * @param string $number The number to compare against to use either the singular or plural form. * @param string $domain Text domain. Unique identifier for retrieving translated strings. */ - return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); + $translation = apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); + + /** + * Filters the singular or plural form of a string for a domain. + * + * The dynamic portion of the hook, `$domain`, refers to the text domain. + * + * @since 5.5.0 + * + * @param string $translation Translated text. + * @param string $single The text to be used if the number is singular. + * @param string $plural The text to be used if the number is plural. + * @param string $number The number to compare against to use either the singular or plural form. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + */ + $translation = apply_filters( "ngettext_{$domain}", $translation, $single, $plural, $number, $domain ); + + return $translation; } /** @@ -439,6 +512,7 @@ * printf( _nx( '%s group', '%s groups', $animals, 'group of animals', 'text-domain' ), number_format_i18n( $animals ) ); * * @since 2.8.0 + * @since 5.5.0 Introduced ngettext_with_context-{$domain} filter. * * @param string $single The text to be used if the number is singular. * @param string $plural The text to be used if the number is plural. @@ -464,7 +538,25 @@ * @param string $context Context information for the translators. * @param string $domain Text domain. Unique identifier for retrieving translated strings. */ - return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); + $translation = apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); + + /** + * Filters the singular or plural form of a string with gettext context for a domain. + * + * The dynamic portion of the hook, `$domain`, refers to the text domain. + * + * @since 5.5.0 + * + * @param string $translation Translated text. + * @param string $single The text to be used if the number is singular. + * @param string $plural The text to be used if the number is plural. + * @param string $number The number to compare against to use either the singular or plural form. + * @param string $context Context information for the translators. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + */ + $translation = apply_filters( "ngettext_with_context_{$domain}", $translation, $single, $plural, $number, $context, $domain ); + + return $translation; } /** @@ -620,7 +712,7 @@ */ $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile ); - if ( true == $plugin_override ) { + if ( true === (bool) $plugin_override ) { unset( $l10n_unloaded[ $domain ] ); return true; @@ -906,8 +998,7 @@ * @param string $handle Name of the script to register a translation domain to. * @param string $domain Optional. Text domain. Default 'default'. * @param string $path Optional. The full file path to the directory containing translation files. - * - * @return false|string False if the script textdomain could not be loaded, the translated strings + * @return string|false False if the script textdomain could not be loaded, the translated strings * in JSON encoding otherwise. */ function load_script_textdomain( $handle, $domain = 'default', $path = null ) { @@ -921,7 +1012,7 @@ $locale = determine_locale(); // If a path was given and the handle file exists simply return it. - $file_base = $domain === 'default' ? $locale : $domain . '-' . $locale; + $file_base = 'default' === $domain ? $locale : $domain . '-' . $locale; $handle_filename = $file_base . '-' . $handle . '.json'; if ( $path ) { @@ -943,20 +1034,43 @@ $src_url = wp_parse_url( $src ); $content_url = wp_parse_url( content_url() ); + $plugins_url = wp_parse_url( plugins_url() ); $site_url = wp_parse_url( site_url() ); // If the host is the same or it's a relative URL. if ( - strpos( $src_url['path'], $content_url['path'] ) === 0 && + ( ! isset( $content_url['path'] ) || strpos( $src_url['path'], $content_url['path'] ) === 0 ) && ( ! isset( $src_url['host'] ) || $src_url['host'] === $content_url['host'] ) ) { // Make the src relative the specific plugin or theme. - $relative = trim( substr( $src_url['path'], strlen( $content_url['path'] ) ), '/' ); + if ( isset( $content_url['path'] ) ) { + $relative = substr( $src_url['path'], strlen( $content_url['path'] ) ); + } else { + $relative = $src_url['path']; + } + $relative = trim( $relative, '/' ); $relative = explode( '/', $relative ); $languages_path = WP_LANG_DIR . '/' . $relative[0]; - $relative = array_slice( $relative, 2 ); + $relative = array_slice( $relative, 2 ); // Remove plugins/ or themes/. + $relative = implode( '/', $relative ); + } elseif ( + ( ! isset( $plugins_url['path'] ) || strpos( $src_url['path'], $plugins_url['path'] ) === 0 ) && + ( ! isset( $src_url['host'] ) || $src_url['host'] === $plugins_url['host'] ) + ) { + // Make the src relative the specific plugin. + if ( isset( $plugins_url['path'] ) ) { + $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) ); + } else { + $relative = $src_url['path']; + } + $relative = trim( $relative, '/' ); + $relative = explode( '/', $relative ); + + $languages_path = WP_LANG_DIR . '/plugins'; + + $relative = array_slice( $relative, 1 ); // Remove . $relative = implode( '/', $relative ); } elseif ( ! isset( $src_url['host'] ) || $src_url['host'] === $site_url['host'] ) { if ( ! isset( $site_url['path'] ) ) { @@ -973,8 +1087,8 @@ * * @since 5.0.2 * - * @param string $relative The relative path of the script. False if it could not be determined. - * @param string $src The full source url of the script. + * @param string|false $relative The relative path of the script. False if it could not be determined. + * @param string $src The full source URL of the script. */ $relative = apply_filters( 'load_script_textdomain_relative_path', $relative, $src ); @@ -1025,10 +1139,10 @@ * * @since 5.0.2 * - * @param string|false $translations JSON-encoded translation data. Default null. - * @param string|false $file Path to the translation file to load. False if there isn't one. - * @param string $handle Name of the script to register a translation domain to. - * @param string $domain The text domain. + * @param string|false|null $translations JSON-encoded translation data. Default null. + * @param string|false $file Path to the translation file to load. False if there isn't one. + * @param string $handle Name of the script to register a translation domain to. + * @param string $domain The text domain. */ $translations = apply_filters( 'pre_load_script_translations', null, $file, $handle, $domain ); @@ -1109,7 +1223,6 @@ * @access private * * @see _load_textdomain_just_in_time() - * @staticvar array $available_translations * * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @param bool $reset Whether to reset the internal cache. Used by the switch to locale functionality. @@ -1138,7 +1251,6 @@ * @access private * * @see _get_path_to_translation() - * @staticvar array $cached_mofiles * * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @return string|false The path to the translation file or false if no translation file was found. @@ -1166,12 +1278,12 @@ $mofile = "{$domain}-{$locale}.mo"; $path = WP_LANG_DIR . '/plugins/' . $mofile; - if ( in_array( $path, $cached_mofiles ) ) { + if ( in_array( $path, $cached_mofiles, true ) ) { return $path; } $path = WP_LANG_DIR . '/themes/' . $mofile; - if ( in_array( $path, $cached_mofiles ) ) { + if ( in_array( $path, $cached_mofiles, true ) ) { return $path; } @@ -1186,7 +1298,6 @@ * @since 2.8.0 * * @global MO[] $l10n - * @staticvar NOOP_Translations $noop_translations * * @param string $domain Text domain. Unique identifier for retrieving translated strings. * @return Translations|NOOP_Translations A Translations instance. @@ -1254,7 +1365,7 @@ * * @param string $dir A directory to search for language files. * Default WP_LANG_DIR. - * @return array An array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names. + * @return string[] An array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names. */ function get_available_languages( $dir = null ) { $languages = array(); @@ -1275,8 +1386,8 @@ * * @since 4.7.0 * - * @param array $languages An array of available language codes. - * @param string $dir The directory where the language files were found. + * @param string[] $languages An array of available language codes. + * @param string $dir The directory where the language files were found. */ return apply_filters( 'get_available_languages', $languages, $dir ); } @@ -1293,7 +1404,7 @@ * @return array Array of language data. */ function wp_get_installed_translations( $type ) { - if ( $type !== 'themes' && $type !== 'plugins' && $type !== 'core' ) { + if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) { return array(); } @@ -1324,7 +1435,7 @@ if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?).po/', $file, $match ) ) { continue; } - if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files ) ) { + if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files, true ) ) { continue; } @@ -1343,7 +1454,7 @@ * @since 3.7.0 * * @param string $po_file Path to PO file. - * @return array PO file headers. + * @return string[] Array of PO file header values keyed by header name. */ function wp_get_pomo_file_data( $po_file ) { $headers = get_file_data( @@ -1389,7 +1500,7 @@ * @type bool $show_option_site_default Whether to show an option to fall back to the site's locale. Default false. * @type bool $show_option_en_us Whether to show an option for English (United States). Default true. * } - * @return string HTML content + * @return string HTML dropdown list of languages. */ function wp_dropdown_languages( $args = array() ) { @@ -1420,7 +1531,7 @@ $translations = $parsed_args['translations']; if ( empty( $translations ) ) { - require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); + require_once ABSPATH . 'wp-admin/includes/translation-install.php'; $translations = wp_get_available_translations(); } @@ -1525,7 +1636,7 @@ * * @since 3.0.0 * - * @global WP_Locale $wp_locale + * @global WP_Locale $wp_locale WordPress date and time locale object. * * @return bool Whether locale is RTL. */ @@ -1542,7 +1653,7 @@ * * @since 4.7.0 * - * @global WP_Locale_Switcher $wp_locale_switcher + * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. * * @param string $locale The locale. * @return bool True on success, false on failure. @@ -1559,7 +1670,7 @@ * * @since 4.7.0 * - * @global WP_Locale_Switcher $wp_locale_switcher + * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. * * @return string|false Locale on success, false on error. */ @@ -1575,7 +1686,7 @@ * * @since 4.7.0 * - * @global WP_Locale_Switcher $wp_locale_switcher + * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. * * @return string|false Locale on success, false on error. */ @@ -1591,7 +1702,7 @@ * * @since 4.7.0 * - * @global WP_Locale_Switcher $wp_locale_switcher + * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. * * @return bool True if the locale has been switched, false otherwise. */