/** * Converts the special plural syntax to array or ruby style plurals * * @param string $key Message key prefix * @param string $message The plural string * * @return bool|array */ public function unflattenPlural($key, $message) { // Quick escape. if (strpos($message, '{{PLURAL') === false) { return array($key => $message); } /* * Replace all variables with placeholders. Possible source of bugs * if other characters that given below are used. */ $regex = '~\\{[a-zA-Z_-]+}~'; $placeholders = array(); $match = array(); while (preg_match($regex, $message, $match)) { $uniqkey = TranslateUtils::getPlaceholder(); $placeholders[$uniqkey] = $match[0]; $search = preg_quote($match[0], '~'); $message = preg_replace("~{$search}~", $uniqkey, $message); } // Then replace (possible multiple) plural instances into placeholders. $regex = '~\\{\\{PLURAL\\|(.*?)}}~s'; $matches = array(); $match = array(); while (preg_match($regex, $message, $match)) { $uniqkey = TranslateUtils::getPlaceholder(); $matches[$uniqkey] = $match; $message = preg_replace($regex, $uniqkey, $message, 1); } // No plurals, should not happen. if (!count($matches)) { return false; } // The final array of alternative plurals forms. $alts = array(); /* * Then loop trough each plural block and replacing the placeholders * to construct the alternatives. Produces invalid output if there is * multiple plural bocks which don't have the same set of keys. */ $pluralChoice = implode('|', array_keys(self::$pluralWords)); $regex = "~({$pluralChoice})\\s*=\\s*(.+)~s"; foreach ($matches as $ph => $plu) { $forms = explode('|', $plu[1]); foreach ($forms as $form) { if ($form === '') { continue; } $match = array(); if (preg_match($regex, $form, $match)) { $formWord = "{$key}.{$match[1]}"; $value = $match[2]; } else { $formWord = "{$key}.other"; $value = $form; } if (!isset($alts[$formWord])) { $alts[$formWord] = $message; } $string = $alts[$formWord]; $alts[$formWord] = str_replace($ph, $value, $string); } } // Replace other variables. foreach ($alts as &$value) { $value = str_replace(array_keys($placeholders), array_values($placeholders), $value); } if (!isset($alts["{$key}.other"])) { wfWarn("Other not set for key {$key}"); return false; } return $alts; }
/** * Splits the content marked with \<translate> tags into sections, which * are separated with with two or more newlines. Extra whitespace is captured * in the template and not included in the sections. * @param array $sections Array of placeholder => TPSection. * @param string $text Contents of one pair of \<translate> tags. * @return string Template with placeholders for sections, which itself are added to $sections. */ protected function sectionise(&$sections, $text) { $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE; $parts = preg_split('~(\\s*\\n\\n\\s*|\\s*$)~', $text, -1, $flags); $template = ''; foreach ($parts as $_) { if (trim($_) === '') { $template .= $_; } else { $ph = TranslateUtils::getPlaceholder(); $sections[$ph] = $this->shakeSection($_); $template .= $ph; } } return $template; }
protected function splitPlural($text, $forms) { if ($forms === 1) { return $text; } $placeholder = TranslateUtils::getPlaceholder(); # |/| is commonly used in KDE to support inflections $text = str_replace('|/|', $placeholder, $text); $plurals = array(); $match = preg_match_all('/{{PLURAL:GETTEXT\\|(.*)}}/iUs', $text, $plurals); if (!$match) { throw new GettextPluralException("Failed to find plural in: {$text}"); } $splitPlurals = array(); for ($i = 0; $i < $forms; $i++) { # Start with the hole string $pluralForm = $text; # Loop over *each* {{PLURAL}} instance and replace # it with the plural form belonging to this index foreach ($plurals[0] as $index => $definition) { $parsedFormsArray = explode('|', $plurals[1][$index]); if (!isset($parsedFormsArray[$i])) { error_log("Too few plural forms in: {$text}"); $pluralForm = ''; } else { $pluralForm = str_replace($pluralForm, $definition, $parsedFormsArray[$i]); } } $pluralForm = str_replace($placeholder, '|/|', $pluralForm); $splitPlurals[$i] = $pluralForm; } return $splitPlurals; }
/** * Converts the flattened plural into messages * * @param string $message * @return array */ protected function unflattenPlural($message) { $regex = '~\\{\\{PLURAL\\|(.*?)}}~s'; $matches = array(); $match = array(); while (preg_match($regex, $message, $match)) { $uniqkey = TranslateUtils::getPlaceholder(); $matches[$uniqkey] = $match; $message = preg_replace($regex, $uniqkey, $message, 1); } // No plurals, should not happen. if (!count($matches)) { return array(); } // The final array of alternative plurals forms. $alts = array(); /* * Then loop trough each plural block and replacing the placeholders * to construct the alternatives. Produces invalid output if there is * multiple plural bocks which don't have the same set of keys. */ $pluralChoice = implode('|', array_keys(self::$pluralWords)); $regex = "~({$pluralChoice})\\s*=\\s*(.+)~s"; foreach ($matches as $ph => $plu) { $forms = explode('|', $plu[1]); foreach ($forms as $form) { if ($form === '') { continue; } $match = array(); if (!preg_match($regex, $form, $match)) { // No quantity key was provided continue; } $formWord = $match[1]; $value = $match[2]; if (!isset($alts[$formWord])) { $alts[$formWord] = $message; } $string = $alts[$formWord]; $alts[$formWord] = str_replace($ph, $value, $string); } } return $alts; }
public function __construct() { parent::__construct('SearchTranslations'); $this->hl = array(TranslateUtils::getPlaceholder(), TranslateUtils::getPlaceholder()); }