API Reference

Auto-gegenereerd via Reflection — blijft altijd in sync met src/.

Filter: alleAppCacheCmsDbDebugDynamicEventsFilesFormHtmlHttpImageLogMediaSecuritySessionStdlibSupportView

AltTagger

Framework\Files\AI\AltTagger
interface

Provider-onafhankelijk contract om in één AI-call:
- Per taal een korte ALT-tekst (max 1 zin) te genereren
- Maximaal 10 generieke tags voor de afbeelding op te leveren

Implementaties: {@see GroqAltTagger}. Caller bind 'm in de container
en gebruikt 'm via de Files-facade-routes.

1 public method
tag(string $imageUrl, array $languages): array

GroqAltTagger

Framework\Files\AI\GroqAltTagger
final class

AltTagger via de Groq API (OpenAI-compatible). Default model is
`meta-llama/llama-4-scout-17b-16e-instruct` — vision-capable.

$tagger = new GroqAltTagger($_ENV['GROQ_API_KEY']);
$r = $tagger->tag('https://example.com/foto.jpg', ['nl', 'en', 'de']);
// $r = ['alts' => ['nl' => '...', 'en' => '...', 'de' => '...'], 'tags' => [...]]

Werkt ook met `data:image/jpeg;base64,...` URL's voor lokale files —
Groq's vision endpoint accepteert beide.

__construct(string $apiKey, string $model = 'meta-llama/llama-4-scout-17b-16e-instruct', ?\TransportInterface $transport = NULL)
1 public method
tag(string $imageUrl, array $languages): array

FileQuery

Framework\Files\FileQuery
final class

Filter/sort-parameters voor `FileRepository::findInFolder()` en `::search()`.

Defaults: alfabetisch oplopend op naam, geen filter, geen limiet.

__construct(?string $q = NULL, ?\FileType $type = NULL, string $sort = 'name', string $direction = 'asc', ?int $limit = NULL, int $offset = 0)

FileRecord

Framework\Files\FileRecord
final class

Eén regel uit de files-tabel.

Een file is óf lokaal opgeslagen (`contentHash` set, `externalUrl` null),
óf extern (`externalUrl` set, `contentHash` null). Nooit allebei, nooit geen.

`metadata` is een vrij-vorm associative array (JSON in storage). Voor images:
dimensies; voor externals: provider/embed-id; etc.

__construct(int $id, ?int $folderId, string $name, string $mime, int $size, ?string $contentHash, ?string $externalUrl, \FileType $type, array $metadata, int $createdAt, int $updatedAt)
4 public methods
isExternal(): bool
isLocal(): bool
url(): string

Render-vriendelijke URL: lokaal → /files/{id}/raw, extern → externalUrl.

with(array $changes): self

FileRepository

Framework\Files\FileRepository
interface

Storage-contract voor file-records (DB-laag, los van de blob-bytes).

Implementaties: {@see JsonFileRepository} (default voor demo, geen DB-extensie),
later eventueel een PDO-impl voor MySQL/SQLite.

8 public methods
countInFolder(?int $folderId, \FileQuery $query): int

Tel files in een folder (voor pagination).

create(\FileRecord $record): \FileRecord

Insert een nieuwe row. `id`/`createdAt`/`updatedAt` worden door de
repository gegenereerd; meegegeven waarden worden genegeerd.

delete(int $id): void
find(int $id): ?\FileRecord
findByHash(string $hash): array
findInFolder(?int $folderId, \FileQuery $query): array
search(\FileQuery $query): array

Globale zoek over alle files (folder-onafhankelijk).

update(\FileRecord $record): \FileRecord

Update bestaande row. Geeft de geüpdatete record terug, met nieuwe
`updatedAt`.

FileStorage

Framework\Files\FileStorage
interface

Blob-IO-laag — los van de DB-laag. Werkt content-addressed via sha256.

Twee uploads van dezelfde file produceren één blob (dedup), maar de
`FileRepository` houdt nog steeds twee aparte rows zodat hernoemen/verplaatsen
onafhankelijk werkt.

Implementaties: {@see LocalFileStorage} (default), later eventueel S3.

5 public methods
delete(string $hash): void
exists(string $hash): bool
path(string $hash): ?string

Absoluut bestandspad voor de blob — handig voor X-Sendfile / readfile().
Null als de hash niet bestaat.

read(string $hash): ?string

Lees bytes. Null als de hash niet bestaat.

write(string $hash, string $contents): void

Schrijf bytes; idempotent — als de hash al bestaat, no-op.

FileType

Framework\Files\FileType
enum

Categorie van een file — bepaalt rendering en filter-knoppen in de UI.

Geleid uit de mime-type bij upload of uit de URL-parser bij externals.

4 public methods
static cases(): array
static from(string|int $value): static
static fromMime(string $mime): self
static tryFrom(string|int $value): ?static
Cases: Image, Video, Audio, Pdf, External, Binary

Files

Framework\Files\Files
final class

Facade die `FileRepository` + `FolderRepository` + `FileStorage` koppelt
en de "smart" operaties levert: upload (met dedup), delete (met refcount-
blob-cleanup), externe URL toevoegen.

$files = new Files(
new JsonFileRepository($store),
new JsonFolderRepository($store),
new LocalFileStorage('/data/files'),
);

$rec = $files->upload(folderId: 1, name: 'foo.jpg', contents: $bytes, mime: 'image/jpeg');
$files->delete($rec->id);

Voor low-level operaties (`findByHash`, etc.) kun je de repos direct uit
de container halen — de facade is voor de gebruikelijke schrijfacties.

__construct(\FileRepository $files, \FolderRepository $folders, \FileStorage $storage, \FilesConfig $config = \Framework\Files\FilesConfig::__set_state(array( 'languages' => array ( 0 => 'nl', ), 'languageLabels' => array ( 'nl' => 'Nederlands', ), 'aiEnabled' => false, 'aiModel' => 'grok-2-vision-1212', )))
6 public methods
addExternal(?int $folderId, string $url, ?string $name = NULL, array $metadata = array ( )): \FileRecord

Voeg een externe URL toe als file (YouTube, Vimeo, willekeurige PDF-URL).
Geen blob — alleen een `files`-row met `externalUrl`.

delete(int $fileId): void

Verwijder een file. Bij lokale files wordt na refcount-check de blob
van disk verwijderd als geen andere row 'm gebruikt.

deleteFolder(int $folderId): array

Verwijder een folder + alle descendants + alle files daarin (met
refcount-blob-cleanup per file).

move(int $fileId, ?int $newFolderId): \FileRecord
rename(int $fileId, string $newName): \FileRecord
upload(?int $folderId, string $name, string $contents, string $mime, array $metadata = array ( )): \FileRecord

Upload nieuwe file. Dedup-aware: als een blob met dezelfde hash al
bestaat, wordt 'm hergebruikt — alleen een nieuwe `files`-row.

FilesConfig

Framework\Files\FilesConfig
final class

Configuratie die de caller meegeeft aan {@see Files}. Bepaalt hoe de
front-end zich gedraagt — talen voor multi-lingual ALT-tekst, of de AI-
suggestie zichtbaar is, etc.

$config = new FilesConfig(
languages: ['nl', 'en', 'de'],
languageLabels: ['nl' => 'Nederlands', 'en' => 'English', 'de' => 'Deutsch'],
aiEnabled: true,
);

Defaults zijn NL-only, geen AI. De waarden worden naar de browser gestuurd
via `GET /api/files/config` en gebruikt door file-browser.js om de juiste
inputs te renderen.

__construct(array $languages = array ( 0 => 'nl', ), array $languageLabels = array ( 'nl' => 'Nederlands', ), bool $aiEnabled = false, string $aiModel = 'grok-2-vision-1212')
1 public method
toArray(): array

FolderRecord

Framework\Files\FolderRecord
final class

Eén regel uit de folders-tabel.

`path` is gedenormaliseerd ("/foo/bar/baz") voor snelle breadcrumb-render
en zoek-zonder-recursie. Wordt onderhouden door de repository bij rename/move.

Root = `parentId === null && path === '/'` (of equivalent).

__construct(int $id, ?int $parentId, string $name, string $path, int $createdAt, array $metadata = array ( ))
2 public methods
isRoot(): bool
withMetadata(array $metadata): self

FolderRepository

Framework\Files\FolderRepository
interface

Storage-contract voor folder-records.

9 public methods
all(): array

Alle folders plat — caller bouwt de tree client-side via `parentId`.

children(?int $parentId): array

Direct kinderen van een folder (geen recursie).

create(?int $parentId, string $name): \FolderRecord

Maak een nieuwe folder. `path` wordt gedenormaliseerd uit parent + name.
Faalt als naam al bestaat onder dezelfde parent.

delete(int $id): array

Verwijder folder + alle descendants. Caller is verantwoordelijk voor
het verwijderen van de bijbehorende files (om refcount-blob-cleanup
juist te doen).

find(int $id): ?\FolderRecord
findByPath(string $path): ?\FolderRecord
move(int $id, ?int $newParentId): \FolderRecord

Verplaats — werkt ook descendants bij (path-prefix).
`$newParentId === null` = naar root.

rename(int $id, string $newName): \FolderRecord

Hernoem — werkt ook descendants bij (path-prefix).

update(\FolderRecord $record): \FolderRecord

Update een folder. Voor v1 worden alleen mutaties op `metadata`
toegepast — `name`/`parentId`/`path` gaan via `rename()`/`move()`.

JsonFileRepository

Framework\Files\JsonFileRepository
final class

JSON-backed FileRepository.

__construct(\JsonStore $store)
8 public methods
countInFolder(?int $folderId, \FileQuery $query): int
create(\FileRecord $record): \FileRecord
delete(int $id): void
find(int $id): ?\FileRecord
findByHash(string $hash): array
findInFolder(?int $folderId, \FileQuery $query): array
search(\FileQuery $query): array
update(\FileRecord $record): \FileRecord

JsonFolderRepository

Framework\Files\JsonFolderRepository
final class

JSON-backed FolderRepository.

__construct(\JsonStore $store)
9 public methods
all(): array
children(?int $parentId): array
create(?int $parentId, string $name): \FolderRecord
delete(int $id): array
find(int $id): ?\FolderRecord
findByPath(string $path): ?\FolderRecord
move(int $id, ?int $newParentId): \FolderRecord
rename(int $id, string $newName): \FolderRecord
update(\FolderRecord $record): \FolderRecord

JsonStore

Framework\Files\JsonStore
final class

Gedeeld read/write/atomic-update mechanisme voor de JSON-repos.

Eén JSON-file met `{folders: [...], files: [...], next_id: int}`. Alle writes
gaan via `transaction()` die file-lock + read-modify-write doet zodat parallelle
processen elkaar niet overschrijven.

$store = new JsonStore('/path/to/files.json');
$store->transaction(function (array $data) {
$data['files'][] = [...];
return $data;
});

Niet bedoeld voor productie-load met veel concurrent writers — voor 100k+
files of veel parallel uploads: gebruik straks de PDO-impl. Voor de demo
en kleine apps prima.

__construct(string $path)
2 public methods
read(): array

Lees de hele store. Bij corrupte file wordt een lege store geretourneerd
(caller kan dan opnieuw beginnen).

transaction(callable $fn): ?mixed

Atomaire read-modify-write. Callback krijgt de huidige data, returnt
de nieuwe data; ertussen blijft de file ge-flock'd.

LocalFileStorage

Framework\Files\LocalFileStorage
final class

Disk-backed FileStorage. Layout:

<baseDir>/<sha256[0:2]>/<sha256>.bin

De `[0:2]`-sub-dir voorkomt dat we duizend files in één directory plempen.
Sha256 is exact 64 hex chars; we accepteren niks anders (anti-traversal).

__construct(string $baseDir)
5 public methods
delete(string $hash): void
exists(string $hash): bool
path(string $hash): ?string
read(string $hash): ?string
write(string $hash, string $contents): void