[ Index ]

PHP Cross Reference of Wordpress 2.9.1

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 291 2009-10-21 05:46:08Z 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          $this->entries = array_merge($this->entries, $other->entries);
 108      }
 109  }
 110  
 111  class Gettext_Translations extends Translations {
 112      /**
 113       * The gettext implmentation of select_plural_form.
 114       *
 115       * It lives in this class, because there are more than one descendand, which will use it and
 116       * they can't share it effectively.
 117       *
 118       */
 119  	function gettext_select_plural_form($count) {
 120          if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) {
 121              list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
 122              $this->_nplurals = $nplurals;
 123              $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
 124          }
 125          return call_user_func($this->_gettext_select_plural_form, $count);
 126      }
 127      
 128  	function nplurals_and_expression_from_header($header) {
 129          if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
 130              $nplurals = (int)$matches[1];
 131              $expression = trim($this->parenthesize_plural_exression($matches[2]));
 132              return array($nplurals, $expression);
 133          } else {
 134              return array(2, 'n != 1');
 135          }
 136      }
 137  
 138      /**
 139       * Makes a function, which will return the right translation index, according to the
 140       * plural forms header
 141       */
 142  	function make_plural_form_function($nplurals, $expression) {
 143          $expression = str_replace('n', '$n', $expression);
 144          $func_body = "
 145              \$index = (int)($expression);
 146              return (\$index < $nplurals)? \$index : $nplurals - 1;";
 147          return create_function('$n', $func_body);
 148      }
 149  
 150      /**
 151       * Adds parantheses to the inner parts of ternary operators in
 152       * plural expressions, because PHP evaluates ternary oerators from left to right
 153       * 
 154       * @param string $expression the expression without parentheses
 155       * @return string the expression with parentheses added
 156       */
 157  	function parenthesize_plural_exression($expression) {
 158          $expression .= ';';
 159          $res = '';
 160          $depth = 0;
 161          for ($i = 0; $i < strlen($expression); ++$i) {
 162              $char = $expression[$i];
 163              switch ($char) {
 164                  case '?':
 165                      $res .= ' ? (';
 166                      $depth++;
 167                      break;
 168                  case ':':
 169                      $res .= ') : (';
 170                      break;
 171                  case ';':
 172                      $res .= str_repeat(')', $depth) . ';';
 173                      $depth= 0;
 174                      break;
 175                  default:
 176                      $res .= $char;
 177              }
 178          }
 179          return rtrim($res, ';');
 180      }
 181      
 182  	function make_headers($translation) {
 183          $headers = array();
 184          // sometimes \ns are used instead of real new lines
 185          $translation = str_replace('\n', "\n", $translation);
 186          $lines = explode("\n", $translation);
 187          foreach($lines as $line) {
 188              $parts = explode(':', $line, 2);
 189              if (!isset($parts[1])) continue;
 190              $headers[trim($parts[0])] = trim($parts[1]);
 191          }
 192          return $headers;
 193      }
 194      
 195  	function set_header($header, $value) {
 196          parent::set_header($header, $value);
 197          if ('Plural-Forms' == $header) {
 198              list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
 199              $this->_nplurals = $nplurals;
 200              $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
 201          }
 202      }
 203  }
 204  endif;
 205  
 206  if ( !class_exists( 'NOOP_Translations' ) ):
 207  /**
 208   * Provides the same interface as Translations, but doesn't do anything
 209   */
 210  class NOOP_Translations {
 211      var $entries = array();
 212      var $headers = array();
 213      
 214  	function add_entry($entry) {
 215          return true;
 216      }
 217  
 218  	function set_header($header, $value) {
 219      }
 220  
 221  	function set_headers(&$headers) {
 222      }
 223  
 224  	function get_header($header) {
 225          return false;
 226      }
 227  
 228  	function translate_entry(&$entry) {
 229          return false;
 230      }
 231  
 232  	function translate($singular, $context=null) {
 233          return $singular;
 234      }
 235  
 236  	function select_plural_form($count) {
 237          return 1 == $count? 0 : 1;
 238      }
 239  
 240  	function get_plural_forms_count() {
 241          return 2;
 242      }
 243  
 244  	function translate_plural($singular, $plural, $count, $context = null) {
 245              return 1 == $count? $singular : $plural;
 246      }
 247  
 248  	function merge_with(&$other) {
 249      }
 250  }
 251  endif;


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7