Validation
Validation Using Laravel
Introduction
Laravel offers multiple approaches to validate incoming data in your application, ensuring that your data is accurate and meets the specified requirements before it is processed. The most common method is to use the validate method available on incoming HTTP requests.
This method is easy to use and integrates seamlessly with Laravel's request lifecycle. By leveraging Laravel's built-in validation rules and custom validation logic, you can ensure your application handles data validation efficiently and effectively.
For detailed information about validation in Laravel, refer to the Laravel documentation.
Usage
UnoPim validates every write through a FormRequest class. Inline $request->validate() calls are not used in core and should not be used in packages: a FormRequest keeps rules out of the controller, gives you an authorize() hook, and is reusable across the store and update paths.
Creating a FormRequest
Put the class in your package's Http/Requests folder:
<?php
namespace Webkul\Example\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Webkul\Core\Rules\Code;
class ExampleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return bouncer()->hasPermission('example.create');
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules(): array
{
return [
'code' => ['required', 'unique:examples,code', new Code],
'title' => ['required', 'max:255'],
'description' => ['nullable', 'string'],
'status' => ['boolean'],
];
}
/**
* Custom messages for the rules above.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'code.unique' => trans('example::app.validation.code-taken'),
];
}
}Messages must come from translation files — never hardcode the English string, or the error will not follow the admin's locale.
Using It in the Controller
Type-hint the request. Laravel resolves it, runs the rules before your method body, and returns a 422 with the error bag when they fail:
use Webkul\Example\Http\Requests\ExampleRequest;
public function store(ExampleRequest $request): JsonResponse
{
$example = $this->exampleRepository->create($request->validated());
return new JsonResponse([
'message' => trans('example::app.examples.create-success'),
]);
}$request->validated() returns only the keys that passed a rule, which keeps unexpected input out of a mass-assignment call.
Custom Rules
For validation that repeats across requests, write a rule class rather than a closure. UnoPim ships several you can reuse — Webkul\Core\Rules\Code for entity codes, and Webkul\Core\Rules\FileMimeExtensionMatch for uploads where the extension must match the real MIME type.
Validation Using Vue
Introduction
VeeValidate is a powerful validation library for Vue.js that provides an extensive set of validation rules out of the box, along with support for custom rules. It is template-based, making it easy to validate HTML5 inputs as well as custom Vue components. VeeValidate also supports localization with 44 languages maintained by the community.
For detailed information about validation in Vue.js using VeeValidate v4, refer to the VeeValidate documentation.
Installation
UnoPim already includes the VeeValidate v4 library, so there is no need to install it separately.
Configuration
UnoPim ships pre-configured vee-validate settings in packages/Webkul/Admin/src/Resources/assets/js/plugins/vee-validate.js, registered from app.js. The plugin:
- registers every rule from
@vee-validate/rulesglobally, - registers UnoPim's own rules —
phone,address,decimal, andrequired_if, - registers the
VForm,VField, andVErrorMessagecomponents, - loads the
@vee-validate/i18nmessage catalogue for each supported locale, so validation errors appear in the admin's language, - and validates on blur, input, and change.
Because the rules are global, a Blade control only needs the rules attribute — no imports or per-component setup.
Examples
Below are examples of how to use VeeValidate for validation in Vue components within UnoPim:
<x-admin::form.control-group class="w-full mb-[10px]">
<x-admin::form.control-group.label class="required">
@lang('example::app.admin.example.create.title')
</x-admin::form.control-group.label>
<x-admin::form.control-group.control
type="text"
name="title"
:value="old('title')"
rules="required"
:label="trans('example::app.admin.example.create.title')"
:placeholder="trans('example::app.admin.example.create.title')"
>
</x-admin::form.control-group.control>
<x-admin::form.control-group.error
control-name="title"
>
</x-admin::form.control-group.error>
</x-admin::form.control-group>Available Custom Validation in unopim
phoneThe phone validation rule is designed to ensure that the input is a valid phone number.
defineRule("phone", (value) => {
if (!value || !value.length) {
return true;
}
if (!/^\+?\d+$/.test(value)) {
return false;
}
return true;
});addressThe address validation rule typically ensures that an address field is not left empty and may include additional logic to check for valid address formats.
defineRule("address", (value) => {
if (!value || !value.length) {
return true;
}
if (
!/^[a-zA-Z0-9\s.\/*'\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\u0590-\u05FF\u3040-\u309F\u30A0-\u30FF\u0400-\u04FF\u0D80-\u0DFF\u3400-\u4DBF\u2000-\u2A6D\u00C0-\u017F\u0980-\u09FF\u0900-\u097F\u4E00-\u9FFF,\(\)-]{1,60}$/iu.test(
value
)
) {
return false;
}
return true;
});decimalThe decimal validation rule ensures that the input is a valid decimal number. This rule allows specifying the number of decimal places and the decimal separator. By default, it accepts any number of decimal places and uses the period (".") as the separator.
defineRule(
"decimal",
(value, { decimals = "*", separator = "." } = {}) => {
if (value === null || value === undefined || value === "") {
return true;
}
if (Number(decimals) === 0) {
return /^-?\d*$/.test(value);
}
const regexPart = decimals === "*" ? "+" : `{1,${decimals}}`;
const regex = new RegExp(
`^[-+]?\\d*(\\${separator}\\d${regexPart})?([eE]{1}[-]?\\d+)?$`
);
return regex.test(value);
}
);required_ifMakes a field required only when a condition you pass is true — useful for fields that appear conditionally in a form.
defineRule("required_if", (value, { condition = true } = {}) => {
if (condition) {
if (value === null || value === undefined || value === '') {
return false;
}
}
return true;
});