Request Validation ================== LacePHP includes a simple, flexible request validator to help you enforce rules on user input. The **RequestValidator** class lives in `lacebox/Sole/RequestValidator.php`. Helper Access ------------- There isn’t a dedicated helper function, so import and grab the validator like this: .. code-block:: php use Lacebox\Sole\RequestValidator; $validator = RequestValidator::getInstance(); Why a Singleton? Using one instance means you can configure rules in one place and then call `validate()` anywhere—your rules and error state stay consistent across your controllers or services. Defining Rules -------------- First, tell the validator which fields to check and which rules to apply. You can define rules as comma-separated strings or arrays: .. code-block:: php $validator->setRules([ 'email' => 'required,email', 'age' => ['required', 'min[18]', 'max[120]'], 'username' => 'required,custom:isAlphanumeric' ]); Here’s what happens: - **required**: value must not be null or empty. - **email**: value must look like a valid email address. - **min[18]**: value (typically number or string length) must be at least 18. - **max[120]**: value must not exceed 120. - **custom:isAlphanumeric**: a user-supplied rule named `isAlphanumeric` (see below). Custom Rules ------------ If you have your own validation logic, register it before `setRules()`: .. code-block:: php $validator->setCustomRules([ 'isAlphanumeric' => new \Weave\Validators\IsAlphanumericRule(), ]); Then you can refer to it with `custom:isAlphanumeric`. First-Error Mode (“lace_break”) ------------------------------- By default, every field is checked against all its rules and *all* errors are collected. If you’d rather stop on the first failure per field, turn on **lace_break**: .. code-block:: php $validator->lace_break(); Throwing Exceptions ------------------- You can choose to have the validator throw a `ValidationException` on failure instead of returning `false`. This can simplify controller code when you want to catch and handle errors: .. code-block:: php $validator->throwOnFail(); Running Validation ------------------ Once you’ve configured your rules, call: .. code-block:: php if ($validator->validate()) { // All good—proceed with your business logic } else { // Validation failed $errors = $validator->errors(); // $errors is an array: ['field1'=>['Error message'], ...] } Or, if you set `throwOnFail(true)`, simply: .. code-block:: php try { $validator->validate(); // continue } catch (\Lacebox\Sole\Validation\ValidationException $e) { $errors = $e->getErrors(); // handle errors, e.g. return them in JSON } Inspecting Errors ----------------- - **fails()** returns `true` if any rules failed. - **errors()** returns the full array of error messages per field. - **first('email')** returns the first error message for the `email` field, or `null` if none. Example Usage ------------- Imagine a simple user-registration endpoint: .. code-block:: php use Lacebox\Sole\RequestValidator; class RegistrationController { public function register() { $validator = RequestValidator::getInstance() ->throwOnFail() // we want exceptions ->lace_break() // stop at first error per field ->setRules([ 'email' => 'required,email', 'password' => 'required,min[8]', ]); try { $validator->validate(); } catch (\Lacebox\Sole\Validation\ValidationException $e) { // return JSON errors with 422 status return kickback()->json([ 'errors' => $e->getErrors() ], 422); } $data = sole_request()->only(['email', 'password']); // ... create user ... return kickback()->json(['status'=>'success'], 201); } } Validation Syntax and Built-in Rules ------------------------------------- LacePHP’s **RequestValidator** currently supports: - **Comma-separated** rule lists. - **Bracket syntax** for parameters, e.g. `min[8]`. - **Built-in rule names**: `required`, `email`, `isEven`, `isGreaterThan`, `isEqualsTo`, `min` plus any custom rules you register. Below is a sample code on how you can set your validation rules, either the custom one or the in-built rule. .. code-block:: php RequestValidator::getInstance() ->setCustomRules([ 'captcha' => new weave\Validators\CaptchaRule() ]) ->setRules([ 'email' => 'required,email', // comma-separated 'password' => 'required,min[8]', // bracket syntax 'captcha' => 'required,custom:captcha' // built-in + custom ]) ->validate(); Built-in Rules ^^^^^^^^^^^^^^ Here are the rules provided out of the box: .. list-table:: :header-rows: 1 :widths: 20 20 50 * - Rule Name - Syntax - Description * - required - `required` - Field must not be null or empty. * - email - `email` - Field must be a valid email address. * - min - `min[]` - Field (string length) must be at least `` characters. * - isGreaterThan - `isGreaterThan[]` - Numeric field must be strictly greater than ``. * - isEqualsTo - `isEqualsTo[]` - Field must equal ``. * - custom - `custom:` - Use a custom rule instance previously registered via `setCustomRules()`. Best Practices -------------- - **Define rules early** in your controller or a service before any side effects. - **Use lace_break()** if you only need the first failure for each field—for example, you don’t want multiple “required” and “email” errors for an empty email. - **Register custom rules** for complex or domain-specific checks (e.g. password strength, date ranges). - **Handle exceptions** cleanly by catching `ValidationException` and returning user-friendly messages (JSON or HTML). .. warning:: - **Always validate** any data that comes from the client—even if you think it’s “just” an internal tool. - **Be explicit** about which fields you validate—unvalidated fields can lead to unexpected behaviour or security issues. - **Keep rules simple** and reusable. If you find yourself repeating a rule combination, consider writing a custom rule class. By following this pattern, you ensure your LacePHP apps remain robust, secure and easy to maintain—no matter how many inputs you need to validate. | |