Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
162
src/Framework/Filesystem/PermissionChecker.php
Normal file
162
src/Framework/Filesystem/PermissionChecker.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Filesystem;
|
||||
|
||||
/**
|
||||
* Helper-Klasse für Filesystem-Permissions-Checks
|
||||
*/
|
||||
final readonly class PermissionChecker
|
||||
{
|
||||
public function __construct(
|
||||
private Storage $storage
|
||||
) {
|
||||
}
|
||||
|
||||
private function resolvePath(string $path): string
|
||||
{
|
||||
// Use reflection to access resolvePath from FileStorage
|
||||
// or implement basic path resolution logic
|
||||
if (method_exists($this->storage, 'resolvePath')) {
|
||||
$reflection = new \ReflectionMethod($this->storage, 'resolvePath');
|
||||
|
||||
return $reflection->invoke($this->storage, $path);
|
||||
}
|
||||
|
||||
// Fallback: return path as-is if storage doesn't have resolvePath
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function isDirectoryWritable(string $path): bool
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
if (! is_dir($resolvedPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_writable($resolvedPath);
|
||||
}
|
||||
|
||||
public function canCreateDirectory(string $path): bool
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
// Prüfe, ob Parent-Directory existiert und schreibbar ist
|
||||
$parentDir = dirname($resolvedPath);
|
||||
|
||||
if (! is_dir($parentDir)) {
|
||||
return $this->canCreateDirectory(dirname($path));
|
||||
}
|
||||
|
||||
return is_writable($parentDir);
|
||||
}
|
||||
|
||||
public function canWriteFile(string $path): bool
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
// Wenn Datei existiert, prüfe ob sie schreibbar ist
|
||||
if (file_exists($resolvedPath)) {
|
||||
return is_writable($resolvedPath);
|
||||
}
|
||||
|
||||
// Wenn Datei nicht existiert, prüfe ob Directory schreibbar ist
|
||||
$dir = dirname($path);
|
||||
|
||||
return $this->isDirectoryWritable($dir) || $this->canCreateDirectory($dir);
|
||||
}
|
||||
|
||||
public function canReadFile(string $path): bool
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
|
||||
return file_exists($resolvedPath) && is_readable($resolvedPath);
|
||||
}
|
||||
|
||||
public function canDeleteFile(string $path): bool
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
if (! file_exists($resolvedPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Datei muss schreibbar sein UND Directory muss schreibbar sein
|
||||
$dir = dirname($resolvedPath);
|
||||
|
||||
return is_writable($resolvedPath) && is_writable($dir);
|
||||
}
|
||||
|
||||
public function getPermissionString(string $path): string
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
if (! file_exists($resolvedPath)) {
|
||||
return 'not found';
|
||||
}
|
||||
|
||||
$perms = fileperms($resolvedPath);
|
||||
$info = '';
|
||||
|
||||
// Type
|
||||
if (($perms & 0xC000) == 0xC000) {
|
||||
$info = 's'; // Socket
|
||||
} elseif (($perms & 0xA000) == 0xA000) {
|
||||
$info = 'l'; // Symbolic Link
|
||||
} elseif (($perms & 0x8000) == 0x8000) {
|
||||
$info = 'f'; // Regular file
|
||||
} elseif (($perms & 0x6000) == 0x6000) {
|
||||
$info = 'b'; // Block special
|
||||
} elseif (($perms & 0x4000) == 0x4000) {
|
||||
$info = 'd'; // Directory
|
||||
} elseif (($perms & 0x2000) == 0x2000) {
|
||||
$info = 'c'; // Character special
|
||||
} elseif (($perms & 0x1000) == 0x1000) {
|
||||
$info = 'p'; // FIFO pipe
|
||||
} else {
|
||||
$info = 'u'; // Unknown
|
||||
}
|
||||
|
||||
// Owner
|
||||
$info .= (($perms & 0x0100) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0080) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0040) ?
|
||||
(($perms & 0x0800) ? 's' : 'x') :
|
||||
(($perms & 0x0800) ? 'S' : '-'));
|
||||
|
||||
// Group
|
||||
$info .= (($perms & 0x0020) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0010) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0008) ?
|
||||
(($perms & 0x0400) ? 's' : 'x') :
|
||||
(($perms & 0x0400) ? 'S' : '-'));
|
||||
|
||||
// World
|
||||
$info .= (($perms & 0x0004) ? 'r' : '-');
|
||||
$info .= (($perms & 0x0002) ? 'w' : '-');
|
||||
$info .= (($perms & 0x0001) ?
|
||||
(($perms & 0x0200) ? 't' : 'x') :
|
||||
(($perms & 0x0200) ? 'T' : '-'));
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function getDiagnosticInfo(string $path): array
|
||||
{
|
||||
$resolvedPath = $this->resolvePath($path);
|
||||
$realPath = realpath($resolvedPath) ?: $resolvedPath;
|
||||
|
||||
return [
|
||||
'path' => $path,
|
||||
'resolved_path' => $resolvedPath,
|
||||
'real_path' => $realPath,
|
||||
'exists' => file_exists($resolvedPath),
|
||||
'is_file' => is_file($resolvedPath),
|
||||
'is_dir' => is_dir($resolvedPath),
|
||||
'is_readable' => is_readable($resolvedPath),
|
||||
'is_writable' => is_writable($resolvedPath),
|
||||
'permissions' => $this->getPermissionString($path),
|
||||
'owner' => file_exists($resolvedPath) ? posix_getpwuid(fileowner($resolvedPath))['name'] ?? 'unknown' : null,
|
||||
'group' => file_exists($resolvedPath) ? posix_getgrgid(filegroup($resolvedPath))['name'] ?? 'unknown' : null,
|
||||
'parent_dir' => dirname($resolvedPath),
|
||||
'parent_writable' => is_dir(dirname($resolvedPath)) ? is_writable(dirname($resolvedPath)) : false,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user