checkDefType ( $def )) {
return;
}
$file = $this->generateFilePath ( $config );
if (file_exists ( $file )) {
return false;
}
if (! $this->_prepareDir ( $config )) {
return false;
}
return $this->_write ( $file, serialize ( $def ), $config );
}
/**
*
* @param HTMLPurifier_Definition $def
* @param HTMLPurifier_Config $config
* @return int|bool
*/
public function set($def, $config) {
if (! $this->checkDefType ( $def )) {
return;
}
$file = $this->generateFilePath ( $config );
if (! $this->_prepareDir ( $config )) {
return false;
}
return $this->_write ( $file, serialize ( $def ), $config );
}
/**
*
* @param HTMLPurifier_Definition $def
* @param HTMLPurifier_Config $config
* @return int|bool
*/
public function replace($def, $config) {
if (! $this->checkDefType ( $def )) {
return;
}
$file = $this->generateFilePath ( $config );
if (! file_exists ( $file )) {
return false;
}
if (! $this->_prepareDir ( $config )) {
return false;
}
return $this->_write ( $file, serialize ( $def ), $config );
}
/**
*
* @param HTMLPurifier_Config $config
* @return bool|HTMLPurifier_Config
*/
public function get($config) {
$file = $this->generateFilePath ( $config );
if (! file_exists ( $file )) {
return false;
}
return unserialize ( file_get_contents ( $file ) );
}
/**
*
* @param HTMLPurifier_Config $config
* @return bool
*/
public function remove($config) {
$file = $this->generateFilePath ( $config );
if (! file_exists ( $file )) {
return false;
}
return unlink ( $file );
}
/**
*
* @param HTMLPurifier_Config $config
* @return bool
*/
public function flush($config) {
if (! $this->_prepareDir ( $config )) {
return false;
}
$dir = $this->generateDirectoryPath ( $config );
$dh = opendir ( $dir );
while ( false !== ($filename = readdir ( $dh )) ) {
if (empty ( $filename )) {
continue;
}
if ($filename [0] === '.') {
continue;
}
unlink ( $dir . '/' . $filename );
}
}
/**
*
* @param HTMLPurifier_Config $config
* @return bool
*/
public function cleanup($config) {
if (! $this->_prepareDir ( $config )) {
return false;
}
$dir = $this->generateDirectoryPath ( $config );
$dh = opendir ( $dir );
while ( false !== ($filename = readdir ( $dh )) ) {
if (empty ( $filename )) {
continue;
}
if ($filename [0] === '.') {
continue;
}
$key = substr ( $filename, 0, strlen ( $filename ) - 4 );
if ($this->isOld ( $key, $config )) {
unlink ( $dir . '/' . $filename );
}
}
}
/**
* Generates the file path to the serial file corresponding to
* the configuration and definition name
*
* @param HTMLPurifier_Config $config
* @return string
* @todo Make protected
*/
public function generateFilePath($config) {
$key = $this->generateKey ( $config );
return $this->generateDirectoryPath ( $config ) . '/' . $key . '.ser';
}
/**
* Generates the path to the directory contain this cache's serial files
*
* @param HTMLPurifier_Config $config
* @return string @note No trailing slash
* @todo Make protected
*/
public function generateDirectoryPath($config) {
$base = $this->generateBaseDirectoryPath ( $config );
return $base . '/' . $this->type;
}
/**
* Generates path to base directory that contains all definition type
* serials
*
* @param HTMLPurifier_Config $config
* @return mixed|string
* @todo Make protected
*/
public function generateBaseDirectoryPath($config) {
$base = $config->get ( 'Cache.SerializerPath' );
$base = is_null ( $base ) ? HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer' : $base;
return $base;
}
/**
* Convenience wrapper function for file_put_contents
*
* @param string $file
* File name to write to
* @param string $data
* Data to write into file
* @param HTMLPurifier_Config $config
* @return int|bool Number of bytes written if success, or false if failure.
*/
private function _write($file, $data, $config) {
$result = file_put_contents ( $file, $data );
if ($result !== false) {
// set permissions of the new file (no execute)
$chmod = $config->get ( 'Cache.SerializerPermissions' );
if (! $chmod) {
$chmod = 0644; // invalid config or simpletest
}
$chmod = $chmod & 0666;
chmod ( $file, $chmod );
}
return $result;
}
/**
* Prepares the directory that this type stores the serials in
*
* @param HTMLPurifier_Config $config
* @return bool True if successful
*/
private function _prepareDir($config) {
$directory = $this->generateDirectoryPath ( $config );
$chmod = $config->get ( 'Cache.SerializerPermissions' );
if (! $chmod) {
$chmod = 0755; // invalid config or simpletest
}
if (! is_dir ( $directory )) {
$base = $this->generateBaseDirectoryPath ( $config );
if (! is_dir ( $base )) {
trigger_error ( 'Base directory ' . $base . ' does not exist,
please create or change using %Cache.SerializerPath', E_USER_WARNING );
return false;
} elseif (! $this->_testPermissions ( $base, $chmod )) {
return false;
}
$old = umask ( 0000 );
mkdir ( $directory, $chmod );
umask ( $old );
} elseif (! $this->_testPermissions ( $directory, $chmod )) {
return false;
}
return true;
}
/**
* Tests permissions on a directory and throws out friendly
* error messages and attempts to chmod it itself if possible
*
* @param string $dir
* Directory path
* @param int $chmod
* Permissions
* @return bool True if directory is writable
*/
private function _testPermissions($dir, $chmod) {
// early abort, if it is writable, everything is hunky-dory
if (is_writable ( $dir )) {
return true;
}
if (! is_dir ( $dir )) {
// generally, you'll want to handle this beforehand
// so a more specific error message can be given
trigger_error ( 'Directory ' . $dir . ' does not exist', E_USER_WARNING );
return false;
}
if (function_exists ( 'posix_getuid' )) {
// POSIX system, we can give more specific advice
if (fileowner ( $dir ) === posix_getuid ()) {
// we can chmod it ourselves
$chmod = $chmod | 0700;
if (chmod ( $dir, $chmod )) {
return true;
}
} elseif (filegroup ( $dir ) === posix_getgid ()) {
$chmod = $chmod | 0070;
} else {
// PHP's probably running as nobody, so we'll
// need to give global permissions
$chmod = $chmod | 0777;
}
trigger_error ( 'Directory ' . $dir . ' not writable, ' . 'please chmod to ' . decoct ( $chmod ), E_USER_WARNING );
} else {
// generic error message
trigger_error ( 'Directory ' . $dir . ' not writable, ' . 'please alter file permissions', E_USER_WARNING );
}
return false;
}
}
// vim: et sw=4 sts=4