SOP.wtf/includes/vendor/pomo/pomo/src/Translations/GettextTranslations.php

163 lines
4.5 KiB
PHP

<?php
/**
* This file is part of the POMO package.
*
* @copyright 2014 POMO
* @license GPL
*/
namespace POMO\Translations;
use POMO\Parser\PluralForms;
/**
* Class for a set of entries for translation and their associated headers.
*/
class GettextTranslations extends Translations implements TranslationsInterface
{
/**
* Number of plural forms.
*
* @var int
*/
public $_nplurals;
/**
* Callback to retrieve the plural form.
*
* @var callable
*/
public $_gettext_select_plural_form;
/**
* The gettext implementation of select_plural_form.
*
* It lives in this class, because there are more than one descendand,
* which will use it and they can't share it effectively.
*
* @param int $count Items count
*
* @return mixed
*/
public function gettext_select_plural_form($count)
{
if (
!isset($this->_gettext_select_plural_form)
|| is_null($this->_gettext_select_plural_form)
) {
list($nplurals, $expression) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
$this->_nplurals = $nplurals;
$this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
}
return call_user_func($this->_gettext_select_plural_form, $count);
}
/**
* @param $header
*
* @return array
*/
public function nplurals_and_expression_from_header($header)
{
if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
$nplurals = (int) $matches[1];
$expression = trim($matches[2]);
return array($nplurals, $expression);
} else {
return array(2, 'n != 1');
}
}
/**
* Makes a function, which will return the right translation index,
* according to the plural forms header.
*
* @param int $nplurals
* @param string $expression
*
* @return callable The right translation index
*/
public function make_plural_form_function($nplurals, $expression)
{
try {
$handler = new PluralForms(rtrim($expression, ';'));
return array($handler, 'get');
} catch (\Exception $e) {
// Fall back to default plural-form function.
return $this->make_plural_form_function(2, 'n != 1');
}
}
/**
* Adds parentheses to the inner parts of ternary operators in
* plural expressions, because PHP evaluates ternary operators
* from left to right.
*
* @param string $expression the expression without parentheses
*
* @return string the expression with parentheses added
*/
public function parenthesize_plural_exression($expression)
{
$expression .= ';';
$res = '';
$depth = 0;
for ($i = 0; $i < strlen($expression); ++$i) {
$char = $expression[$i];
switch ($char) {
case '?':
$res .= ' ? (';
$depth++;
break;
case ':':
$res .= ') : (';
break;
case ';':
$res .= str_repeat(')', $depth) . ';';
$depth = 0;
break;
default:
$res .= $char;
}
}
return rtrim($res, ';');
}
/**
* @param string $translation
*
* @return array
*/
public function make_headers($translation)
{
$headers = array();
// sometimes \ns are used instead of real new lines
$translation = str_replace('\n', "\n", $translation);
$lines = explode("\n", $translation);
foreach ($lines as $line) {
$parts = explode(':', $line, 2);
if (!isset($parts[1])) {
continue;
}
$headers[trim($parts[0])] = trim($parts[1]);
}
return $headers;
}
public function set_header($header, $value)
{
parent::set_header($header, $value);
if ('Plural-Forms' == $header) {
list($nplurals, $expression) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
$this->_nplurals = $nplurals;
$this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
}
}
}