eZ Publish  [trunk]
eztstranslator.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZTSTranslator class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  * @subpackage i18n
00010  */
00011 /**
00012  * Provides internationalization using XML (.ts) files
00013  * @package lib
00014  * @subpackage i18n
00015  */
00016 class eZTSTranslator extends eZTranslatorHandler
00017 {
00018     /**
00019      * Constructs the translator and loads the translation file $file if it is set and exists.
00020      * @param string $locale
00021      * @param string $filename
00022      * @param bool $useCache
00023      */
00024     function eZTSTranslator( $locale, $filename = null, $useCache = true )
00025     {
00026         $this->UseCache = $useCache;
00027         if ( isset( $GLOBALS['eZSiteBasics'] ) )
00028         {
00029             $siteBasics = $GLOBALS['eZSiteBasics'];
00030             if ( isset( $siteBasics['no-cache-adviced'] ) && $siteBasics['no-cache-adviced'] )
00031                 $this->UseCache = false;
00032         }
00033         $this->BuildCache = false;
00034         $this->eZTranslatorHandler( true );
00035 
00036         $this->Locale = $locale;
00037         $this->File = $filename;
00038         $this->Messages = array();
00039         $this->CachedMessages = array();
00040         $this->HasRestoredCache = false;
00041         $this->RootCache = false;
00042     }
00043 
00044     /**
00045      * Initialize the ts translator and context if this is not already done
00046      *
00047      * @param string $context
00048      * @param string $locale
00049      * @param string $filename
00050      * @param bool $useCache
00051      * @return eZTSTranslator
00052      */
00053     static function initialize( $context, $locale, $filename, $useCache = true )
00054     {
00055         $instance = false;
00056         $file = $locale . '/' . $filename;
00057         if ( !empty( $GLOBALS['eZTSTranslationTables'][$file] ) )
00058         {
00059             $instance = $GLOBALS['eZTSTranslationTables'][$file];
00060             if ( $instance->hasInitializedContext( $context ) )
00061             {
00062                 return $instance;
00063             }
00064         }
00065 
00066         eZDebug::createAccumulatorGroup( 'tstranslator', 'TS translator' );
00067         eZDebug::accumulatorStart( 'tstranslator_init', 'tstranslator', 'TS init' );
00068         if ( !$instance )
00069         {
00070             $instance = new eZTSTranslator( $locale, $filename, $useCache );
00071             $GLOBALS['eZTSTranslationTables'][$file] = $instance;
00072             $manager = eZTranslatorManager::instance();
00073             $manager->registerHandler( $instance );
00074         }
00075         $instance->load( $context );
00076         eZDebug::accumulatorStop( 'tstranslator_init' );
00077         return $instance;
00078     }
00079 
00080     /**
00081      * Checks if a context has been initialized (cached)
00082      *
00083      * @param string $context
00084      * @return bool True if the context was initialized before, false if it wasn't
00085      */
00086     function hasInitializedContext( $context )
00087     {
00088         return isset( $this->CachedMessages[$context] );
00089     }
00090 
00091     /**
00092      * Tries to load the context $requestedContext for the translation and returns true if was successful.
00093      *
00094      * @param string $requestedContext
00095      * @return bool True if load was successful, false otherwise
00096      */
00097     function load( $requestedContext )
00098     {
00099         return $this->loadTranslationFile( $this->Locale, $this->File, $requestedContext );
00100     }
00101 
00102     /**
00103      * Loads a translation file
00104      * Will load from cache if possible, or generate cache if needed
00105      *
00106      * Also checks for translation files expiry based on mtime if RegionalSettings.TranslationCheckMTime is enabled
00107      *
00108      * @access private
00109      * @param string $locale
00110      * @param string $filename
00111      * @param string $requestedContext
00112      *
00113      * @return bool The operation status, true or false
00114     */
00115     function loadTranslationFile( $locale, $filename, $requestedContext )
00116     {
00117         // First try for current charset
00118         $charset = eZTextCodec::internalCharset();
00119         $tsTimeStamp = false;
00120         $ini = eZINI::instance();
00121         $checkMTime = $ini->variable( 'RegionalSettings', 'TranslationCheckMTime' ) === 'enabled';
00122 
00123         if ( !$this->RootCache )
00124         {
00125             $roots = array( $ini->variable( 'RegionalSettings', 'TranslationRepository' ) );
00126             $extensionBase = eZExtension::baseDirectory();
00127             $translationExtensions = $ini->variable( 'RegionalSettings', 'TranslationExtensions' );
00128             foreach ( $translationExtensions as $translationExtension )
00129             {
00130                 $extensionPath = $extensionBase . '/' . $translationExtension . '/translations';
00131                 if ( !$checkMTime || file_exists( $extensionPath ) )
00132                 {
00133                     $roots[] = $extensionPath;
00134                 }
00135             }
00136             $this->RootCache = array( 'roots' => $roots );
00137         }
00138         else
00139         {
00140             $roots = $this->RootCache['roots'];
00141             if ( isset( $this->RootCache['timestamp'] ) )
00142                 $tsTimeStamp = $this->RootCache['timestamp'];
00143         }
00144 
00145 
00146         // Load cached translations if possible
00147         if ( $this->UseCache == true )
00148         {
00149             if ( !$tsTimeStamp )
00150             {
00151                 $expiry = eZExpiryHandler::instance();
00152                 $globalTsTimeStamp = $expiry->getTimestamp( self::EXPIRY_KEY, 0 );
00153                 $localeTsTimeStamp = $expiry->getTimestamp( self::EXPIRY_KEY . '-' . $locale, 0 );
00154                 $tsTimeStamp = max( $globalTsTimeStamp, $localeTsTimeStamp );
00155                 if ( $checkMTime && $tsTimeStamp < time() )// no need if ts == time()
00156                 {
00157                     // iterate over each known TS file, and get the highest timestamp
00158                     // this value will be used to check for cache validity
00159                     foreach ( $roots as $root )
00160                     {
00161                         $path = eZDir::path( array( $root, $locale, $charset, $filename ) );
00162                         if ( file_exists( $path ) )
00163                         {
00164                             $timestamp = filemtime( $path );
00165                             if ( $timestamp > $tsTimeStamp )
00166                                 $tsTimeStamp = $timestamp;
00167                         }
00168                         else
00169                         {
00170                             $path = eZDir::path( array( $root, $locale, $filename ) );
00171                             if ( file_exists( $path ) )
00172                             {
00173                                 $timestamp = filemtime( $path );
00174                                 if ( $timestamp > $tsTimeStamp )
00175                                     $tsTimeStamp = $timestamp;
00176                             }
00177                         }
00178                     }
00179                 }
00180                 $this->RootCache['timestamp'] = $tsTimeStamp;
00181             }
00182 
00183             $key = 'cachecontexts';
00184             if ( $this->HasRestoredCache or
00185                  eZTranslationCache::canRestoreCache( $key, $tsTimeStamp ) )
00186             {
00187                 eZDebug::accumulatorStart( 'tstranslator_cache_load', 'tstranslator', 'TS cache load' );
00188                 if ( !$this->HasRestoredCache )
00189                 {
00190                     if ( !eZTranslationCache::restoreCache( $key ) )
00191                     {
00192                         $this->BuildCache = true;
00193                     }
00194                     $contexts = eZTranslationCache::contextCache( $key );
00195                     if ( !is_array( $contexts ) )
00196                         $contexts = array();
00197                     $this->HasRestoredCache = $contexts;
00198                 }
00199                 else
00200                     $contexts = $this->HasRestoredCache;
00201                 if ( !$this->BuildCache )
00202                 {
00203                     $contextName = $requestedContext;
00204                     if ( !isset( $this->CachedMessages[$contextName] ) )
00205                     {
00206                         eZDebug::accumulatorStart( 'tstranslator_context_load', 'tstranslator', 'TS context load' );
00207                         if ( eZTranslationCache::canRestoreCache( $contextName, $tsTimeStamp ) )
00208                         {
00209                             if ( !eZTranslationCache::restoreCache( $contextName ) )
00210                             {
00211                                 $this->BuildCache = true;
00212                             }
00213                             $this->CachedMessages[$contextName] =
00214                                  eZTranslationCache::contextCache( $contextName );
00215 
00216                             foreach ( $this->CachedMessages[$contextName] as $key => $msg )
00217                             {
00218                                 $this->Messages[$key] = $msg;
00219                             }
00220                         }
00221                         eZDebug::accumulatorStop( 'tstranslator_context_load' );
00222                     }
00223                 }
00224                 eZDebugSetting::writeNotice( 'i18n-tstranslator', "Loading cached translation", __METHOD__ );
00225                 eZDebug::accumulatorStop( 'tstranslator_cache_load' );
00226                 if ( !$this->BuildCache )
00227                 {
00228                     return true;
00229                 }
00230             }
00231             eZDebugSetting::writeNotice( 'i18n-tstranslator',
00232                                          "Translation cache has expired. Will rebuild it from source.",
00233                                          __METHOD__ );
00234             $this->BuildCache = true;
00235         }
00236 
00237         $status = false;
00238 
00239         // first process country translation files
00240         // then process country variation translation files
00241         $localeParts = explode( '@', $locale );
00242 
00243         $triedPaths = array();
00244         $loadedPaths = array();
00245 
00246         $ini = eZINI::instance( "i18n.ini" );
00247         $fallbacks = $ini->variable( 'TranslationSettings', 'FallbackLanguages' );
00248 
00249         foreach ( $localeParts as $localePart )
00250         {
00251             $localeCodeToProcess = isset( $localeCodeToProcess ) ? $localeCodeToProcess . '@' . $localePart: $localePart;
00252 
00253             // array with alternative subdirs to check
00254             $alternatives = array(
00255                 array( $localeCodeToProcess, $charset, $filename ),
00256                 array( $localeCodeToProcess, $filename ),
00257             );
00258 
00259             if ( isset( $fallbacks[$localeCodeToProcess] ) && $fallbacks[$localeCodeToProcess] )
00260             {
00261                 if ( $fallbacks[$localeCodeToProcess] === 'eng-GB' ) // Consider eng-GB fallback as "untranslated" since eng-GB does not provide any ts file
00262                 {
00263                     $fallbacks[$localeCodeToProcess] = 'untranslated';
00264                 }
00265                 $alternatives[] = array( $fallbacks[$localeCodeToProcess], $charset, $filename );
00266                 $alternatives[] = array( $fallbacks[$localeCodeToProcess], $filename );
00267             }
00268 
00269             foreach ( $roots as $root )
00270             {
00271                 if ( !file_exists( $root ) )
00272                 {
00273                     continue;
00274                 }
00275 
00276                 unset( $path );
00277 
00278                 foreach ( $alternatives as $alternative )
00279                 {
00280                     $pathParts = $alternative;
00281                     array_unshift( $pathParts, $root );
00282                     $pathToTry = eZDir::path( $pathParts );
00283                     $triedPaths[] = $pathToTry;
00284 
00285                     if ( file_exists( $pathToTry ) )
00286                     {
00287                         $path = $pathToTry;
00288                         break;
00289                     }
00290                 }
00291 
00292                 if ( !isset( $path ) )
00293                 {
00294                     continue;
00295                 }
00296 
00297                 eZDebug::accumulatorStart( 'tstranslator_load', 'tstranslator', 'TS load' );
00298 
00299                 $doc = new DOMDocument( '1.0', 'utf-8' );
00300                 $success = $doc->load( $path );
00301 
00302                 if ( !$success )
00303                 {
00304                     eZDebug::writeWarning( "Unable to load XML from file $path", __METHOD__ );
00305                     continue;
00306                 }
00307 
00308                 if ( !$this->validateDOMTree( $doc ) )
00309                 {
00310                     eZDebug::writeWarning( "XML text for file $path did not validate", __METHOD__ );
00311                     continue;
00312                 }
00313 
00314                 $loadedPaths[] = $path;
00315 
00316                 $status = true;
00317 
00318                 $treeRoot = $doc->documentElement;
00319                 $children = $treeRoot->childNodes;
00320                 for ($i = 0; $i < $children->length; $i++ )
00321                 {
00322                     $child = $children->item( $i );
00323 
00324                     if ( $child->nodeType == XML_ELEMENT_NODE )
00325                     {
00326                         if ( $child->tagName == "context" )
00327                         {
00328                             $this->handleContextNode( $child );
00329                         }
00330                     }
00331                 }
00332                 eZDebug::accumulatorStop( 'tstranslator_load' );
00333             }
00334         }
00335 
00336         eZDebugSetting::writeDebug( 'i18n-tstranslator', implode( PHP_EOL, $triedPaths ), __METHOD__ . ': tried paths' );
00337         eZDebugSetting::writeDebug( 'i18n-tstranslator', implode( PHP_EOL, $loadedPaths ), __METHOD__ . ': loaded paths' );
00338 
00339         // Save translation cache
00340         if ( $this->UseCache == true && $this->BuildCache == true )
00341         {
00342             eZDebug::accumulatorStart( 'tstranslator_store_cache', 'tstranslator', 'TS store cache' );
00343             if ( eZTranslationCache::contextCache( 'cachecontexts' ) == null )
00344             {
00345                 $contexts = array_keys( $this->CachedMessages );
00346                 eZTranslationCache::setContextCache( 'cachecontexts',
00347                                                      $contexts );
00348                 eZTranslationCache::storeCache( 'cachecontexts' );
00349                 $this->HasRestoredCache = $contexts;
00350             }
00351 
00352             foreach ( $this->CachedMessages as $contextName => $context )
00353             {
00354                 if ( eZTranslationCache::contextCache( $contextName ) == null )
00355                     eZTranslationCache::setContextCache( $contextName, $context );
00356                 eZTranslationCache::storeCache( $contextName );
00357             }
00358 
00359             $this->BuildCache = false;
00360             eZDebug::accumulatorStop( 'tstranslator_store_cache' );
00361         }
00362 
00363         return $status;
00364     }
00365 
00366     /**
00367      * Validates the DOM tree $tree and returns true if it is correct
00368      * @param DOMDocument $tree
00369      * @return bool True if the DOMDocument is valid, false otherwise
00370      */
00371     static function validateDOMTree( $tree )
00372     {
00373         if ( !is_object( $tree ) )
00374             return false;
00375 
00376         $isValid = $tree->RelaxNGValidate( 'schemas/translation/ts.rng' );
00377 
00378         return $isValid;
00379     }
00380 
00381     /**
00382      * Handles a DOM Context node and the messages it contains
00383      * @param DOMNode $context
00384      * @return bool
00385      */
00386     function handleContextNode( $context )
00387     {
00388         $contextName = null;
00389         $messages = array();
00390         $context_children = $context->childNodes;
00391 
00392         for( $i = 0; $i < $context_children->length; $i++ )
00393         {
00394             $context_child = $context_children->item( $i );
00395             if ( $context_child->nodeType == XML_ELEMENT_NODE )
00396             {
00397                 if ( $context_child->tagName == "name" )
00398                 {
00399                     $name_el = $context_child->firstChild;
00400                     if ( $name_el )
00401                     {
00402                         $contextName = $name_el->nodeValue;
00403                     }
00404                 }
00405                 break;
00406             }
00407         }
00408         if ( !$contextName )
00409         {
00410             eZDebug::writeError( "No context name found, skipping context", __METHOD__ );
00411             return false;
00412         }
00413         foreach( $context_children as $context_child )
00414         {
00415             if ( $context_child->nodeType == XML_ELEMENT_NODE )
00416             {
00417                 $childName = $context_child->tagName;
00418                 if ( $childName == "message" )
00419                 {
00420                     $this->handleMessageNode( $contextName, $context_child );
00421                 }
00422                 else if ( $childName == "name" )
00423                 {
00424                     /* Skip name tags */
00425                 }
00426                 else
00427                 {
00428                     eZDebug::writeError( "Unknown element name: $childName", __METHOD__ );
00429                 }
00430             }
00431         }
00432         if ( $contextName === null )
00433         {
00434             eZDebug::writeError( "No context name found, skipping context", __METHOD__ );
00435             return false;
00436         }
00437         if ( !isset( $this->CachedMessages[$contextName] ) )
00438             $this->CachedMessages[$contextName] = array();
00439 
00440         return true;
00441     }
00442 
00443     /**
00444      * Handles a translation message DOM node
00445      * @param string $contextName
00446      * @param DOMNode $message
00447      */
00448     function handleMessageNode( $contextName, $message )
00449     {
00450         $source = null;
00451         $translation = null;
00452         $comment = null;
00453         $message_children = $message->childNodes;
00454         for( $i = 0; $i < $message_children->length; $i++ )
00455         {
00456             $message_child = $message_children->item( $i );
00457             if ( $message_child->nodeType == XML_ELEMENT_NODE )
00458             {
00459                 $childName = $message_child->tagName;
00460                 if ( $childName  == "source" )
00461                 {
00462                     if ( $message_child->childNodes->length > 0 )
00463                     {
00464                         $source = '';
00465                         foreach ( $message_child->childNodes as $textEl )
00466                         {
00467                             if ( $textEl instanceof DOMText )
00468                             {
00469                                 $source .= $textEl->nodeValue;
00470                             }
00471                             else if ( $textEl instanceof DOMElement && $textEl->tagName == 'byte' )
00472                             {
00473                                 $source .= chr( intval( '0' . $textEl->getAttribute( 'value' ) ) );
00474                             }
00475                         }
00476                     }
00477                 }
00478                 else if ( $childName == "translation" )
00479                 {
00480                     if ( $message_child->childNodes->length > 0 )
00481                     {
00482                         $translation = '';
00483                         foreach ( $message_child->childNodes as $textEl )
00484                         {
00485                             if ( $textEl instanceof DOMText )
00486                             {
00487                                 $translation .= $textEl->nodeValue;
00488                             }
00489                             else if ( $textEl instanceof DOMElement && $textEl->tagName == 'byte' )
00490                             {
00491                                 $translation .= chr( intval( '0' . $textEl->getAttribute( 'value' ) ) );
00492                             }
00493                         }
00494                     }
00495                 }
00496                 else if ( $childName == "comment" )
00497                 {
00498                     $comment_el = $message_child->firstChild;
00499                     $comment = $comment_el->nodeValue;
00500                 }
00501                 else if ( $childName == "translatorcomment" )
00502                 {
00503                     //Ignore it.
00504                 }
00505                 else if ( $childName == "location" )
00506                 {
00507                     //Handle location element. No functionality yet.
00508                 }
00509                 else
00510                     eZDebug::writeError( "Unknown element name: " . $childName, __METHOD__ );
00511             }
00512         }
00513         if ( $source === null )
00514         {
00515             eZDebug::writeError( "No source name found, skipping message in context '{$contextName}'", __METHOD__ );
00516             return false;
00517         }
00518         if ( $translation === null ) // No translation provided, then take the source as a reference
00519         {
00520 //             eZDebug::writeError( "No translation, skipping message", __METHOD__ );
00521             $translation = $source;
00522         }
00523         /* we need to convert ourselves if we're using libxml stuff here */
00524         if ( $message instanceof DOMElement )
00525         {
00526             $codec = eZTextCodec::instance( "utf8" );
00527             $source = $codec->convertString( $source );
00528             $translation = $codec->convertString( $translation );
00529             $comment = $codec->convertString( $comment );
00530         }
00531 
00532         $this->insert( $contextName, $source, $translation, $comment );
00533         return true;
00534     }
00535 
00536     /**
00537      * Returns the message that matches a translation md5 key
00538      * @param string $key
00539      * @return array|false The message, as an array, or false if not found
00540      */
00541     function findKey( $key )
00542     {
00543         $msg = null;
00544         if ( isset( $this->Messages[$key] ) )
00545         {
00546             $msg = $this->Messages[$key];
00547         }
00548         return $msg;
00549     }
00550 
00551     /**
00552      * Returns the message that matches a context / source / comment
00553      * @param string $context
00554      * @param string $source
00555      * @param string $comment
00556      * @return array|false The message, as an array, or false if not found
00557      */
00558     function findMessage( $context, $source, $comment = null )
00559     {
00560         // First try with comment,
00561         $man = eZTranslatorManager::instance();
00562         $key = $man->createKey( $context, $source, $comment );
00563 
00564         if ( !isset( $this->Messages[$key] ) )
00565         {
00566             // then try without comment for general translation
00567             $key = $man->createKey( $context, $source );
00568         }
00569 
00570         return $this->findKey( $key );
00571     }
00572 
00573     /**
00574      * Returns the translation for a translation md5 key
00575      * @param string $key
00576      * @return string|false
00577      */
00578     function keyTranslate( $key )
00579     {
00580         $msg = $this->findKey( $key );
00581         if ( $msg !== null )
00582             return $msg["translation"];
00583         else
00584         {
00585             return null;
00586         }
00587     }
00588 
00589     /**
00590      * Translates a context + source + comment
00591      * @param string $context
00592      * @param string $source
00593      * @param string $comment
00594      * @return string|false
00595      */
00596     function translate( $context, $source, $comment = null )
00597     {
00598         $msg = $this->findMessage( $context, $source, $comment );
00599         if ( $msg !== null )
00600         {
00601             return $msg["translation"];
00602         }
00603 
00604         return null;
00605     }
00606 
00607     /**
00608      * Inserts the translation $translation for the context $context and source $source as a translation message.
00609      * Returns the key for the message. If $comment is non-null it will be included in the message.
00610      *
00611      * If the translation message exists no new message is created and the existing key is returned.
00612      *
00613      * @param string $context
00614      * @param string $source
00615      * @param string $translation
00616      * @param string $comment
00617      *
00618      * @return string The translation (md5) key
00619     */
00620     function insert( $context, $source, $translation, $comment = null )
00621     {
00622         if ( $context == "" )
00623             $context = "default";
00624         $man = eZTranslatorManager::instance();
00625         $key = $man->createKey( $context, $source, $comment );
00626         $msg = $man->createMessage( $context, $source, $comment, $translation );
00627         $msg["key"] = $key;
00628         $this->Messages[$key] = $msg;
00629 
00630         // Set array of messages to be cached
00631         if ( $this->UseCache == true && $this->BuildCache == true )
00632         {
00633             if ( !isset( $this->CachedMessages[$context] ) )
00634                 $this->CachedMessages[$context] = array();
00635             $this->CachedMessages[$context][$key] = $msg;
00636         }
00637         return $key;
00638     }
00639 
00640     /**
00641      * Removes the translation message with context $context and source $source.
00642      *
00643      * If you have the translation key use removeKey() instead.
00644      *
00645      * @param string $context
00646      * @param string $source
00647      * @param string $message
00648      *
00649      * @return bool true if the message was removed, false otherwise
00650      */
00651     function remove( $context, $source, $message = null )
00652     {
00653         if ( $context == "" )
00654             $context = "default";
00655         $man = eZTranslatorManager::instance();
00656         $key = $man->createKey( $context, $source, $message );
00657         if ( isset( $this->Messages[$key] ) )
00658             unset( $this->Messages[$key] );
00659     }
00660 
00661     /**
00662      * Removes the translation message with the key $key.
00663      *
00664      * @param string $key The translation md5 key
00665      *
00666      * @return bool true if the message was removed, false otherwise
00667      */
00668     function removeKey( $key )
00669     {
00670         if ( isset( $this->Messages[$key] ) )
00671             unset( $this->Messages[$key] );
00672     }
00673 
00674     /**
00675      * Fetches the list of available translations, as an eZTSTranslator for each translation.
00676      *
00677      * @param array $localList
00678      *
00679      * @return array( eZTSTranslator ) list of eZTranslator objects representing available translations
00680     */
00681     static function fetchList( $localeList = array() )
00682     {
00683         $ini = eZINI::instance();
00684 
00685         $dir = $ini->variable( 'RegionalSettings', 'TranslationRepository' );
00686 
00687         $fileInfoList = array();
00688         $translationList = array();
00689         $locale = '';
00690 
00691         if ( count( $localeList ) == 0 )
00692         {
00693             $localeList = eZDir::findSubdirs( $dir );
00694         }
00695 
00696         foreach( $localeList as $locale )
00697         {
00698             if ( $locale != 'untranslated' )
00699             {
00700                 $translationFiles = eZDir::findSubitems( $dir . '/' . $locale, 'f' );
00701 
00702                 foreach( $translationFiles as $translationFile )
00703                 {
00704                     if ( eZFile::suffix( $translationFile ) == 'ts' )
00705                     {
00706                         $translationList[] = new eZTSTranslator( $locale,  $translationFile );
00707                     }
00708                 }
00709             }
00710         }
00711 
00712         return $translationList;
00713     }
00714 
00715     /**
00716      * Resets the in-memory translations table
00717      * @return void
00718      */
00719     static function resetGlobals()
00720     {
00721         unset( $GLOBALS['eZTSTranslationTables'] );
00722         unset( $GLOBALS['eZTranslationCacheTable'] );
00723     }
00724 
00725     /**
00726      * Expires the translation cache
00727      *
00728      * @param int $timestamp An optional timestamp cache should be exired from. Current timestamp used by default
00729      * @param string $locale Optional translation's locale to expire specifically. Expires global ts cache by default.
00730      *
00731      * @return void
00732      */
00733     public static function expireCache( $timestamp = false, $locale = null )
00734     {
00735         eZExpiryHandler::registerShutdownFunction();
00736 
00737         if ( $timestamp === false )
00738             $timestamp = time();
00739 
00740         $handler = eZExpiryHandler::instance();
00741         if ( $locale )
00742             $handler->setTimestamp( self::EXPIRY_KEY . '-' . $locale, $timestamp );
00743         else
00744             $handler->setTimestamp( self::EXPIRY_KEY, $timestamp );
00745         $handler->store();
00746         self::resetGlobals();
00747     }
00748 
00749     /**
00750      * Contains the hash table with message translations
00751      * @var array
00752      */
00753     public $Messages;
00754     public $File;
00755     public $UseCache;
00756     public $BuildCache;
00757     public $CachedMessages;
00758 
00759     /**
00760      * Translation expiry key used by eZExpiryHandler to manage translation caches
00761      */
00762     const EXPIRY_KEY = 'ts-translation-cache';
00763 }
00764 
00765 ?>