180 lines
6.2 KiB
PHP
180 lines
6.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Filesystem;
|
|
|
|
use App\Framework\Filesystem\ValueObjects\FilePath;
|
|
use App\Framework\Logging\Logger;
|
|
use ReflectionClass;
|
|
|
|
/**
|
|
* Factory für Filesystem-Objekte mit Lazy-Loading-Unterstützung.
|
|
*/
|
|
final readonly class FilesystemFactory
|
|
{
|
|
public function __construct(
|
|
private ?Logger $logger = null
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Erstellt eine neue FilesystemFactory-Instanz mit Logger.
|
|
*
|
|
* @param Logger|null $logger Optional logger instance
|
|
* @return self
|
|
*/
|
|
public static function create(?Logger $logger = null): self
|
|
{
|
|
return new self($logger);
|
|
}
|
|
|
|
/**
|
|
* Erstellt ein File-Objekt mit Lazy-Loading für schwere Eigenschaften.
|
|
*
|
|
* @param FilePath|string $path Pfad zur Datei
|
|
* @param Storage $storage Storage-Implementierung
|
|
* @param int|null $cacheTimeoutSeconds Optional, Zeit in Sekunden, nach der der Cache ungültig wird
|
|
* @param bool $lazyLoad Optional, ob Lazy-Loading verwendet werden soll
|
|
*/
|
|
public function createFile(
|
|
FilePath|string $path,
|
|
Storage $storage,
|
|
?int $cacheTimeoutSeconds = null,
|
|
bool $lazyLoad = true
|
|
): File {
|
|
$pathString = $path instanceof FilePath ? $path->toString() : $path;
|
|
|
|
// Direkte Instanziierung ohne Lazy-Loading
|
|
if (! $lazyLoad) {
|
|
$this->logger?->debug("Erstelle File-Objekt ohne Lazy-Loading: {$pathString}");
|
|
|
|
// Nur laden wenn die Datei existiert
|
|
if (! $storage->exists($pathString)) {
|
|
return new File($path, $storage);
|
|
}
|
|
|
|
return new File(
|
|
path: $path,
|
|
storage: $storage,
|
|
contents: $storage->get($pathString),
|
|
size: $storage->size($pathString),
|
|
lastModified: $storage->lastModified($pathString)
|
|
);
|
|
}
|
|
|
|
$reflection = new ReflectionClass(File::class);
|
|
$loadTime = time();
|
|
$logger = $this->logger;
|
|
|
|
// LazyProxy verwenden für individuelle Property-Callbacks
|
|
return $reflection->newLazyProxy([
|
|
// Dateiinhalt wird erst beim ersten Zugriff geladen
|
|
'contents' => function (File $file) use ($loadTime, $cacheTimeoutSeconds, $logger) {
|
|
$pathStr = $file->getPathString();
|
|
$logger?->debug("Lazy-Loading contents für {$pathStr}");
|
|
|
|
// Cache-Invalidierung basierend auf Zeit
|
|
if ($cacheTimeoutSeconds !== null && time() - $loadTime > $cacheTimeoutSeconds) {
|
|
$logger?->debug("Cache-Timeout erreicht für {$pathStr}, lade neu");
|
|
}
|
|
|
|
if (! $file->exists()) {
|
|
$logger?->debug("Datei existiert nicht: {$pathStr}");
|
|
|
|
return '';
|
|
}
|
|
|
|
return $file->storage->get($pathStr);
|
|
},
|
|
|
|
// Dateigröße wird erst beim ersten Zugriff ermittelt
|
|
'size' => function (File $file) use ($loadTime, $cacheTimeoutSeconds, $logger) {
|
|
$pathStr = $file->getPathString();
|
|
$logger?->debug("Lazy-Loading size für {$pathStr}");
|
|
|
|
// Cache-Invalidierung basierend auf Zeit
|
|
if ($cacheTimeoutSeconds !== null && time() - $loadTime > $cacheTimeoutSeconds) {
|
|
$logger?->debug("Cache-Timeout erreicht für {$pathStr}, lade neu");
|
|
}
|
|
|
|
if (! $file->exists()) {
|
|
$logger?->debug("Datei existiert nicht: {$pathStr}");
|
|
|
|
return 0;
|
|
}
|
|
|
|
return $file->storage->size($pathStr);
|
|
},
|
|
|
|
// Zeitstempel wird erst beim ersten Zugriff ermittelt
|
|
'lastModified' => function (File $file) use ($loadTime, $cacheTimeoutSeconds, $logger) {
|
|
$pathStr = $file->getPathString();
|
|
$logger?->debug("Lazy-Loading lastModified für {$pathStr}");
|
|
|
|
// Cache-Invalidierung basierend auf Zeit
|
|
if ($cacheTimeoutSeconds !== null && time() - $loadTime > $cacheTimeoutSeconds) {
|
|
$logger?->debug("Cache-Timeout erreicht für {$pathStr}, lade neu");
|
|
}
|
|
|
|
if (! $file->exists()) {
|
|
$logger?->debug("Datei existiert nicht: {$pathStr}");
|
|
|
|
return 0;
|
|
}
|
|
|
|
return $file->storage->lastModified($pathStr);
|
|
},
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Erstellt ein Directory-Objekt mit Lazy-Loading für schwere Eigenschaften.
|
|
*
|
|
* @param FilePath|string $path Pfad zum Verzeichnis
|
|
* @param Storage $storage Storage-Implementierung
|
|
* @param bool $lazyLoad Optional, ob Lazy-Loading verwendet werden soll
|
|
*/
|
|
public function createDirectory(
|
|
FilePath|string $path,
|
|
Storage $storage,
|
|
bool $lazyLoad = true
|
|
): Directory {
|
|
$pathString = $path instanceof FilePath ? $path->toString() : $path;
|
|
|
|
// Direkte Instanziierung ohne Lazy-Loading
|
|
if (! $lazyLoad) {
|
|
$this->logger?->debug("Erstelle Directory-Objekt ohne Lazy-Loading: {$pathString}");
|
|
|
|
$contents = [];
|
|
if (is_dir($pathString)) {
|
|
$contents = $storage->listDirectory($pathString);
|
|
}
|
|
|
|
return new Directory($path, $storage, $contents);
|
|
}
|
|
|
|
$reflection = new ReflectionClass(Directory::class);
|
|
$logger = $this->logger;
|
|
|
|
// LazyGhost verwenden - alle Eigenschaften werden beim ersten Zugriff initialisiert
|
|
$lazyDir = $reflection->newLazyGhost(
|
|
// Initializer-Callback
|
|
function (Directory $directory) use ($logger): void {
|
|
$pathStr = $directory->getPathString();
|
|
$logger?->debug("Lazy-Loading Directory-Inhalt für {$pathStr}");
|
|
|
|
// Verzeichnisinhalt wird erst beim ersten Zugriff auf eine Eigenschaft geladen
|
|
if ($directory->exists()) {
|
|
$directory->contents = $directory->storage->listDirectory($pathStr);
|
|
} else {
|
|
$directory->contents = [];
|
|
}
|
|
}
|
|
);
|
|
|
|
/** @var Directory $lazyDir */
|
|
return $lazyDir;
|
|
}
|
|
}
|