Validation brick

Вхідні дані з форми чи API не можна довіряти «як є»: порожній email, зайві поля, CSRF-токен у validated(). addValidation() на ConceptStack піднімає Rakit-валідатор і FormRequest factory — правила живуть біля request-класу, а не розкидані по controller. Повертає ValidationBuilder. Мінімальна збірка з формою — у рецепті Валідація.

Два режими використання (свідомо розділені):

  • Лише addValidation() — достатньо для ручного FormRequestFactory::make() у controller (ранні кроки рецепта).
  • Плюс withFormRequests() на Http — коли хочеш type-hint FormRequest у action: валідація до входу в метод, невалідні дані навіть не досягають бізнес-коду.

Методи ValidationBuilder:

Метод Параметри Опис Залежність
setRules() array<string, class-string<RuleInterface>> $customRules Кастомні Rakit-правила (ім’я → class) —
setGlobalExcept() list<string> $globalExcept Поля, які FormRequest завжди виключає з validated (наприклад CSRF) —
withLogging() string $logFilePath, int $maxFiles = 7 Лог результатів валідації у rotating file —
withMasking() — Маскувати чутливі поля в логах валідації addMasking()

setRules()

$stack->addValidation()
    ->setRules([
        'unique_email' => UniqueEmailRule::class,
    ]);

Стандартні правила Rakit (required, email, …) уже доступні в FormRequest::rules() — їх не треба реєструвати тут. setRules() потрібен, коли з’являється доменне правило («email унікальний у БД»): коротке ім’я → class-string RuleInterface, класи resolve-яться з контейнера.

setGlobalExcept()

$stack->addValidation()
    ->setGlobalExcept(['_csrf_token']);

CSRF-токен потрібен middleware, але не бізнесу: його не варто бачити в validated() і писати в БД. Список полів прибирається з validated для усіх FormRequest (разом із per-request $except). Типово після кроку Session з withCsrf().

withLogging()

$stack->addValidation()
    ->withLogging($rootPath . 'storage/logs/validation.log');

Коли треба аудитити / дебажити саме спроби валідації (які поля впали), а не загальний app-лог. Це не capability addLogging() (Monolog для додатку) — окремий rotating sink для ValidationLogger. Без виклику валідація мовчки проходить або падає, без файлу спроб.

withMasking()

$stack->addMasking()
    ->setPatterns([/* … */]);

$stack->addValidation()
    ->withLogging($rootPath . 'storage/logs/validation.log')
    ->withMasking();

Лог валідації може містити паролі й токени. Opt-in маскування через DataMasker має сенс лише разом із withLogging(). Потрібен addMasking(); інакше require(validation, masking) не виконається при providers().

FormRequest: factory vs resolver

// Достатньо для factory у контролері (рецепт кроку 3):
$stack->addValidation();

// Лише якщо type-hint FormRequest у action:
$stack->addHttp()
    ->setRoutes([$rootPath . 'routes/web.php'])
    ->withFormRequests();

addValidation() піднімає validator і FormRequestServiceProvider (є FormRequestFactoryInterface). withFormRequests() додає FormRequestArgumentResolver у HTTP-ланцюжок — див. Http brick. На кроці обробки помилок resolver кидає ValidationException, а middleware перетворює її на redirect + flash — тому type-hint і middleware йдуть у парі. Пакети: Validation, Form Request.

Рецепт з формою — Валідація. Каталог bricks — Bricks і addX().