PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Internationalization » Translation2 » Bug #2256

Cache flushing/write update

Details

Request #2256Cache flushing/write update
Submitted2004-08-31 03:10 UTC
Frommatthewh at meta-bit dot com
Assignedquipo
StatusClosed
PackageTranslation2
PHP Version4.3.6
OSWinXP
Roadmaps(Not assigned)

Comments

[2004-08-31 03:10 UTC] matthewh at meta-bit dot com

Description:
------------
The current Translation2 Decorator CacheMemory, does not provide a facility to flush/purge the cache.

This is required in order to re-read strings after the Translation2_Admin class has added,updated or removed a string.

A similar flush method should possibly be provided on the CacheLiteFunction Translation2 Decorator too. For example, allowing invocation of the underlying CacheLite::clean() method.

Reproduce code:
---------------
// Init. an Admin + Cache.
$admin =& new Translation2_Admin( .... );
$translation2 =& $translation2->getDecorator('CacheMemory');
// Retrieve something...[populates cache]
$initialString = $translation2->get( $id, $page, 'en' );
// Now update that string
$dirtyList = array( 'en' => 'new ');
// Update dbase..
$admin->add( $id, $page, $dirtyList );
// Dbase + Cache are now out of sync.
$staleString = $translation2->get( $id, $page, 'en' );
// assert: $staleString != 'new'
// Want to be able to do this - flush the cache...
$translation2->flush( $page, 'en' );
$correctString = $translation2->get( $id, $page, 'en' );
// assert: $correctString == 'new'
--------------------------------------------------------
Similarly, a Translation2_Decorator_CacheLiteFunction instance could delegate the flush() to the underlying clean() method within its CacheLiteFunction member.

Expected result:
----------------
* After flushing the cache, the given page of strings are cleared.

* Subsequent retrieves from the cache populate it with the newly updated strings.

Actual result:
--------------
* Currently, once the strings are loaded into the CacheMemory decorator, there's no way to clear the cache and re-read them after an update/addition/removal of a string.

* Same applies with Translation2_Decorator_CacheLiteFunction - no easy way to flush/purge cache.

[2004-08-31 11:46 UTC] matthewh at meta-bit dot com

I'd like to contribute some source that extends the current Translation2 Decorator framework with the flush methods discussed in the previous comment. This code seems to be working within my current application:
-------------------------------------------------------
<?php

/**
* @package Translation2
* @version $Id$
*/
/**
* Load Translation2 decorator CacheMemory base class
*/
require_once 'Translation2/Decorator/CacheMemory.php';

/**
* Decorator to cache fetched data in memory + allow flushing of the cache
* after a write/delete operation.
*
* @package Translation2
* @access public
*/
class Translation2_Decorator_FlushableCacheMemory extends Translation2_Decorator_CacheMemory
{

// NB: Assumes parent members were protected members...poor OO style...
// Possibly rewrite this to decorate the decorator + just replicate the attribs here.

/**
* MIH: Delete strings out of the cache.
*
* Use this if strings are written to the translation tables (ie, via
* Translation2_Admin). Ensures the cache entries don't become stale.
*
* @param string pageID the page of translation strings to flush
* @param string langID the translation string language, en, ja etc.
**/
function flushPage( $pageID=TRANSLATION2_DEFAULT_PAGEID, $langID=null )
{
$pageID_key = $this->_getPageIDKey($pageID);
$langID_key = empty($langID) ? $this->translation2->lang['id'] : $langID;

if (
(array_key_exists($langID_key, $this->data)) &&
(array_key_exists($pageID_key, $this->data[$langID_key]))
)
{
// MIH
// error_log( "flushPage(): Flushing ".count( $this->data[$langID_key][$pageID_key] )." values ", 0 );
unset( $this->data[$langID_key][$pageID_key] );
}

if (
(array_key_exists($langID_key, $this->rawData)) &&
(array_key_exists($pageID_key, $this->rawData[$langID_key]))
)
{
// error_log( "flushPage(): Flushing ".count( $this->rawData[$langID_key][$pageID_key] )." raw values ", 0 );
unset( $this->rawData[$langID_key][$pageID_key] );
}
}

/**
* MIH: Flushes a page for several languages
*
* Iterates over all languages in the nominated list and purges the
* corresponding page's strings from the cache.
*
* Use this method after writing a new set of strings to the cache.
*
* @param string pageID page name to purge from cache.
* @param array langList array of locales to purge: en, ja etc.
*
**/
function flushPages( $pageID=TRANSLATION2_DEFAULT_PAGEID, $langList )
{
// error_log( "flushPages()", 0 );
if (is_array( $langList ))
{
foreach( $langList as $langID)
{
// error_log( "flushPages(): Flushing: page:".$pageID." lang:".$langID, 0 );
$this->flushPage( $pageID, $langID );
}
}
// else
// error_log( "flushPages(): Error : bad arg:".var_export( $langList, true ), 0 );
}

/**
* Delete all cached strings.
*
**/
function flushAll()
{
$this->rawData = array();
$this->data = array();
}

// }}}
}
?>
-------------------------------------------
Instantiation is via :
$myTranslation2->getDecorator('FlushableCacheMemory');

------
Invocation via:
if (method_exists( $this->_translation2, "flushPages" ))
{
$localeList = $this->getAvailableLocales();
// flush all locales for nominated page...
$this->m_trRef->flushPages( $pageID, $localeList );
}
// subsequent reads from the stringsd cache (with Translation2::get()) will repopulate the cache.