<?php

// uglyyyyy... cannot override, so Registry pattern?! it's a sample only, lucky
define('CACHE_ENGINE_FILE_PATH''./cache/*.tmp');

class 
Cache_Engine_File implements Cache_Engine
{
  protected
    
$_oParent null;
  
  protected
    
$_oProcessWrite null;
  
  public function 
__construct(Cache $oParent)
  {
    
$this->_oParent $oParent;
  }
  
  public function 
exists()
  {
    if(
is_file($sPath $this->_path()))
      return 
false;
    
    return 
$sPath;
  }
  
  public function 
expired($iExpirityTime)
  {
    if(!(
$sPath $this->exists()) || (filemtime($sPath) + $iExpirityTime) < time())
      return 
true;
    
    return 
false;
  }
  
  public function 
delete()
  {
    if(!(
$sPath $this->exists()))
      return 
false;
    
    return 
unlink($sPath);
  }
  
  public function 
load($iTimeout null)
  {
    
$this->_waitUnlock($iTimeout);
    
    if(!(
$sPath $this->exists()))
      return 
false;
    
    if(!(
$iFile filesize($sPath)))
      return 
false;
    
    if(!
$oFile fopen($sPath'r'))
      return 
false;
    
    if(!
flock($oFileLOCK_SH))
      throw new 
Cache_Exception_Runtime('Cannot obtain read lock for file cache');
    
    if(
$iFile && !($mContents fread($oFile$iFile)))
      
$mContents false;
    
    
flock($oFileLOCK_UN);
    
fclose($oFile);
    
    return 
unserialize($mContents);
  }
  
  public function 
savePrepare($iTimeout null)
  {
    
$this->_waitUnlock($iTimeout);
    
    
$sPath $this->_path(true);
    
$this->_oProcessWrite fopen($sPath'w+');
    
    if(!
flock($this->_oProcessWriteLOCK_EX))
      throw new 
Cache_Exception_Runtime('Cannot obtain write lock for file cache');
    
    return 
true;
  }
  
  public function 
save($mContent$bAutofinalize true)
  {
    if(!
$this->_oProcessWrite)
      
$this->savePrepare();
    
    
$mContents serialize($mContents);
    
    
fwrite($this->_oProcessWrite, (string)$mContents);
    
    if(
$bAutofinalize)
      
$this->saveFinalize();
    
    return 
$bResult;
  }
  
  public function 
saveFinalize()
  {
    
flock($this->_oProcessWriteLOCK_UN);
    
fclose($this->_oProcessWrite);
    
    return 
true;
  }
  
  protected function 
_waitUnlock($iTimeout null)
  {
    if(
$iTimeout === null)
      
$iTimeout 500000// useconds
    
    
return true// no lock... flock() is in use
  
}
  
  protected function 
_path($bAutogenerateDirectoryZonePath false)
  {
    if(
$bAutogenerateDirectoryZonePath)
    {
      
// @todo
      // .. generate the path by mkdir() if does not exists
    
}
    
    
$sPath dirname(CACHE_ENGINE_FILE_PATH);
    
    foreach(
$this->_oParent->_aZonePath as $sItem)
      if(!
is_dir($sPath .= $sItem '/'))
        throw new 
Cache_Exception_Runtime('Cache path does not exists at ' $sPath '.');
    
    
$sPath str_replace('*'$this->_oParent->_sZonebasename(CACHE_ENGINE_FILE_PATH));
    return 
$sPath;
  }
  
  
// @todo
  
  
public function deleteGroup($sZone)
  {
  }
}