[ PHPXref.com ] [ Generated: Thu Aug 19 03:45:23 2010 ] [ WordPress 3.0.1 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

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


[ Powered by PHPXref - Served by Debian GNU/Linux ]