*/ public function list(): array { $files = is_dir($this->dir) ? scandir($this->dir) : []; $out = []; foreach ($files === false ? [] : $files as $file) { if ($this->exists($file)) { $path = "{$this->dir}/{$file}"; $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 { if (!$this->exists($file)) { return null; } $source = file_get_contents("{$this->dir}/{$file}"); return $source === false ? null : $source; } private function exists(string $file): bool { return self::isValidName($file) && is_file("{$this->dir}/{$file}"); } }