2014-02-14 17:28:11 +01:00
|
|
|
<?php
|
|
|
|
// {{{ICINGA_LICENSE_HEADER}}}
|
|
|
|
// {{{ICINGA_LICENSE_HEADER}}}
|
|
|
|
|
|
|
|
namespace Icinga\Util;
|
|
|
|
|
2014-06-26 15:53:14 +02:00
|
|
|
use SplFileObject;
|
2014-06-27 09:53:50 +02:00
|
|
|
use ErrorException;
|
2014-06-26 15:53:14 +02:00
|
|
|
use RuntimeException;
|
|
|
|
use Icinga\Exception\NotWritableError;
|
2014-06-23 13:18:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* File
|
|
|
|
*
|
|
|
|
* A class to ease opening files and reading/writing to them.
|
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
class File extends SplFileObject
|
2014-02-14 17:28:11 +01:00
|
|
|
{
|
2014-06-23 13:18:03 +02:00
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* The mode used to open the file
|
2014-06-23 13:18:03 +02:00
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
protected $openMode;
|
2014-06-23 13:18:03 +02:00
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::__construct()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function __construct($filename, $openMode = 'r', $useIncludePath = false, $context = null)
|
|
|
|
{
|
|
|
|
$this->openMode = $openMode;
|
|
|
|
if ($context === null) {
|
|
|
|
parent::__construct($filename, $openMode, $useIncludePath);
|
|
|
|
} else {
|
|
|
|
parent::__construct($filename, $openMode, $useIncludePath, $context);
|
|
|
|
}
|
|
|
|
}
|
2014-06-23 13:18:03 +02:00
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* Create a file with an access mode
|
2014-06-23 13:18:03 +02:00
|
|
|
*
|
2014-06-26 15:53:14 +02:00
|
|
|
* @param string $path The path to the file
|
|
|
|
* @param int $accessMode The access mode to set
|
2014-06-23 13:18:03 +02:00
|
|
|
*
|
2014-06-26 15:53:14 +02:00
|
|
|
* @throws RuntimeException In case the file cannot be created or the access mode cannot be set
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public static function create($path, $accessMode)
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
if (!@touch($path)) {
|
|
|
|
throw new RuntimeException('Cannot create file "' . $path . '" with acces mode "' . $accessMode . '"');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!@chmod($path, $accessMode)) {
|
|
|
|
throw new RuntimeException('Cannot set access mode "' . $accessMode . '" on file "' . $path . '"');
|
|
|
|
}
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::fwrite()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function fwrite($str, $length = null)
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
$this->assertOpenForWriting();
|
|
|
|
$this->setupErrorHandler();
|
|
|
|
$retVal = $length === null ? parent::fwrite($str) : parent::fwrite($str, $length);
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::ftruncate()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function ftruncate($size)
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
$this->assertOpenForWriting();
|
2014-06-23 13:18:03 +02:00
|
|
|
$this->setupErrorHandler();
|
2014-06-26 15:53:14 +02:00
|
|
|
$retVal = parent::ftruncate($size);
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
2014-06-23 15:01:52 +02:00
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::ftell()
|
2014-06-23 15:01:52 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function ftell()
|
2014-06-23 15:01:52 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
$this->setupErrorHandler();
|
|
|
|
$retVal = parent::ftell();
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 15:01:52 +02:00
|
|
|
}
|
|
|
|
|
2014-06-23 13:18:03 +02:00
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::flock()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function flock($operation, &$wouldblock = null)
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
|
|
|
$this->setupErrorHandler();
|
2014-06-26 15:53:14 +02:00
|
|
|
$retVal = parent::flock($operation, $wouldblock);
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::fgetc()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function fgetc()
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
$this->setupErrorHandler();
|
|
|
|
$retVal = parent::fgetc();
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* @see SplFileObject::fflush()
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
public function fflush()
|
2014-06-23 13:18:03 +02:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
$this->setupErrorHandler();
|
|
|
|
$retVal = parent::fflush();
|
|
|
|
restore_error_handler();
|
|
|
|
return $retVal;
|
2014-06-23 13:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* Setup an error handler that throws a RuntimeException for every emitted E_WARNING
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
|
|
|
protected function setupErrorHandler()
|
|
|
|
{
|
|
|
|
set_error_handler(
|
2014-06-27 09:53:50 +02:00
|
|
|
function ($errno, $errstr, $errfile, $errline) {
|
2014-06-26 15:53:14 +02:00
|
|
|
restore_error_handler();
|
2014-10-16 15:47:50 +02:00
|
|
|
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
2014-06-23 13:18:03 +02:00
|
|
|
},
|
|
|
|
E_WARNING
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-26 15:53:14 +02:00
|
|
|
* Assert that the file was opened for writing and throw an exception otherwise
|
|
|
|
*
|
|
|
|
* @throws NotWritableError In case the file was not opened for writing
|
2014-06-23 13:18:03 +02:00
|
|
|
*/
|
2014-06-26 15:53:14 +02:00
|
|
|
protected function assertOpenForWriting()
|
2014-02-14 17:28:11 +01:00
|
|
|
{
|
2014-06-26 15:53:14 +02:00
|
|
|
if (!preg_match('@w|a|\+@', $this->openMode)) {
|
|
|
|
throw new NotWritableError('File not open for writing');
|
|
|
|
}
|
2014-02-14 17:28:11 +01:00
|
|
|
}
|
2014-04-28 14:03:52 +02:00
|
|
|
}
|