Making WordPress.org


Ignore:
Timestamp:
05/04/2021 05:45:15 AM (3 years ago)
Author:
dd32
Message:

Translate: Add a warning that triggers on unexpected malformed sptintf placeholders.

This is to handle the cases where a literal percent word is replaced by % within a printf-string without being escaped, as has happened in learn.wordpress.org strings multiple times.

Included is a translation fixer, which automatically escapes the % to %% when possible, as long as the resulting string passes through the other "placeholders match" checks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-custom-warnings/wporg-gp-custom-warnings.php

    r10739 r10946  
    264264
    265265    /**
     266     * Adds a warning for adding unexpected percent signs in a sprintf-like string.
     267     *
     268     * This is to catch translations for originals like this:
     269     *  - Original: `<a href="%s">100 percent</a>`
     270     *  - Submitted translation: `<a href="%s">100%</a>`
     271     *  - Proper translation: `<a href="%s">100%%</a>`
     272     *
     273     * @param string $original    The original string.
     274     * @param string $translation The translated string.
     275     */
     276    public function warning_unexpected_sprintf_token( $original, $translation ) {
     277        $unexpected_tokens = [];
     278        $is_sprintf        = preg_match( '!%((\d+\$(?:\d+)?)?[bcdefgosux])!i', $original );
     279
     280        // Find any percents that are not valid or escaped.
     281        if ( $is_sprintf ) {
     282            // Negative/Positive lookahead not used to allow the warning to include the context around the % sign.
     283            preg_match_all( '/(?P<context>[^\s%]*)%((\d+\$(?:\d+)?)?(?P<char>.))/i', $translation, $m );
     284
     285            foreach ( $m['char'] as $i => $char ) {
     286                // % is included for escaped %%.
     287                if ( false === strpos( 'bcdefgosux%', $char ) ) {
     288                    $unexpected_tokens[] = $m[0][ $i ];
     289                }
     290            }
     291        }
     292
     293        if ( $unexpected_tokens ) {
     294            return "The translation contains the following unexpected placeholders: " . implode( ', ', $unexpected_tokens );
     295        }
     296
     297        return true; // All is okay.
     298    }
     299
     300    /**
    266301     * Registers all methods starting with warning_ with GlotPress.
    267302     */
Note: See TracChangeset for help on using the changeset viewer.