Files

Files is a pure storage service — no table for it in DDL.sql. Any metadata your app wants to keep about a stored file (owner, parent record, ordering) is your own table, not Clarity's concern.

Construction

new Files(
    string $adapter,                // Files::ADAPTER_FILESYSTEM | ADAPTER_S3
    ?string $basePath = null,       // required for ADAPTER_FILESYSTEM
    ?object $s3Client = null,       // required for ADAPTER_S3 — anything exposing putObject/deleteObject/doesObjectExist
    ?string $s3Bucket = null,       // required for ADAPTER_S3
    array $allowedExtensions = [...], // extension => list of acceptable content-sniffed MIME types
    int $maxSizeBytes = 10_485_760,   // 10 MB default
)

Methods

$files->store(UploadedFileInterface $file, bool $public = true, ?string $directory = null): array
// ['path' => string, 'mimeType' => string, 'size' => int, 'public' => bool]

$files->storeMultiple(array $files, bool $public = true, ?string $directory = null): array
$files->delete(string $path): bool
$files->exists(string $path): bool
$stored = $files->store($request->file('avatar'), directory: 'avatars');
// dispatches Event::FILE_UPLOADED with $stored as the payload

Validation, always

MIME type is detected from file content (PHP's fileinfo), never from the client-supplied Content-Type header — that header is exactly as trustworthy as a filename extension, which is to say not at all. An upload must pass both the extension allowlist and a content-sniffed MIME type consistent with that extension, or store() throws.

Next steps

  • Event — listening for Event::FILE_UPLOADED.