orchidsoftware / platform

Orchid is a @laravel package that allows for rapid application development of back-office applications, admin/user panels, and dashboards.
https://orchid.software
MIT License
4.26k stars 631 forks source link

правило валидации для Attachment, загруженных ранее полями Upload, Cr… #2745

Open mavsan opened 7 months ago

mavsan commented 7 months ago

Часто необходимо выполнять валидацию файлов, загруженных через Upload. Можно через Observer, но лучше, лгично и читаемо - через контроллер или Form Request в стандартном валидаторе Laravel. Предлагаю такое правило для валидатора.

Как использовать:

use Orchid\Rule\AttachmentRule;

class SomeClassScreen  extends Screen {

    public function save(Request $request) {
        $request->validate([
            'file' => ['required', new AttachmentRule('bail|image|dimensions:max_width=100,max_height=100', true)]
        ]);
    }
}

или

namespace App\Http\Requests;

use Orchid\Rule\AttachmentRule;

class SomeRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'file' => ['required', new AttachmentRule('bail|image|dimensions:max_width=100,max_height=100')],
        ];
    }
}

Класс принимает 2 параметра в конструктор - правила валидации и надо ли удалять файлы, не прошедшие валидацию (по умолчанию - true).

Есть один нюанс: required должно быть вынесено, как в примере выше, т.к. если поле не пришло или пустое - валидатор просто пропускает это поле, даже если указать required в параметрах AttachmentRule.

Вот, что получаем в итоге: image

После валидации: image

Ну и исправить описание ошибок, чтобы было не "Поле ... должно быть картинкой", а - "Файл ... должен быть картинкой" ну или как-то так, если это критично, конечно.

tabuna commented 7 months ago

@mavsan У меня мысль которая потенциально является решением, так же и валидации. Так как код непосредственной загрузки достаточно короткий и легко воспроизводимым, то возможно имеет смысл добавить методы которые указали бы route, например:

Upload::make('images')->route('my.route.to.upload.image')

и уже в собственном маршруте мы можем делать различные проверки и не сохранять файл:

public function upload(Request $request)
{
    // My any validation

    $file = new File($request->file('photo'));
    $attachment = $file->load();

    return response()->json($attachment);
}
mavsan commented 7 months ago

Да, с роутом - хорошая мысль. Возможно, вместо роута надо указывать метод в текущем экране, как с кнопкой. Или оба варианта - роут или метод, чтобы каждый решал для себя - как ему удобно: собрать все проверки загрузки в отдельном контроллере или в текущем экране работать.