Laurent W. Laurent W. - 6 months ago 16
PHP Question

Symfony1.4 : Clearing cache across applications with internal URI

From the documentation (by the way, where is the 1.4 version?!), I've tried this code to delete a frontend cache page, from the backend app:

$frontend_cache_dir = sfConfig::get('sf_cache_dir').DIRECTORY_SEPARATOR.'frontend'.DIRECTORY_SEPARATOR.sfConfig::get('sf_environment').DIRECTORY_SEPARATOR.'template';
$cache = new sfFileCache(array('cache_dir' => $frontend_cache_dir));
$cache->removePattern($uri);


It does nothing. So I've dug in the source code, and here is the
removePattern
function :

public function removePattern($pattern)
{
if (false !== strpos($pattern, '**'))
{
$pattern = str_replace(sfCache::SEPARATOR, DIRECTORY_SEPARATOR, $pattern).self::EXTENSION;

$regexp = self::patternToRegexp($pattern);
$paths = array();
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->getOption('cache_dir'))) as $path)
{
if (preg_match($regexp, str_replace($this->getOption('cache_dir').DIRECTORY_SEPARATOR, '', $path)))
{
$paths[] = $path;
}
}
}
else
{
$paths = glob($this->getOption('cache_dir').DIRECTORY_SEPARATOR.str_replace(sfCache::SEPARATOR, DIRECTORY_SEPARATOR, $pattern).self::EXTENSION);
}

foreach ($paths as $path)
{
if (is_dir($path))
{
sfToolkit::clearDirectory($path);
}
else
{
@unlink($path);
}
}
}


Of course, it can't work, because it does not generate a cache key, like the
remove
function of the cache manager does.

The
$path
variable should be something like this :
/home/.../cache/frontend/dev/template/localhost/all/module/action/key1/value1/key2/value2.cache


And I ended up with this :
/home/.../cache/frontend/dev/template/module/action?key1=value1&key2=value2.cache


This
$path
variable does not include the hostname and the vary headers.

Moreover, all the parameters (
key1=value1&key2=value2
) are not converted into
/key1/value1/key2/value2


How can I solve this problem without hacking the Symfony's core ?

Answer

I fixed this switching contexts. The documentation is definitly wrong.

sfContext::switchTo('frontend');
sfContext::getInstance()->getViewCacheManager()->remove($uri);
sfContext::switchTo('backend');

Thanks to jeremy