Cache_File
Kohana_Cache_File
Cache
Kohana_Cache

Class Contents

Class declared in MODPATH/cache/classes/cache/file.php on line 3.

Constants

DEFAULT_EXPIRE
integer 3600

Properties

public static $default
string(4) "file"
public static $instances
array(0) 

Methods

protected __construct( )
Kohana_Cache_File

Source Code
protected function __construct(array $config)
{
	// Setup parent
	parent::__construct($config);

	try
	{
		$directory = Arr::get($this->_config, 'cache_dir', Kohana::$cache_dir);
		$this->_cache_dir = new SplFileInfo($directory);
	}
	// PHP < 5.3 exception handle
	catch (ErrorException $e)
	{
		$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
	}
	// PHP >= 5.3 exception handle
	catch (UnexpectedValueException $e)
	{
		$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE);
	}

	// If the defined directory is a file, get outta here
	if ($this->_cache_dir->isFile())
	{
		throw new Kohana_Cache_Exception('Unable to create cache directory as a file already exists : :resource', array(':resource' => $this->_cache_dir->getRealPath()));
	}

	// Check the read status of the directory
	if ( ! $this->_cache_dir->isReadable())
	{
		throw new Kohana_Cache_Exception('Unable to read from the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
	}

	// Check the write status of the directory
	if ( ! $this->_cache_dir->isWritable())
	{
		throw new Kohana_Cache_Exception('Unable to write to the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
	}
}

protected _delete_file( )
Kohana_Cache_File

Source Code
protected function _delete_file(SplFileInfo $file, $retain_parent_directory = FALSE, $ignore_errors = FALSE, $only_expired = FALSE)
{
	// Allow graceful error handling
	try
	{
		// If is file
		if ($file->isFile())
		{
			try
			{
				// If only expired is not set
				if ($only_expired === FALSE)
				{
					// We want to delete the file
					$delete = TRUE;
				}
				// Otherwise...
				else
				{
					// Assess the file expiry to flag it for deletion
					$json = $file->openFile('r')->current();
					$data = json_decode($json);
					$delete = $data->expiry < time();
				}

				// If the delete flag is set
				if ($delete === TRUE)
				{
					// Try to delete
					unlink($file->getRealPath());
				}
			}
			catch (ErrorException $e)
			{
				// Catch any delete file warnings
				if ($e->getCode() === E_WARNING)
				{
					throw new Kohana_Cache_Exception(__METHOD__.' failed to delete file : :file', array(':file' => $file->getRealPath()));
				}
			}
		}
		// Else, is directory
		elseif ($file->isDir())
		{
			// Create new DirectoryIterator
			$files = new DirectoryIterator($file->getPathname());

			// Iterate over each entry
			while ($files->valid())
			{
				// Extract the entry name
				$name = $files->getFilename();

				// If the name is not a dot
				if ($name != '.' and $name != '..')
				{
					// Create new file resource
					$fp = new SplFileInfo($files->getRealPath());
					// Delete the file
					$this->_delete_file($fp);
				}

				// Move the file pointer on
				$files->next();
			}

			// If set to retain parent directory, return now
			if ($retain_parent_directory)
			{
				return TRUE;
			}

			try
			{
				// Remove the files iterator
				// (fixes Windows PHP which has permission issues with open iterators)
				unset($files);

				// Try to remove the parent directory
				return rmdir($file->getRealPath());
			}
			catch (ErrorException $e)
			{
				// Catch any delete directory warnings
				if ($e->getCode() === E_WARNING)
				{
					throw new Kohana_Cache_Exception(__METHOD__.' failed to delete directory : :directory', array(':directory' => $file->getRealPath()));
				}
			}
		}
	}
	// Catch all exceptions
	catch (Exception $e)
	{
		// If ignore_errors is on
		if ($ignore_errors === TRUE)
		{
			// Return
			return FALSE;
		}
		// Throw exception
		throw $e;
	}
}

protected _make_directory( )
Kohana_Cache_File

Source Code
protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL)
{
	if ( ! mkdir($directory, $mode, $recursive, $context))
	{
		throw new Kohana_Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
	}
	chmod($directory, $mode);

	return new SplFileInfo($directory);;
}

protected _resolve_directory( )
Kohana_Cache_File

Source Code
protected function _resolve_directory($filename)
{
	return $this->_cache_dir->getRealPath().DIRECTORY_SEPARATOR.$filename[0].$filename[1].DIRECTORY_SEPARATOR;
}

public delete( )
Kohana_Cache_File

Source Code
public function delete($id)
{
	$filename = Cache_File::filename($this->_sanitize_id($id));
	$directory = $this->_resolve_directory($filename);

	return $this->_delete_file(new SplFileInfo($directory.$filename), NULL, TRUE);
}

public delete_all( )
Kohana_Cache_File

Source Code
public function delete_all()
{
	return $this->_delete_file($this->_cache_dir, TRUE);
}

protected static filename( )
Kohana_Cache_File

Source Code
protected static function filename($string)
{
	return sha1($string).'.json';
}

public garbage_collect( )
Kohana_Cache_File

Source Code
public function garbage_collect()
{
	$this->_delete_file($this->_cache_dir, TRUE, FALSE, TRUE);
	return;
}

public get( )
Kohana_Cache_File

Source Code
public function get($id, $default = NULL)
{
	$filename = Cache_File::filename($this->_sanitize_id($id));
	$directory = $this->_resolve_directory($filename);

	// Wrap operations in try/catch to handle notices
	try
	{
		// Open file
		$file = new SplFileInfo($directory.$filename);

		// If file does not exist
		if ( ! $file->isFile())
		{
			// Return default value
			return $default;
		}
		else
		{
			// Open the file and extract the json
			$json = $file->openFile()->current();

			// Decode the json into PHP object
			$data = json_decode($json);

			// Test the expiry
			if ($data->expiry < time())
			{
				// Delete the file
				$this->_delete_file($file, NULL, TRUE);

				// Return default value
				return $default;
			}
			else
			{
				return ($data->type === 'string') ? $data->payload : unserialize($data->payload);
			}
		}
		
	}
	catch (ErrorException $e)
	{
		// Handle ErrorException caused by failed unserialization
		if ($e->getCode() === E_NOTICE)
		{
			throw new Kohana_Cache_Exception(__METHOD__.' failed to unserialize cached object with message : '.$e->getMessage());
		}

		// Otherwise throw the exception
		throw $e;
	}
}

public set( )
Kohana_Cache_File

Source Code
public function set($id, $data, $lifetime = NULL)
{
	$filename = Cache_File::filename($this->_sanitize_id($id));
	$directory = $this->_resolve_directory($filename);

	// If lifetime is NULL
	if ($lifetime === NULL)
	{
		// Set to the default expiry
		$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE);
	}

	// Open directory
	$dir = new SplFileInfo($directory);

	// If the directory path is not a directory
	if ( ! $dir->isDir())
	{
		// Create the directory 
		if ( ! mkdir($directory, 0777, TRUE))
		{
			throw new Kohana_Cache_Exception(__METHOD__.' unable to create directory : :directory', array(':directory' => $directory));
		}

		// chmod to solve potential umask issues
		chmod($directory, 0777);
	}

	// Open file to inspect
	$resouce = new SplFileInfo($directory.$filename);
	$file = $resouce->openFile('w');

	try
	{
		$type = gettype($data);

		// Serialize the data
		$data = json_encode( (object) array(
			'payload'  => ($type === 'string') ? $data : serialize($data),
			'expiry'   => time() + $lifetime,
			'type'     => $type
		));

		$size = strlen($data);
	}
	catch (ErrorException $e)
	{
		// If serialize through an error exception
		if ($e->getCode() === E_NOTICE)
		{
			// Throw a caching error
			throw new Kohana_Cache_Exception(__METHOD__.' failed to serialize data for caching with message : '.$e->getMessage());
		}

		// Else rethrow the error exception
		throw $e;
	}

	try
	{
		$file->fwrite($data, $size);
		return (bool) $file->fflush();
	}
	catch (Exception $e)
	{
		throw $e;
	}
}

public __clone( )
Kohana_Cache

Source Code
public function __clone()
{
	throw new Kohana_Cache_Exception('Cloning of Kohana_Cache objects is forbidden');
}

protected _sanitize_id( )
Kohana_Cache

Source Code
protected function _sanitize_id($id)
{
	// Change slashes and spaces to underscores
	return str_replace(array('/', '\\', ' '), '_', $id);
}

public static instance( )
Kohana_Cache

Source Code
public static function instance($group = NULL)
{
	// If there is no group supplied
	if ($group === NULL)
	{
		// Use the default setting
		$group = Cache::$default;
	}

	if (isset(Cache::$instances[$group]))
	{
		// Return the current group if initiated already
		return Cache::$instances[$group];
	}

	$config = Kohana::config('cache');

	if ( ! $config->offsetExists($group))
	{
		throw new Kohana_Cache_Exception('Failed to load Kohana Cache group: :group', array(':group' => $group));
	}

	$config = $config->get($group);

	// Create a new cache type instance
	$cache_class = 'Cache_'.ucfirst($config['driver']);
	Cache::$instances[$group] = new $cache_class($config);

	// Return the instance
	return Cache::$instances[$group];
}