Add checks & realpath() usage

- New util class "FileSystem"
- Add check in admin summary too
This commit is contained in:
Philipp Holzer 2019-10-22 22:47:37 +02:00
parent 0e84a843a4
commit 6b2c28e2d7
No known key found for this signature in database
GPG key ID: D8365C3D36B77D90
5 changed files with 129 additions and 60 deletions

64
src/Util/FileSystem.php Normal file
View file

@ -0,0 +1,64 @@
<?php
namespace Friendica\Util;
final class FileSystem
{
/**
* @var string a error message
*/
private $errorMessage;
public function createDir(string $file)
{
$dirname = null;
$pos = strpos($file, '://');
if (!$pos) {
$dirname = realpath(dirname($file));
}
if (substr($file, 0, 7) === 'file://') {
$dirname = realpath(dirname(substr($file, 7)));
}
if (isset($dirname) && !is_dir($dirname)) {
set_error_handler([$this, 'customErrorHandler']);
$status = mkdir($dirname, 0777, true);
restore_error_handler();
if (!$status && !is_dir($dirname)) {
throw new \UnexpectedValueException(sprintf('Directory "%s" cannot get created: ' . $this->errorMessage, $dirname));
}
return $dirname;
} elseif (isset($dirname) && is_dir($dirname)) {
return $dirname;
} else {
return '';
}
}
public function createStream(string $url)
{
$directory = $this->createDir($url);
set_error_handler([$this, 'customErrorHandler']);
if (!empty($directory)) {
$url = $directory . DIRECTORY_SEPARATOR . pathinfo($url, PATHINFO_BASENAME);
}
$stream = fopen($url, 'ab');
restore_error_handler();
if (!is_resource($stream)) {
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $this->errorMessage, $url));
}
return $stream;
}
private function customErrorHandler($code, $msg)
{
$this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
}
}

View file

@ -3,6 +3,7 @@
namespace Friendica\Util\Logger;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\FileSystem;
use Friendica\Util\Introspection;
use Psr\Log\LogLevel;
@ -35,11 +36,11 @@ class StreamLogger extends AbstractLogger
*/
private $pid;
/**
* An error message
* @var string
* @var FileSystem
*/
private $errorMessage;
private $fileSystem;
/**
* Translates LogLevel log levels to integer values
@ -63,8 +64,10 @@ class StreamLogger extends AbstractLogger
*
* @throws \Exception
*/
public function __construct($channel, $stream, Introspection $introspection, $level = LogLevel::DEBUG)
public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, $level = LogLevel::DEBUG)
{
$this->fileSystem = $fileSystem;
parent::__construct($channel, $introspection);
if (is_resource($stream)) {
@ -157,43 +160,6 @@ class StreamLogger extends AbstractLogger
throw new \LogicException('Missing stream URL.');
}
$this->createDir();
set_error_handler([$this, 'customErrorHandler']);
$this->stream = fopen($this->url, 'ab');
restore_error_handler();
if (!is_resource($this->stream)) {
$this->stream = null;
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: ' . $this->errorMessage, $this->url));
}
}
private function createDir()
{
$dirname = null;
$pos = strpos($this->url, '://');
if (!$pos) {
$dirname = dirname($this->url);
}
if (substr($this->url, 0, 7) === 'file://') {
$dirname = dirname(substr($this->url, 7));
}
if (isset($dirname) && !is_dir($dirname)) {
set_error_handler([$this, 'customErrorHandler']);
$status = mkdir($dirname, 0777, true);
restore_error_handler();
if (!$status && !is_dir($dirname)) {
throw new \UnexpectedValueException(sprintf('Directory "%s" cannot get created: ' . $this->errorMessage, $dirname));
}
}
}
private function customErrorHandler($code, $msg)
{
$this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
$this->stream = $this->fileSystem->createStream($this->url);
}
}