*/ public static function slug(string $table, ?int $ignoreId = null): array { $unique = Rule::unique($table, 'slug'); return [ 'required_if:public,true', 'nullable', 'string', 'max:255', 'regex:/^[a-z0-9]+(-[a-z0-9]+)*$/', $ignoreId === null ? $unique : $unique->ignore($ignoreId), ]; } /** * The rule for an IANA timezone identifier. * * Shared because two things write `users.timezone` — the picker on the * profile form and the silent browser detection behind PUT /timezone — * and a zone the registry would refuse must not be storable through * either. The framework's own `timezone` rule is not enough on its own: * it accepts abbreviations and offsets that `DateTimeZone` tolerates * but that never appear in the picker, so membership is checked too. * * Presence is the caller's business: both callers currently require it, * but the field is always sent by a control that has a value, so * whether an omission clears or keeps is a decision for the form, not * for the format. * * @return array */ public static function timezone(): array { return ['string', 'timezone', Rule::in(app(TimezoneRegistry::class)->all())]; } /** * The rules protecting one form with a CAPTCHA, or none at all. * * Shared because four unrelated forms — login, client registration, * the password-reset request and a visitor's comment — must each * enforce this identically, and because "this installation does not * protect this form" needs to read as an empty rule set at every one * of them rather than as four slightly different conditionals. * * Spread into the caller's rules: * * $request->validate([ * 'email' => ['required', 'email'], * ...Rules::captcha(CaptchaForm::Login), * ]); * * `bail` so a missing token is refused before any network call, and * `required` even on the forms that let an unreachable provider * through: failing open is about *our server* being unable to ask, and * treating an absent field as an answer is precisely the bug that left * v1's registration form unprotected. * * @return array> */ public static function captcha(CaptchaForm $form): array { if (! app(Captcha::class)->protects($form)) { return []; } return ['captcha_token' => ['bail', 'required', 'string', 'max:5000', new CaptchaRule($form)]]; } }