Поддержка
Поля

Файлы, изображения

Загрузка файлов и изображений через подключаемые медиа-драйверы. Встроенный FileDriver, создание собственных драйверов и настройка на уровне поля.

File

Поле предназначено для загрузки файлов. Добавьте его в метод fields() вашего ресурса:

app/Frame/PostResource.php
use Frame\Laravel\Fields\File;

public function fields(): array
{
    return [
        File::make('documents'),
    ];
}

Ограничение количества

Метод maximum() задаёт максимальное количество загружаемых файлов:

app/Frame/PostResource.php
File::make('documents')
    ->maximum(5)

Множественная загрузка

Метод multiple() включает режим множественной загрузки:

app/Frame/PostResource.php
File::make('attachments')
    ->multiple()
    ->maximum(10)

Допустимые форматы

Через withMeta() можно ограничить допустимые форматы файлов:

app/Frame/InitiativeResource.php
File::make('videos')
    ->maximum(5)
    ->withMeta([
        'accept' => 'video/mp4',
    ])

Image

Поле Image расширяет File и предназначено для работы с изображениями. По умолчанию принимает форматы: jpeg, png, svg, webp.

app/Frame/UserResource.php
use Frame\Laravel\Fields\Image;

public function fields(): array
{
    return [
        Image::make('avatar'),
    ];
}
При maximum(1) поле отображается в таблице (index). При maximum(>1) — автоматически скрывается из таблицы.
app/Frame/UserResource.php
Image::make('avatar')
    ->maximum(1)
app/Frame/GalleryResource.php
Image::make('photos')
    ->multiple()
    ->maximum(10)

Конверсии

Метод conversion() указывает, какую конверсию изображения использовать при отображении. Название конверсии передаётся в медиа-драйвер, который решает, как её обработать:

app/Frame/UserResource.php
Image::make('avatar')
    ->conversion('thumbnail')

Медиа-драйверы

Загрузка, получение, удаление и привязка файлов выполняется через медиа-драйвер — класс, реализующий контракт MediaDriver.

По умолчанию используется FileDriver, который хранит файлы через Laravel Storage и сохраняет метаданные в JSON-колонке модели. Дополнительных зависимостей не требуется.

Контракт MediaDriver

Каждый драйвер реализует пять методов:

upload
UploadedFile → array
Загрузка файла. Принимает UploadedFile, возвращает массив метаданных для фронтенда.
delete
int|string → void
Удаление файла по его идентификатору.
resolve
Model, string, array → ?array
Получение списка медиа для поля модели. Принимает модель, имя поля и массив опций (например, conversion).
fill
Model, string, ?array → void
Привязка медиа к модели. Получает массив медиа-данных и сохраняет их в модель.
export
Model, string → ?string
Экспорт значения поля в строковое представление (пути через запятую).

Полный интерфейс контракта:

packages/core/src/Contracts/MediaDriver.php
use Frame\Core\Contracts\MediaDriver;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;

interface MediaDriver
{
    public function upload(UploadedFile $file): array;

    public function delete(int|string $id): void;

    public function resolve(Model $model, string $field, array $options = []): ?array;

    public function fill(Model $model, string $field, ?array $value): void;

    public function export(Model $model, string $field): ?string;
}

Глобальный драйвер

По умолчанию все поля File и Image используют FileDriver. Чтобы заменить драйвер глобально, вызовите useMediaDriver() в сервис-провайдере:

app/Providers/AppServiceProvider.php
use Frame\Core\Frame;
use App\Drivers\SpatieMediaDriver;

public function boot(): void
{
    Frame::useMediaDriver(SpatieMediaDriver::class);
}

После этого все файловые поля будут работать через указанный драйвер.

Драйвер на уровне поля

Метод driver() позволяет задать драйвер для конкретного поля. Драйвер поля имеет приоритет над глобальным:

app/Frame/UserResource.php
use App\Drivers\CloudinaryDriver;
use App\Drivers\SpatieMediaDriver;

public function fields(): array
{
    return [
        // Аватар через Spatie Media Library
        Image::make('avatar')
            ->driver(new SpatieMediaDriver()),

        // Документы через Cloudinary
        File::make('documents')
            ->driver(new CloudinaryDriver()),
    ];
}

JSON-режим

Если поле работает в JSON-режиме (->json()), всегда используется встроенный FileDriver — независимо от глобального или per-field драйвера. Это гарантирует корректную работу с JSON-колонками.
app/Frame/ProductResource.php
File::make('metadata->files')
    ->json()

FileDriver (по умолчанию)

FileDriver — встроенный драйвер, не требующий дополнительных пакетов:

  • Загружает файлы через Laravel Storage (диск public, директория frame-uploads)
  • Хранит метаданные в JSON-колонке модели
  • Поддерживает любые типы файлов

При необходимости можно настроить диск и директорию через сервис-контейнер:

app/Providers/AppServiceProvider.php
use Frame\Laravel\Drivers\FileDriver;

public function register(): void
{
    $this->app->when(FileDriver::class)
        ->needs('$disk')
        ->give('s3');

    $this->app->when(FileDriver::class)
        ->needs('$directory')
        ->give('uploads');
}

Создание своего драйвера

Для интеграции с любым сервисом хранения создайте класс, реализующий контракт MediaDriver:

Создайте класс драйвера

app/Drivers/SpatieMediaDriver.php
namespace App\Drivers;

use Frame\Core\Contracts\MediaDriver;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;

class SpatieMediaDriver implements MediaDriver
{
    public function upload(UploadedFile $file): array
    {
        // Загрузка через Spatie Media Library
        // Оптимизация, создание превью и т.д.
    }

    public function delete(int|string $id): void
    {
        // Удаление медиа по ID
    }

    public function resolve(Model $model, string $field, array $options = []): ?array
    {
        $conversion = $options['conversion'] ?? '';

        // Получение медиа из коллекции модели
    }

    public function fill(Model $model, string $field, ?array $value): void
    {
        // Привязка медиа к модели: reorder, copy, удаление неиспользуемых
    }

    public function export(Model $model, string $field): ?string
    {
        // Экспорт путей через запятую
    }
}

Зарегистрируйте драйвер

app/Providers/AppServiceProvider.php
use Frame\Core\Frame;
use App\Drivers\SpatieMediaDriver;

public function boot(): void
{
    Frame::useMediaDriver(SpatieMediaDriver::class);
}
Массив $options в методе resolve() может содержать ключ conversion — название конверсии, переданное из Image::conversion().

Структура ответа upload

Метод upload() должен возвращать массив с метаданными загруженного файла. Фронтенд ожидает следующую структуру:

app/Drivers/SpatieMediaDriver.php
public function upload(UploadedFile $file): array
{
    return [
        'id' => 'unique-id',           // Уникальный идентификатор
        'path' => 'https://.../',      // Полный URL к файлу
        'size' => 102400,              // Размер в байтах
        'name' => 'document.pdf',      // Оригинальное имя файла
        'type' => 'file',              // 'file' или 'image'
        'preview' => null,             // Превью (thumbhash, base64 и т.д.)
        'extension' => 'pdf',          // Расширение файла
        'collection' => 'default',     // Название коллекции
        'conversions' => [],           // Доступные конверсии
        'properties' => [],            // Дополнительные свойства
        'order' => 0,                  // Порядок сортировки
    ];
}