[ Index ]
 

Code source de eZ Publish 3.9.0

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

title

Body

[fermer]

/lib/ezi18n/classes/ -> eztstranslator.php (source)

   1  <?php
   2  //
   3  // Definition of eZTSTranslator class
   4  //
   5  // Created on: <07-Jun-2002 12:40:42 amos>
   6  //
   7  // SOFTWARE NAME: eZ publish
   8  // SOFTWARE RELEASE: 3.9.0
   9  // BUILD VERSION: 17785
  10  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
  11  // SOFTWARE LICENSE: GNU General Public License v2.0
  12  // NOTICE: >
  13  //   This program is free software; you can redistribute it and/or
  14  //   modify it under the terms of version 2.0  of the GNU General
  15  //   Public License as published by the Free Software Foundation.
  16  //
  17  //   This program is distributed in the hope that it will be useful,
  18  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20  //   GNU General Public License for more details.
  21  //
  22  //   You should have received a copy of version 2.0 of the GNU General
  23  //   Public License along with this program; if not, write to the Free
  24  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25  //   MA 02110-1301, USA.
  26  //
  27  //
  28  
  29  /*! \file eztstranslator.php
  30  */
  31  
  32  /*!
  33    \class eZTSTranslator eztstranslator.php
  34    \ingroup eZTranslation
  35    \brief This provides internationalization using XML (.ts) files
  36  
  37  */
  38  
  39  include_once ( "lib/ezi18n/classes/eztranslatorhandler.php" );
  40  include_once ( "lib/ezi18n/classes/eztextcodec.php" );
  41  include_once ( "lib/ezi18n/classes/eztranslationcache.php" );
  42  
  43  class eZTSTranslator extends eZTranslatorHandler
  44  {
  45      /*!
  46       Construct the translator and loads the translation file $file if it is set and exists.
  47      */
  48      function eZTSTranslator( $locale, $filename = null, $useCache = true )
  49      {
  50          $this->UseCache = $useCache;
  51          if ( isset( $GLOBALS['eZSiteBasics'] ) )
  52          {
  53              $siteBasics = $GLOBALS['eZSiteBasics'];
  54              if ( isset( $siteBasics['no-cache-adviced'] ) && $siteBasics['no-cache-adviced'] )
  55                  $this->UseCache = false;
  56          }
  57          $this->BuildCache = false;
  58          $this->eZTranslatorHandler( true );
  59  
  60          $this->Locale = $locale;
  61          $this->File = $filename;
  62          $this->Messages = array();
  63          $this->CachedMessages = array();
  64          $this->HasRestoredCache = false;
  65          $this->RootCache = false;
  66      }
  67  
  68      /*!
  69       \static
  70       Initialize the ts translator and context if this is not already done.
  71      */
  72      function &initialize( $context, $locale, $filename, $useCache = true )
  73      {
  74          $tables =& $GLOBALS["eZTSTranslationTables"];
  75          $instance = false;
  76          $file = $locale . '/' . $filename;
  77          if ( isset( $tables[$file] ) and
  78               get_class( $tables[$file] ) == "eztstranslator" )
  79              $instance =& $tables[$file];
  80          if ( $instance and
  81               $instance->hasInitializedContext( $context ) )
  82              return $instance;
  83          eZDebug::createAccumulatorGroup( 'tstranslator', 'TS translator' );
  84          eZDebug::accumulatorStart( 'tstranslator_init', 'tstranslator', 'TS init' );
  85          if ( !$instance )
  86          {
  87              $instance = new eZTSTranslator( $locale, $filename, $useCache );
  88              $tables[$file] =& $instance;
  89              $manager =& eZTranslatorManager::instance();
  90              $manager->registerHandler( $instance );
  91          }
  92          $instance->load( $context );
  93          eZDebug::accumulatorStop( 'tstranslator_init' );
  94          return $instance;
  95      }
  96  
  97      /*!
  98       \return true if the context \a $context is already initialized.
  99      */
 100      function hasInitializedContext( $context )
 101      {
 102          return isset( $this->CachedMessages[$context] );
 103      }
 104  
 105      /*!
 106       Tries to load the context \a $requestedContext for the translation and returns true if was successful.
 107      */
 108      function load( $requestedContext )
 109      {
 110          return $this->loadTranslationFile( $this->Locale, $this->File, $requestedContext );
 111      }
 112  
 113      /*!
 114       \private
 115      */
 116      function loadTranslationFile( $locale, $filename, $requestedContext )
 117      {
 118          include_once ( 'lib/ezfile/classes/ezdir.php' );
 119  
 120          // First try for current charset
 121          $charset = eZTextCodec::internalCharset();
 122          $tsTimeStamp = false;
 123  
 124          if ( !$this->RootCache )
 125          {
 126              $ini =& eZINI::instance();
 127              $roots = array( $ini->variable( 'RegionalSettings', 'TranslationRepository' ) );
 128              $extensionBase = eZExtension::baseDirectory();
 129              $translationExtensions = $ini->variable( 'RegionalSettings', 'TranslationExtensions' );
 130              foreach ( $translationExtensions as $translationExtension )
 131              {
 132                  $extensionPath = $extensionBase . '/' . $translationExtension . '/translations';
 133                  if ( file_exists( $extensionPath ) )
 134                  {
 135                      $roots[] = $extensionPath;
 136                  }
 137              }
 138              $this->RootCache = array( 'roots' => $roots );
 139          }
 140          else
 141          {
 142              $roots = $this->RootCache['roots'];
 143              if ( isset( $this->RootCache['timestamp'] ) )
 144                  $tsTimeStamp = $this->RootCache['timestamp'];
 145          }
 146  
 147          // Load cached translations if possible
 148          if ( $this->UseCache == true )
 149          {
 150              if ( !$tsTimeStamp )
 151              {
 152                  foreach ( $roots as $root )
 153                  {
 154                      $path = eZDir::path( array( $root, $locale, $charset, $filename ) );
 155                      if ( file_exists( $path ) )
 156                      {
 157                          $timestamp = filemtime( $path );
 158                          if ( $timestamp > $tsTimeStamp )
 159                              $tsTimeStamp = $timestamp;
 160                      }
 161                      else
 162                      {
 163                          $path = eZDir::path( array( $root, $locale, $filename ) );
 164                          if ( file_exists( $path ) )
 165                          {
 166                              $timestamp = filemtime( $path );
 167                              if ( $timestamp > $tsTimeStamp )
 168                                  $tsTimeStamp = $timestamp;
 169                          }
 170                      }
 171                  }
 172                  $this->RootCache['timestamp'] = $tsTimeStamp;
 173              }
 174              $key = 'cachecontexts';
 175              if ( $this->HasRestoredCache or
 176                   eZTranslationCache::canRestoreCache( $key, $tsTimeStamp ) )
 177              {
 178                  eZDebug::accumulatorStart( 'tstranslator_cache_load', 'tstranslator', 'TS cache load' );
 179                  if ( !$this->HasRestoredCache )
 180                  {
 181                      if ( !eZTranslationCache::restoreCache( $key ) )
 182                      {
 183                          $this->BuildCache = true;
 184                      }
 185                      $contexts = eZTranslationCache::contextCache( $key );
 186                      if ( !is_array( $contexts ) )
 187                          $contexts = array();
 188                      $this->HasRestoredCache = $contexts;
 189                  }
 190                  else
 191                      $contexts = $this->HasRestoredCache;
 192                  if ( !$this->BuildCache )
 193                  {
 194                      $contextName = $requestedContext;
 195                      if ( !isset( $this->CachedMessages[$contextName] ) )
 196                      {
 197                          eZDebug::accumulatorStart( 'tstranslator_context_load', 'tstranslator', 'TS context load' );
 198                          if ( eZTranslationCache::canRestoreCache( $contextName, $tsTimeStamp ) )
 199                          {
 200                              if ( !eZTranslationCache::restoreCache( $contextName ) )
 201                              {
 202                                  $this->BuildCache = true;
 203                              }
 204                              $this->CachedMessages[$contextName] =
 205                                   eZTranslationCache::contextCache( $contextName );
 206  
 207                              foreach ( $this->CachedMessages[$contextName] as $key => $msg )
 208                              {
 209                                  $this->Messages[$key] = $msg;
 210                              }
 211                          }
 212                          eZDebug::accumulatorStop( 'tstranslator_context_load' );
 213                      }
 214                  }
 215                  eZDebugSetting::writeNotice( 'i18n-tstranslator', "Loading cached translation", "eZTSTranslator::loadTranslationFile" );
 216                  eZDebug::accumulatorStop( 'tstranslator_cache_load' );
 217                  if ( !$this->BuildCache )
 218                  {
 219                      return true;
 220                  }
 221              }
 222              eZDebugSetting::writeNotice( 'i18n-tstranslator',
 223                                           "Translation cache has expired. Will rebuild it from source.",
 224                                           "eZTSTranslator::loadTranslationFile" );
 225              $this->BuildCache = true;
 226          }
 227  
 228          $status = false;
 229          foreach ( $roots as $root )
 230          {
 231              $path = eZDir::path( array( $root, $locale, $charset, $filename ) );
 232              if ( !file_exists( $path ) )
 233              {
 234                  $path = eZDir::path( array( $root, $locale, $filename ) );
 235  
 236                  $ini =& eZINI::instance( "i18n.ini" );
 237                  $fallbacks = $ini->variable( 'TranslationSettings', 'FallbackLanguages' );
 238  
 239                  if ( array_key_exists( $locale,  $fallbacks ) and $fallbacks[$locale] )
 240                  {
 241                      $fallbackpath = eZDir::path( array( $root, $fallbacks[$locale], $filename ) );
 242                      if ( !file_exists( $path ) and file_exists( $fallbackpath ) )
 243                          $path = $fallbackpath;
 244                  }
 245  
 246                  if ( !file_exists( $path ) )
 247                  {
 248                      eZDebug::writeError( "Could not load translation file: $path", "eZTSTranslator::loadTranslationFile" );
 249                      continue;
 250                  }
 251              }
 252  
 253              eZDebug::accumulatorStart( 'tstranslator_load', 'tstranslator', 'TS load' );
 254              $fd = fopen( $path, "rb" );
 255              $trans_xml = fread( $fd, filesize( $path ) );
 256              fclose( $fd );
 257  
 258              include_once ( "lib/ezxml/classes/ezxml.php" );
 259              $xml = new eZXML();
 260  
 261              $tree =& $xml->domTree( $trans_xml, array(), true );
 262  
 263              if ( !$this->validateDOMTree( $tree ) )
 264              {
 265                  eZDebug::writeWarning( "XML text for file $path did not validate", 'eZTSTranslator::loadTranslationFile' );
 266                  continue;
 267              }
 268              $status = true;
 269  
 270              $treeRoot = $tree->get_root();
 271              $children = $treeRoot->children();
 272              foreach( $children as $child )
 273              {
 274                  if ( $child->type == 1 )
 275                  {
 276                      if ( $child->name() == "context" )
 277                      {
 278                          $this->handleContextNode( $child );
 279                      }
 280                      else
 281                          eZDebug::writeError( "Unknown element name: " . $child->name(),
 282                                               "eZTSTranslator::loadTranslationFile" );
 283                  }
 284              }
 285              eZDebug::accumulatorStop( 'tstranslator_load' );
 286          }
 287  
 288          // Save translation cache
 289          if ( $this->UseCache == true && $this->BuildCache == true )
 290          {
 291              eZDebug::accumulatorStart( 'tstranslator_store_cache', 'tstranslator', 'TS store cache' );
 292              if ( eZTranslationCache::contextCache( 'cachecontexts' ) == null )
 293              {
 294                  $contexts = array_keys( $this->CachedMessages );
 295                  eZTranslationCache::setContextCache( 'cachecontexts',
 296                                                       $contexts );
 297                  eZTranslationCache::storeCache( 'cachecontexts' );
 298                  $this->HasRestoredCache = $contexts;
 299              }
 300  
 301              foreach ( $this->CachedMessages as $contextName => $context )
 302              {
 303                  if ( eZTranslationCache::contextCache( $contextName ) == null )
 304                      eZTranslationCache::setContextCache( $contextName, $context );
 305                  eZTranslationCache::storeCache( $contextName );
 306              }
 307              $this->BuildCache = false;
 308              eZDebug::accumulatorStop( 'tstranslator_store_cache' );
 309          }
 310  
 311          return $status;
 312      }
 313  
 314      /*!
 315       \static
 316       Validates the DOM tree \a $tree and returns true if it is correct.
 317       \warning There's no validation done yet. It checks if \a $tree is object only.
 318       In all other cases it returns \c true for all DOM trees.
 319      */
 320      function validateDOMTree( &$tree )
 321      {
 322          if ( !is_object( $tree ) )
 323              return false;
 324  
 325          return true;
 326  /*        $xmlSchema = '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 327  xmlns="http://www.w3.org/2001/XMLSchema/default">
 328  
 329  <xsd:annotation>
 330    <xsd:documentation xml:lang="en">
 331     Translation message schema for ez.no.
 332     Copyright 2002 ez.no. All rights reserved.
 333    </xsd:documentation>
 334   </xsd:annotation>
 335  
 336   <xsd:element name="TS" type="TranslateRootType"/>
 337  
 338   <xsd:complexType name="TranslateRootType">
 339    <xsd:sequence>
 340     <xsd:element name="context" type="ContextType"/>
 341    </xsd:sequence>
 342   </xsd:complexType>
 343  
 344   <xsd:complexType name="ContextType">
 345    <xsd:sequence>
 346     <xsd:element name="name" type="xsd:string" />
 347     <xsd:element name="message" type="MessageType"/>
 348    </xsd:sequence>
 349   </xsd:complexType>
 350  
 351   <xsd:complexType name="MessageType">
 352    <xsd:sequence>
 353     <xsd:element name="source"      type="xsd:string"/>
 354     <xsd:element name="translation" type="TranslationType"/>
 355     <xsd:element name="comment"     type="xsd:string" minOccurs="0" maxOccurs="1"/>
 356    </xsd:sequence>
 357   </xsd:complexType>
 358  
 359   <xsd:simpleType name="TranslationType">
 360    <xsd:restriction base="xsd:string">
 361    </xsd:restriction>
 362    <xsd:attribute name="type" type="xsd:string" />
 363   </xsd:simpleType>
 364  
 365  </xsd:schema>';
 366  
 367          include_once( "lib/ezxml/classes/ezschema.php" );
 368  
 369          $schema = new eZSchema( );
 370          $schema->setSchema( $xmlSchema );
 371  
 372          return $schema->validate( $tree );*/
 373      }
 374  
 375      function handleContextNode( $context )
 376      {
 377          $contextName = null;
 378          $messages = array();
 379          $context_children = $context->children();
 380  
 381          foreach( $context_children as $context_child )
 382          {
 383              if ( $context_child->type == 1 )
 384              {
 385                  if ( $context_child->name() == "name" )
 386                  {
 387                      $name_el = $context_child->children();
 388                      if ( count( $name_el ) > 0 )
 389                      {
 390                          $name_el = $name_el[0];
 391                          $contextName = $name_el->content;
 392                      }
 393                  }
 394                  break;
 395              }
 396          }
 397          if ( !$contextName )
 398          {
 399              eZDebug::writeError( "No context name found, skipping context",
 400                                   "eZTSTranslator::handleContextNode" );
 401              return false;
 402          }
 403          foreach( $context_children as $context_child )
 404          {
 405              if ( $context_child->type == 1 )
 406              {
 407                  $childName = $context_child->name();
 408                  if ( $childName == "message" )
 409                  {
 410                      $this->handleMessageNode( $contextName, $context_child );
 411                  }
 412                  else if ( $childName == "name" )
 413                  {
 414                      /* Skip name tags */
 415                  }
 416                  else
 417                  {
 418                      eZDebug::writeError( "Unknown element name: $childName",
 419                                           "eZTSTranslator::handleContextNode" );
 420                  }
 421              }
 422          }
 423          if ( $contextName === null )
 424          {
 425              eZDebug::writeError( "No context name found, skipping context",
 426                                   "eZTSTranslator::handleContextNode" );
 427              return false;
 428          }
 429          if ( !isset( $this->CachedMessages[$contextName] ) )
 430              $this->CachedMessages[$contextName] = array();
 431  
 432          return true;
 433      }
 434  
 435      function handleMessageNode( $contextName, &$message )
 436      {
 437          $source = null;
 438          $translation = null;
 439          $comment = null;
 440          $message_children = $message->children();
 441          foreach( $message_children as $message_child )
 442          {
 443              if ( $message_child->type == 1 )
 444              {
 445                  if ( $message_child->name() == "source" )
 446                  {
 447                      $source_el = $message_child->children();
 448                      $source_el = $source_el[0];
 449                      $source = $source_el->content;
 450                  }
 451                  else if ( $message_child->name() == "translation" )
 452                  {
 453                      $translation_el = $message_child->children();
 454                      if ( count( $translation_el ) > 0 )
 455                      {
 456                          $translation_el = $translation_el[0];
 457                          $translation = $translation_el->content;
 458                      }
 459                  }
 460                  else if ( $message_child->name() == "comment" )
 461                  {
 462                      $comment_el = $message_child->children();
 463                      $comment_el = $comment_el[0];
 464                      $comment = $comment_el->content;
 465                  }
 466                  else
 467                      eZDebug::writeError( "Unknown element name: " . $message_child->name(),
 468                                           "eZTSTranslator::handleMessageNode" );
 469              }
 470          }
 471          if ( $source === null )
 472          {
 473              eZDebug::writeError( "No source name found, skipping message",
 474                                   "eZTSTranslator::handleMessageNode" );
 475              return false;
 476          }
 477          if ( $translation === null )
 478          {
 479  //             eZDebug::writeError( "No translation, skipping message", "eZTSTranslator::messageNode" );
 480              return false;
 481          }
 482          /* we need to convert ourselves if we're using libxml stuff here */
 483          if ( get_class( $message ) == 'domelement' )
 484          {
 485              $codec =& eZTextCodec::instance( "utf8" );
 486              $source = $codec->convertString( $source );
 487              $translation = $codec->convertString( $translation );
 488              $comment = $codec->convertString( $comment );
 489          }
 490  
 491          $this->insert( $contextName, $source, $translation, $comment );
 492          return true;
 493      }
 494  
 495      /*!
 496       \reimp
 497      */
 498      function findKey( $key )
 499      {
 500          $msg = null;
 501          if ( isset( $this->Messages[$key] ) )
 502          {
 503              $msg = $this->Messages[$key];
 504          }
 505          return $msg;
 506      }
 507  
 508      /*!
 509       \reimp
 510      */
 511      function findMessage( $context, $source, $comment = null )
 512      {
 513          // First try with comment,
 514          $man = eZTranslatorManager::instance();
 515          $key = $man->createKey( $context, $source, $comment );
 516  
 517          if ( !isset( $this->Messages[$key] ) )
 518          {
 519              // then try without comment for general translation
 520              $key = $man->createKey( $context, $source );
 521          }
 522  
 523          return $this->findKey( $key );
 524      }
 525  
 526      /*!
 527       \reimp
 528      */
 529      function keyTranslate( $key )
 530      {
 531          $msg = $this->findKey( $key );
 532          if ( $msg !== null )
 533              return $msg["translation"];
 534          else
 535          {
 536              return null;
 537          }
 538      }
 539  
 540      /*!
 541       \reimp
 542      */
 543      function translate( $context, $source, $comment = null )
 544      {
 545          $msg = $this->findMessage( $context, $source, $comment );
 546          if ( $msg !== null )
 547          {
 548              return $msg["translation"];
 549          }
 550  
 551          return null;
 552      }
 553  
 554      /*!
 555       Inserts the \a $translation for the \a $context and \a $source as a translation message
 556       and returns the key for the message. If $comment is non-null it will be included in the message.
 557  
 558       If the translation message exists no new message is created and the existing key is returned.
 559      */
 560      function insert( $context, $source, $translation, $comment = null )
 561      {
 562  //         eZDebug::writeDebug( "context=$context" );
 563          if ( $context == "" )
 564              $context = "default";
 565          $man =& eZTranslatorManager::instance();
 566          $key = $man->createKey( $context, $source, $comment );
 567  //         if ( isset( $this->Messages[$key] ) )
 568  //             return $key;
 569          $msg = $man->createMessage( $context, $source, $comment, $translation );
 570          $msg["key"] = $key;
 571          $this->Messages[$key] = $msg;
 572          // Set array of messages to be cached
 573          if ( $this->UseCache == true && $this->BuildCache == true )
 574          {
 575              if ( !isset( $this->CachedMessages[$context] ) )
 576                  $this->CachedMessages[$context] = array();
 577              $this->CachedMessages[$context][$key] = $msg;
 578          }
 579          return $key;
 580      }
 581  
 582      /*!
 583       Removes the translation message with \a $context and \a $source.
 584       Returns true if the message was removed, false otherwise.
 585  
 586       If you have the translation key use removeKey() instead.
 587      */
 588      function remove( $context, $source, $message = null )
 589      {
 590          if ( $context == "" )
 591              $context = "default";
 592          $man =& eZTranslatorManager::instance();
 593          $key = $man->createKey( $context, $source, $message );
 594          if ( isset( $this->Messages[$key] ) )
 595              unset( $this->Messages[$key] );
 596      }
 597  
 598      /*!
 599       Removes the translation message with \a $key.
 600       Returns true if the message was removed, false otherwise.
 601      */
 602      function removeKey( $key )
 603      {
 604          if ( isset( $this->Messages[$key] ) )
 605              unset( $this->Messages[$key] );
 606      }
 607  
 608      /// \privatesection
 609      /// Contains the hash table with message translations
 610      var $Messages;
 611      var $File;
 612      var $UseCache;
 613      var $BuildCache;
 614      var $CachedMessages;
 615  }
 616  
 617  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7