TranslateUtils::getPlaceholder(), ]; // {0} is a common variable format preg_match_all( '/\{\d+\}/', $text, $matches ); foreach ( $matches[0] as $m ) { $replacements[$m] = TranslateUtils::getPlaceholder(); } $text = strtr( $text, $replacements ); $map = array_flip( $replacements ); return [ $text, $map ]; } /** * Reverse of armour. * * @param string $text * @param array $map Map returned by armour. * @return string */ private static function unarmour( $text, array $map ) { return strtr( $text, $map ); } /** * Parses plural markup into a structure form. * * @param string $text * @return array [ string $template, array $instanceMap ] */ public static function parsePluralForms( $text ) { $m = []; $pre = preg_quote( self::PRE, '/' ); $post = preg_quote( self::POST, '/' ); [ $armouredText, $armourMap ] = self::armour( $text ); $ok = preg_match_all( "/$pre(.*)$post/Us", $armouredText, $m ); if ( $ok === false ) { throw new GettextPluralException( "Plural regular expression failed for text: $text" ); } $template = $armouredText; $instanceMap = []; foreach ( $m[0] as $instanceIndex => $instanceText ) { $ph = TranslateUtils::getPlaceholder(); // Using preg_replace instead of str_replace because of the limit parameter $pattern = '/' . preg_quote( $instanceText, '/' ) . '/'; $template = preg_replace( $pattern, $ph, $template, 1 ); $instanceForms = explode( '|', $m[ 1 ][ $instanceIndex ] ); foreach ( $instanceForms as $i => $v ) { $instanceForms[ $i ] = self::unarmour( $v, $armourMap ); } $instanceMap[$ph] = $instanceForms; } $template = self::unarmour( $template, $armourMap ); return [ $template, $instanceMap ]; } /** * Gives fully expanded forms given a template and parsed plural markup instances. * * @param string $template * @param array $instanceMap * @param int $expectedPluralCount * @return string[] */ public static function expandTemplate( $template, array $instanceMap, $expectedPluralCount ) { $formArray = []; for ( $formIndex = 0; $formIndex < $expectedPluralCount; $formIndex++ ) { // Start with the whole string $form = $template; // Loop over each plural markup instance and replace it with the plural form belonging // to the current index foreach ( $instanceMap as $ph => $instanceForms ) { // For missing forms, fall back to empty text. // Extra forms are excluded because $formIndex < $expectedPluralCount $replacement = $instanceForms[ $formIndex ] ?? ''; $form = str_replace( $ph, $replacement, $form ); } $formArray[ $formIndex ] = $form; } return $formArray; } } class_alias( GettextPlural::class, '\MediaWiki\Extensions\Translate\GettextPlural' );