Input

Validation

Přehled FormValidation, schema usage a samostatné stránky pro detailní popis validačních pravidel.

Recommended flow

Application code should use typed/fluent validation schemas. Rule strings are not the public validation API.

Rule subpages

Detailed rule pages are available under Validation section. They show fluent builder methods and stable rule names for translations/messages.

Basic schema example

Use ValidationSchema when the schema is built outside the validation call.

$schema = \Lemonade\Framework\Validation\ValidationSchema::create()
    ->field('email', 'E-mail')
        ->required(message: 'E-mail is required.')
        ->email(message: 'Enter a valid e-mail.')
        ->maxLength(120)
        ->end()
    ->field('message', 'Message')
        ->required()
        ->minLength(10)
        ->maxLength(4000)
        ->noHtml()
        ->end();

$result = $validator->validate($payload, $schema);

Inline fluent example

For small forms, build the schema directly through FormValidation::field() and finish with validate().

$result = $validator
    ->field('email', 'E-mail')
        ->required()
        ->email()
        ->maxLength(120)
    ->field('name', 'Name')
        ->required()
        ->maxLength(100)
    ->validate($payload);

Handling result

ValidationResult returns validity, field errors and validated payload.

if (!$result->isValid()) {
    return [
        'ok' => false,
        'errors' => $result->errors(),
    ];
}

$data = $result->validated();

Conditional rules

Rules support required/skip conditions based on other fields.

$schema = \Lemonade\Framework\Validation\ValidationSchema::create()
    ->field('department', 'Department')
        ->required()
        ->end()
    ->field('budget', 'Budget')
        ->requiredIf('department', 'sales')
        ->inList(['small', 'mid', 'large'])
        ->end()
    ->field('phone', 'Phone')
        ->skipUnless('department', 'support')
        ->phoneHeavy()
        ->end();

Custom rule registration

Register custom rule class in RuleRegistry and use it through custom(). ValidationRuleResolver creates rule objects through the container, so custom rules can use constructor injection.

/** @var \Lemonade\Framework\Validation\Rule\RuleRegistry $rules */
$rules = $container->get(\Lemonade\Framework\Validation\Rule\RuleRegistry::class);
$rules->addRule('slug', \App\Validation\Rule\SlugRule::class);

$result = $validator
    ->field('slug', 'URL slug')
        ->required()
        ->custom('slug', message: 'Slug is invalid.')
    ->validate($payload);

reCAPTCHA rule usage

Use the typed recaptcha() builder method or the helper setup when validating public forms.

$validator->addGoogleRecaptcha('Please confirm reCAPTCHA.', 'RECAPTCHA_SECRET');
$result = $validator->validate($payload);

Localization

Messages are resolved from field-level rule messages, custom rule failure details and translator keys (validation.{rule}). Stable rule names are internal identifiers for registry, translations and message targeting.

Controller anti-pattern

Avoid putting full validation + mapping + side effects directly in controller methods. Keep controller thin and move use-case flow into service.