*/ public function list(): array { $files = is_dir($this->dir) ? scandir($this->dir) : []; $out = []; foreach ($files === false ? [] : $files as $file) { $path = "{$this->dir}/{$file}"; if (!self::isValidName($file) || !is_file($path)) { continue; } $out[] = ['file' => $file, 'bytes' => (int) filesize($path), 'updatedAt' => (int) filemtime($path)]; } usort($out, static fn (array $a, array $b): int => strcmp($a['file'], $b['file'])); return $out; } /** The module's source, or null when there is no such plugin. */ public function read(string $file): ?string { $path = "{$this->dir}/{$file}"; if (!self::isValidName($file) || !is_file($path)) { return null; } $source = file_get_contents($path); return $source === false ? null : $source; } }