[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/pomo/ -> translations.php (source)

   1  <?php
   2  /**
   3   * Class for a set of entries for translation and their associated headers
   4   *
   5   * @version $Id: translations.php 718 2012-10-31 00:32:02Z nbachiyski $
   6   * @package pomo
   7   * @subpackage translations
   8   */
   9  
  10  require_once dirname(__FILE__) . '/entry.php';
  11  
  12  if ( !class_exists( 'Translations' ) ):
  13  class Translations {
  14      var $entries = array();
  15      var $headers = array();
  16  
  17      /**
  18       * Add entry to the PO structure
  19       *
  20       * @param object &$entry
  21       * @return bool true on success, false if the entry doesn't have a key
  22       */
  23  	function add_entry($entry) {
  24          if (is_array($entry)) {
  25              $entry = new Translation_Entry($entry);
  26          }
  27          $key = $entry->key();
  28          if (false === $key) return false;
  29          $this->entries[$key] = &$entry;
  30          return true;
  31      }
  32  
  33  	function add_entry_or_merge($entry) {
  34          if (is_array($entry)) {
  35              $entry = new Translation_Entry($entry);
  36          }
  37          $key = $entry->key();
  38          if (false === $key) return false;
  39          if (isset($this->entries[$key]))
  40              $this->entries[$key]->merge_with($entry);
  41          else
  42              $this->entries[$key] = &$entry;
  43          return true;
  44      }
  45  
  46      /**
  47       * Sets $header PO header to $value
  48       *
  49       * If the header already exists, it will be overwritten
  50       *
  51       * TODO: this should be out of this class, it is gettext specific
  52       *
  53       * @param string $header header name, without trailing :
  54       * @param string $value header value, without trailing \n
  55       */
  56  	function set_header($header, $value) {
  57          $this->headers[$header] = $value;
  58      }
  59  
  60  	function set_headers($headers) {
  61          foreach($headers as $header => $value) {
  62              $this->set_header($header, $value);
  63          }
  64      }
  65  
  66  	function get_header($header) {
  67          return isset($this->headers[$header])? $this->headers[$header] : false;
  68      }
  69  
  70  	function translate_entry(&$entry) {
  71          $key = $entry->key();
  72          return isset($this->entries[$key])? $this->entries[$key] : false;
  73      }
  74  
  75  	function translate($singular, $context=null) {
  76          $entry = new Translation_Entry(array('singular' => $singular, 'context' => $context));
  77          $translated = $this->translate_entry($entry);
  78          return ($translated && !empty($translated->translations))? $translated->translations[0] : $singular;
  79      }
  80  
  81      /**
  82       * Given the number of items, returns the 0-based index of the plural form to use
  83       *
  84       * Here, in the base Translations class, the common logic for English is implemented:
  85       *     0 if there is one element, 1 otherwise
  86       *
  87       * This function should be overrided by the sub-classes. For example MO/PO can derive the logic
  88       * from their headers.
  89       *
  90       * @param integer $count number of items
  91       */
  92  	function select_plural_form($count) {
  93          return 1 == $count? 0 : 1;
  94      }
  95  
  96  	function get_plural_forms_count() {
  97          return 2;
  98      }
  99  
 100  	function translate_plural($singular, $plural, $count, $context = null) {
 101          $entry = new Translation_Entry(array('singular' => $singular, 'plural' => $plural, 'context' => $context));
 102          $translated = $this->translate_entry($entry);
 103          $index = $this->select_plural_form($count);
 104          $total_plural_forms = $this->get_plural_forms_count();
 105          if ($translated && 0 <= $index && $index < $total_plural_forms &&
 106                  is_array($translated->translations) &&
 107                  isset($translated->translations[$index]))
 108              return $translated->translations[$index];
 109          else
 110              return 1 == $count? $singular : $plural;
 111      }
 112  
 113      /**
 114       * Merge $other in the current object.
 115       *
 116       * @param Object &$other Another Translation object, whose translations will be merged in this one
 117       * @return void
 118       **/
 119  	function merge_with(&$other) {
 120          foreach( $other->entries as $entry ) {
 121              $this->entries[$entry->key()] = $entry;
 122          }
 123      }
 124  
 125  	function merge_originals_with(&$other) {
 126          foreach( $other->entries as $entry ) {
 127              if ( !isset( $this->entries[$entry->key()] ) )
 128                  $this->entries[$entry->key()] = $entry;
 129              else
 130                  $this->entries[$entry->key()]->merge_with($entry);
 131          }
 132      }
 133  }
 134  
 135  class Gettext_Translations extends Translations {
 136      /**
 137       * The gettext implementation of select_plural_form.
 138       *
 139       * It lives in this class, because there are more than one descendand, which will use it and
 140       * they can't share it effectively.
 141       *
 142       */
 143  	function gettext_select_plural_form($count) {
 144          if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) {
 145              list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
 146              $this->_nplurals = $nplurals;
 147              $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
 148          }
 149          return call_user_func($this->_gettext_select_plural_form, $count);
 150      }
 151  
 152  	function nplurals_and_expression_from_header($header) {
 153          if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
 154              $nplurals = (int)$matches[1];
 155              $expression = trim($this->parenthesize_plural_exression($matches[2]));
 156              return array($nplurals, $expression);
 157          } else {
 158              return array(2, 'n != 1');
 159          }
 160      }
 161  
 162      /**
 163       * Makes a function, which will return the right translation index, according to the
 164       * plural forms header
 165       */
 166  	function make_plural_form_function($nplurals, $expression) {
 167          $expression = str_replace('n', '$n', $expression);
 168          $func_body = "
 169              \$index = (int)($expression);
 170              return (\$index < $nplurals)? \$index : $nplurals - 1;";
 171          return create_function('$n', $func_body);
 172      }
 173  
 174      /**
 175       * Adds parantheses to the inner parts of ternary operators in
 176       * plural expressions, because PHP evaluates ternary oerators from left to right
 177       *
 178       * @param string $expression the expression without parentheses
 179       * @return string the expression with parentheses added
 180       */
 181  	function parenthesize_plural_exression($expression) {
 182          $expression .= ';';
 183          $res = '';
 184          $depth = 0;
 185          for ($i = 0; $i < strlen($expression); ++$i) {
 186              $char = $expression[$i];
 187              switch ($char) {
 188                  case '?':
 189                      $res .= ' ? (';
 190                      $depth++;
 191                      break;
 192                  case ':':
 193                      $res .= ') : (';
 194                      break;
 195                  case ';':
 196                      $res .= str_repeat(')', $depth) . ';';
 197                      $depth= 0;
 198                      break;
 199                  default:
 200                      $res .= $char;
 201              }
 202          }
 203          return rtrim($res, ';');
 204      }
 205  
 206  	function make_headers($translation) {
 207          $headers = array();
 208          // sometimes \ns are used instead of real new lines
 209          $translation = str_replace('\n', "\n", $translation);
 210          $lines = explode("\n", $translation);
 211          foreach($lines as $line) {
 212              $parts = explode(':', $line, 2);
 213              if (!isset($parts[1])) continue;
 214              $headers[trim($parts[0])] = trim($parts[1]);
 215          }
 216          return $headers;
 217      }
 218  
 219  	function set_header($header, $value) {
 220          parent::set_header($header, $value);
 221          if ('Plural-Forms' == $header) {
 222              list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
 223              $this->_nplurals = $nplurals;
 224              $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
 225          }
 226      }
 227  }
 228  endif;
 229  
 230  if ( !class_exists( 'NOOP_Translations' ) ):
 231  /**
 232   * Provides the same interface as Translations, but doesn't do anything
 233   */
 234  class NOOP_Translations {
 235      var $entries = array();
 236      var $headers = array();
 237  
 238  	function add_entry($entry) {
 239          return true;
 240      }
 241  
 242  	function set_header($header, $value) {
 243      }
 244  
 245  	function set_headers($headers) {
 246      }
 247  
 248  	function get_header($header) {
 249          return false;
 250      }
 251  
 252  	function translate_entry(&$entry) {
 253          return false;
 254      }
 255  
 256  	function translate($singular, $context=null) {
 257          return $singular;
 258      }
 259  
 260  	function select_plural_form($count) {
 261          return 1 == $count? 0 : 1;
 262      }
 263  
 264  	function get_plural_forms_count() {
 265          return 2;
 266      }
 267  
 268  	function translate_plural($singular, $plural, $count, $context = null) {
 269              return 1 == $count? $singular : $plural;
 270      }
 271  
 272  	function merge_with(&$other) {
 273      }
 274  }
 275  endif;


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu