[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/i18n/ -> sfMessageSource_gettext.class.php (source)

   1  <?php
   2  
   3  /**
   4   * sfMessageSource_gettext class file.
   5   *
   6   * This program is free software; you can redistribute it and/or modify
   7   * it under the terms of the BSD License.
   8   *
   9   * Copyright(c) 2004 by Qiang Xue. All rights reserved.
  10   *
  11   * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
  12   * The latest version of PRADO can be obtained from:
  13   * {@link http://prado.sourceforge.net/}
  14   *
  15   * @author     Wei Zhuo <weizhuo[at]gmail[dot]com>
  16   * @version    $Id: sfMessageSource_gettext.class.php 3148 2007-01-04 19:34:28Z fabien $
  17   * @package    symfony
  18   * @subpackage i18n
  19   */
  20  
  21  /**
  22   * sfMessageSource_gettext class.
  23   * 
  24   * Using Gettext MO format as the message source for translation.
  25   * The gettext classes are based on PEAR's gettext MO and PO classes.
  26   * 
  27   * See the MessageSource::factory() method to instantiate this class.
  28   * 
  29   * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
  30   * @version v1.0, last update on Fri Dec 24 16:18:44 EST 2004
  31   * @package System.I18N.core
  32   */
  33  class sfMessageSource_gettext extends sfMessageSource
  34  { 
  35    /**
  36     * Message data filename extension.
  37     * @var string 
  38     */
  39    protected $dataExt = '.mo';
  40  
  41    /**
  42     * PO data filename extension
  43     * @var string 
  44     */
  45    protected $poExt = '.po';
  46  
  47    /**
  48     * Separator between culture name and source.
  49     * @var string 
  50     */
  51    protected $dataSeparator = '.';
  52  
  53    function __construct($source)
  54    {
  55      $this->source = (string)$source;
  56    }
  57  
  58    /**
  59     * Load the messages from a MO file.
  60     *
  61     * @param string MO file.
  62     * @return array of messages.
  63     */
  64    protected function &loadData($filename)
  65    {
  66      $mo = TGettext::factory('MO',$filename);
  67      $mo->load();
  68      $result = $mo->toArray();
  69  
  70      $results = array();
  71      $count = 0;
  72      foreach ($result['strings'] as $source => $target)
  73      {
  74        $results[$source][] = $target;  //target
  75        $results[$source][] = $count++; //id
  76        $results[$source][] = '';       //comments
  77      }
  78  
  79      return $results;
  80    }
  81  
  82    /**
  83     * Determin if the MO file source is valid.
  84     *
  85     * @param string MO file
  86     * @return boolean true if valid, false otherwise. 
  87     */
  88    protected function isValidSource($filename)
  89    {
  90      return is_file($filename);
  91    }
  92  
  93    /**
  94     * Get the MO file for a specific message catalogue and cultural variant.
  95     *
  96     * @param string message catalogue
  97     * @return string full path to the MO file. 
  98     */
  99    protected function getSource($variant)
 100    {
 101      return $this->source.'/'.$variant;
 102    }
 103  
 104    /**
 105     * Get the last modified unix-time for this particular catalogue+variant.
 106     * Just use the file modified time.
 107     *
 108     * @param string catalogue+variant
 109     * @return int last modified in unix-time format.
 110     */
 111    protected function getLastModified($source)
 112    {
 113      return is_file($source) ? filemtime($source) : 0;
 114    }
 115  
 116    /**
 117     * Get all the variants of a particular catalogue.
 118     *
 119     * @param string catalogue name
 120     * @return array list of all variants for this catalogue.
 121     */
 122    protected function getCatalogueList($catalogue)
 123    {
 124      $variants = explode('_', $this->culture);
 125      $source = $catalogue.$this->dataExt;
 126  
 127      $catalogues = array($source);
 128  
 129      $variant = null;
 130  
 131      for ($i = 0, $max = count($variants); $i < $max; $i++)
 132      {
 133        if (strlen($variants[$i]) > 0)
 134        {
 135          $variant .= $variant ? '_'.$variants[$i] : $variants[$i];
 136          $catalogues[] = $catalogue.$this->dataSeparator.$variant.$this->dataExt;
 137        }
 138      }
 139      $byDir = $this->getCatalogueByDir($catalogue);
 140      $catalogues = array_merge($byDir,array_reverse($catalogues));
 141  
 142      return $catalogues;
 143    }
 144  
 145    /**
 146     * Traverse through the directory structure to find the catalogues.
 147     * This should only be called by getCatalogueList()
 148     *
 149     * @param string a particular catalogue.
 150     * @return array a list of catalogues. 
 151     * @see getCatalogueList()
 152     */
 153    protected function getCatalogueByDir($catalogue)
 154    {
 155      $variants = explode('_', $this->culture);
 156      $catalogues = array();
 157  
 158      $variant = null;
 159  
 160      for($i = 0, $max = count($variants); $i < $max; $i++)
 161      {
 162        if (strlen($variants[$i]) > 0)
 163        {
 164          $variant .= $variant ? '_'.$variants[$i] : $variants[$i];
 165          $catalogues[] = $variant.'/'.$catalogue.$this->dataExt;
 166        }
 167      }
 168  
 169      return array_reverse($catalogues);
 170    }
 171  
 172    /**
 173     * Get the variant for a catalogue depending on the current culture.
 174     *
 175     * @param string catalogue
 176     * @return string the variant. 
 177     * @see save()
 178     * @see update()
 179     * @see delete()
 180     */
 181    protected function getVariants($catalogue = 'messages')
 182    {
 183      if (empty($catalogue))
 184      {
 185        $catalogue = 'messages';
 186      }
 187  
 188      foreach ($this->getCatalogueList($catalogue) as $variant)
 189      {
 190        $file = $this->getSource($variant);
 191        $po = $this->getPOFile($file);
 192        if (is_file($file) || is_file($po))
 193        {
 194          return array($variant, $file, $po);
 195        }
 196      }
 197  
 198      return false;
 199    }
 200  
 201    protected function getPOFile($MOFile)
 202    {
 203      return substr($MOFile, 0, strlen($MOFile) - strlen($this->dataExt)).$this->poExt;
 204    }
 205  
 206    /**
 207     * Save the list of untranslated blocks to the translation source. 
 208     * If the translation was not found, you should add those
 209     * strings to the translation source via the <b>append()</b> method.
 210     *
 211     * @param string the catalogue to add to
 212     * @return boolean true if saved successfuly, false otherwise.   
 213     */
 214    function save($catalogue='messages')
 215    {
 216      $messages = $this->untranslated;
 217  
 218      if (count($messages) <= 0)
 219      {
 220        return false;
 221      }
 222  
 223      $variants = $this->getVariants($catalogue);
 224  
 225      if ($variants)
 226      {
 227        list($variant, $MOFile, $POFile) = $variants;
 228      }
 229      else
 230      {
 231        return false;
 232      }
 233  
 234      if (is_writable($MOFile) == false)
 235      {
 236        throw new sfException("Unable to save to file {$MOFile}, file must be writable.");
 237      }
 238      if (is_writable($POFile) == false)
 239      {
 240        throw new sfException("Unable to save to file {$POFile}, file must be writable.");
 241      }
 242  
 243      // set the strings as untranslated.
 244      $strings = array();
 245      foreach ($messages as $message)
 246      {
 247        $strings[$message] = ''; 
 248      }
 249  
 250      // load the PO
 251      $po = TGettext::factory('PO',$POFile);
 252      $po->load();
 253      $result = $po->toArray();
 254  
 255      $existing = count($result['strings']);
 256  
 257      // add to strings to the existing message list
 258      $result['strings'] = array_merge($result['strings'],$strings);
 259  
 260      $new = count($result['strings']);
 261  
 262      if ($new > $existing)
 263      {
 264        // change the date 2004-12-25 12:26
 265        $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
 266  
 267        $po->fromArray($result);
 268        $mo = $po->toMO();
 269        if ($po->save() && $mo->save($MOFile))
 270        {
 271          if (!empty($this->cache))
 272          {
 273            $this->cache->clean($variant, $this->culture);
 274          }
 275  
 276          return true;
 277        }
 278        else
 279        {
 280          return false;
 281        }
 282      }
 283  
 284      return false;
 285    }
 286  
 287    /**
 288     * Delete a particular message from the specified catalogue.
 289     *
 290     * @param string the source message to delete.
 291     * @param string the catalogue to delete from.
 292     * @return boolean true if deleted, false otherwise. 
 293     */
 294    function delete($message, $catalogue = 'messages')
 295    {
 296      $variants = $this->getVariants($catalogue);
 297      if ($variants)
 298      {
 299        list($variant, $MOFile, $POFile) = $variants;
 300      }
 301      else
 302      {
 303        return false;
 304      }
 305  
 306      if (is_writable($MOFile) == false)
 307      {
 308        throw new sfException("Unable to modify file {$MOFile}, file must be writable.");
 309      }
 310  
 311      if (is_writable($POFile) == false)
 312      {
 313        throw new sfException("Unable to modify file {$POFile}, file must be writable.");
 314      }
 315  
 316      $po = TGettext::factory('PO', $POFile);
 317      $po->load();
 318      $result = $po->toArray(); 
 319  
 320      foreach ($result['strings'] as $string => $value)
 321      {
 322        if ($string == $message)
 323        {
 324          $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
 325          unset($result['strings'][$string]);
 326  
 327          $po->fromArray($result);
 328          $mo = $po->toMO();
 329          if ($po->save() && $mo->save($MOFile))
 330          {
 331            if (!empty($this->cache))
 332            {
 333              $this->cache->clean($variant, $this->culture);
 334            }
 335  
 336            return true;
 337          }
 338          else
 339          {
 340            return false;
 341          }
 342        }
 343      }
 344  
 345      return false;
 346    }
 347  
 348    /**
 349     * Update the translation.
 350     *
 351     * @param string the source string.
 352     * @param string the new translation string.
 353     * @param string comments
 354     * @param string the catalogue of the translation.
 355     * @return boolean true if translation was updated, false otherwise.
 356     */
 357    function update($text, $target, $comments, $catalogue = 'messages')
 358    {
 359      $variants = $this->getVariants($catalogue);
 360      if ($variants)
 361      {
 362        list($variant, $MOFile, $POFile) = $variants;
 363      }
 364      else
 365      {
 366        return false;
 367      }
 368  
 369      if (is_writable($MOFile) == false)
 370      {
 371        throw new sfException("Unable to update file {$MOFile}, file must be writable.");
 372      }
 373  
 374      if (is_writable($POFile) == false)
 375      {
 376        throw new sfException("Unable to update file {$POFile}, file must be writable.");
 377      }
 378  
 379      $po = TGettext::factory('PO',$POFile);
 380      $po->load();
 381      $result = $po->toArray();
 382  
 383      foreach ($result['strings'] as $string => $value)
 384      {
 385        if ($string == $text)
 386        {
 387          $result['strings'][$string] = $target;
 388          $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s');
 389  
 390          $po->fromArray($result);
 391          $mo = $po->toMO();
 392  
 393          if ($po->save() && $mo->save($MOFile))
 394          {
 395            if (!empty($this->cache))
 396            {
 397              $this->cache->clean($variant, $this->culture);
 398            }
 399  
 400            return true;
 401          }
 402          else
 403          {
 404            return false;
 405          }
 406        }
 407      }
 408  
 409      return false;
 410    }
 411  
 412    /**
 413     * Returns a list of catalogue as key and all it variants as value.
 414     *
 415     * @return array list of catalogues 
 416     */
 417    function catalogues()
 418    {
 419      return $this->getCatalogues();
 420    }
 421  
 422    /**
 423     * Returns a list of catalogue and its culture ID. This takes care
 424     * of directory structures.
 425     * E.g. array('messages','en_AU')
 426     *
 427     * @return array list of catalogues 
 428     */
 429    protected function getCatalogues($dir=null,$variant=null)
 430    {
 431      $dir = $dir?$dir:$this->source;
 432      $files = scandir($dir);
 433  
 434      $catalogue = array();
 435  
 436      foreach ($files as $file)
 437      {
 438        if (is_dir($dir.'/'.$file) && preg_match('/^[a-z]{2}(_[A-Z]{2,3})?$/',$file))
 439        {
 440          $catalogue = array_merge($catalogue, $this->getCatalogues($dir.'/'.$file, $file));
 441        }
 442  
 443        $pos = strpos($file,$this->dataExt);
 444  
 445        if ($pos > 0 && substr($file, -1 * strlen($this->dataExt)) == $this->dataExt)
 446        {
 447          $name = substr($file,0,$pos);
 448          $dot = strrpos($name,$this->dataSeparator);
 449          $culture = $variant;
 450          $cat = $name;
 451          if (is_int($dot))
 452          {
 453            $culture = substr($name, $dot+1,strlen($name));
 454            $cat = substr($name,0,$dot);
 455          }
 456          $details[0] = $cat;
 457          $details[1] = $culture;
 458  
 459          $catalogue[] = $details;
 460        }
 461      }
 462      sort($catalogue);
 463  
 464      return $catalogue;
 465    }
 466  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7