پرش به مطلب اصلی

قوانین اعتبارسنجی (Validation Rules)

برای جلوگیری از پراکندگی و افزایش انسجام، تمام قوانینِ اعتبارسنجیِ قابل‌استفادهٔ مشترک در یک زیرساختِ متمرکز تعریف شده‌اند:

Dornica\Foundation\Core\Rules

این قوانین کلاس‌های استانداردِ لاراول (ValidationRule) هستند و مستقیماً در Form Requestها به‌کار می‌روند:

use Dornica\Foundation\Core\Rules\CodeRule;

public function rules(): array
{
return [
'code' => ['required', 'string', new CodeRule()],
];
}
پیام‌ها

پیام‌های پیش‌فرضِ فارسی همراهِ قوانین ثبت می‌شوند. :attribute به‌طور خودکار با نامِ فیلد جایگزین می‌شود و می‌توانید نامِ نمایشیِ فیلد را در متدِ attributes()ِ Form Request تعیین کنید.


قوانینِ رشته‌ای / قالب

CodeRule

مقدار باید تنها شاملِ اعداد، حروف لاتین، خط تیره (-) و زیرخط (_) باشد. مطابقِ قواعدِ پنل برای کد.

  • الگو: ^[-a-zA-Z0-9_]+$
  • پیام: «:attribute وارد شده باید تنها شامل اعداد، حروف لاتین، خط تیره (-) و زیرخط (_) باشد.»
'code' => ['required', 'string', new CodeRule()],

SlugRule

مانند CodeRule برای اسلاگ؛ تنها اعداد، حروف لاتین، - و _.

  • الگو: ^[-a-zA-Z0-9_]+$
  • پیام: «:attribute وارد شده باید تنها شامل اعداد، حروف لاتین، خط تیره (-) و زیرخط (_) باشد.»
'slug' => ['required', 'string', new SlugRule()],

StyleRule

برای استایل؛ مانند بالا ولی فاصله هم مجاز است.

  • الگو: ^[-a-zA-Z0-9_ ]+$
  • پیام: «:attribute وارد شده باید تنها شامل اعداد، حروف لاتین، خط تیره (-) و زیرخط (_) باشد.»
'style' => ['nullable', 'string', new StyleRule()],

PersianSlugRule

در بخش‌هایی مانند مقالات و محتوا که برخلافِ قواعدِ عمومیِ پنل، اسلاگ باید از حروف فارسی نیز پشتیبانی کند.

  • مجاز: اعداد، حروف لاتین، حروف فارسی، - و _.
  • پیام: «:attribute وارد شده باید تنها شامل اعداد، حروف لاتین، حروف فارسی، خط تیره (-) و زیرخط (_) باشد.»
'slug' => ['required', 'string', new PersianSlugRule()],

PersianNameRule

برای اعتبارسنجیِ عنوان، نام و موارد مشابه استفاده می‌شود؛ مگر اینکه در تسک مشخص شده باشد که کاراکترهای خاص یا حروف لاتین مجاز است.

  • مجاز: تنها حروف فارسی و فاصله.
  • پیام: «:attribute وارد شده باید تنها شامل حروف فارسی و فاصله باشد.»
'title' => ['required', 'string', new PersianNameRule()],

AddressStringRule

آدرس نباید فقط از اعداد تشکیل شده باشد (مثلاً ورودیِ «7» معتبر نیست).

  • پیام: «:attribute نمی‌تواند فقط شامل عدد باشد.»
'address' => ['required', 'string', new AddressStringRule()],

UrlRule

مقدار باید یک URL معتبر باشد (با یا بدونِ http(s)://).

'website' => ['nullable', 'string', new UrlRule()],

قوانینِ اندازه / نرمال‌سازی

NumberSeparatorRule

سقفِ یک مقدار را بررسی می‌کند و در پیامِ خطا مقدارِ سقف را با جداکنندهٔ هزارگان نمایش می‌دهد. برای اعدادِ بزرگ (مثلِ اندازهٔ فایل) که در فرانت با جداکننده وارد می‌شوند مناسب است.

use Dornica\Foundation\Core\Rules\NumberSeparatorRule;

// عددی: مقدار نباید از max بزرگ‌تر باشد
'max_size' => ['required', 'numeric', new NumberSeparatorRule(max: 999999999)],

// رشته‌ای: طولِ رشته نباید از max بیشتر باشد
'code' => ['required', 'string', new NumberSeparatorRule(max: 32, isString: true)],
  • پارامترها: NumberSeparatorRule(int|float $max, bool $isString = false)
    • isString = false → مقایسهٔ مقدارِ عددی با max.
    • isString = true → مقایسهٔ طولِ رشته با max.

NormalizedStringRule

به‌دلیلِ تفاوتِ فرمتِ برگشتیِ دادهٔ textarea و editor (تگ‌های HTML،  ، کاراکترهای نامرئی، پایان‌خط‌ها)، پیش از بررسیِ حداکثرِ طول، مقدار نرمال‌سازی و پاک‌سازی می‌شود تا شمارشِ کاراکترها بین کامپوننت و Form Request یکسان شود.

use Dornica\Foundation\Core\Rules\NormalizedStringRule;

'body' => ['required', 'string', new NormalizedStringRule(max: 65000)],

// اگر ورودی از editor است (حذفِ شکستِ خطوطِ داخلی هنگام شمارش)
'content' => ['required', 'string', new NormalizedStringRule(max: 65000, isEditor: true)],
  • پارامترها: NormalizedStringRule(int|float $max, bool $isEditor = false)
  • پیام: «فیلد :attribute نباید بزرگ‌تر از :max باشد.»

قوانینِ تاریخِ جلالی

پکیجِ Jalali مجموعه‌ای از قوانینِ اعتبارسنجیِ تاریخ/زمانِ شمسی را روی Validator لاراول ثبت می‌کند (بدون وابستگی به verta) که مستقیماً در Requestها قابل استفاده‌اند:

$request->validate([
'start_date' => 'jalali_date:Y/m/d',
'expire_at' => 'jalali_datetime_after:1403/01/01 00:00:00,Y/m/d H:i:s',
]);
قانونآرگومان‌هاتوضیح
jalali_dateformat?تاریخِ شمسیِ معتبر
jalali_datetimeformat?تاریخ‌وزمانِ شمسیِ معتبر
jalali_date_equaldate,format?برابر با تاریخ
jalali_date_not_equaldate,format?نامساوی با تاریخ
jalali_date_afterdate,format?بعد از تاریخ
jalali_date_after_equaldate,format?بعد یا برابرِ تاریخ
jalali_date_beforedate,format?قبل از تاریخ
jalali_date_before_equaldate,format?قبل یا برابرِ تاریخ
jalali_datetime_equal · jalali_datetime_not_equal · jalali_datetime_after · jalali_datetime_after_equal · jalali_datetime_before · jalali_datetime_before_equaldatetime,format?مانند بالا، ولی در سطحِ تاریخ‌وزمان

نکته‌ها:

  • آرگومانِ format اختیاری است؛ پیش‌فرض Y-m-d.
  • جداکننده‌های فرمت باید دقیق مطابق ورودی باشند: مثلاً jalali_date:Y.m.d روی ورودیِ 1403-01-01 رد می‌شود.
  • بخشِ زمان اختیاری است؛ یک ورودیِ فقط‌تاریخ در برابرِ فرمتِ تاریخ‌وزمان هم اعتبارسنجی می‌شود.
  • در قوانینِ مقایسه، آرگومان‌ها به‌ترتیبِ مقدارِ مقایسه,format هستند.
  • در پیام‌ها، :date با ارقام فارسی نمایش داده می‌شود.
validator(['start_date' => '1403/05/14'], [
'start_date' => 'jalali_date_after:1403/01/01,Y/m/d',
])->passes(); // true
پیام‌ها

پیام‌های پیش‌فرضِ فارسیِ این قوانین همراهِ پکیج ثبت می‌شوند و می‌توانید هرکدام را در lang/fa/validation.phpِ پروژه با کلیدِ همان قانون بازنویسی کنید:

'jalali_date' => ':attribute معتبر نمی باشد.',
'jalali_date_equal' => ':attribute برابر :date نمی باشد.',
'jalali_date_after' => ':attribute باید بعد از :date باشد.',
// ...

قوانینِ مکانی (Geospatial)

مجموعه‌ای از قوانین برای اعتبارسنجیِ داده‌های مکانی (نقطه، چندضلعی، GeoJSON، UTM و محدوده). این‌ها عمومی هستند و هم در پنل و هم در API قابل استفاده‌اند.

فرمتِ مختصات

در قوانینِ ValidPoint، ValidPolygon، ValidMultiPolygon و PointWithinBoundary مختصات به‌صورتِ latitude/longitude (یا رشتهٔ "lat,lng") هستند. اما ValidGeoJson طبقِ استانداردِ GeoJSON مختصات را به‌صورتِ [lng, lat] انتظار دارد.

ValidPoint

یک نقطهٔ جغرافیاییِ معتبر.

  • ورودی: آرایهٔ ['latitude' => .., 'longitude' => ..] یا رشتهٔ "lat,lng" (مثلاً "35.6892,51.3890").
  • بازه: latitude بین -90 و 90، longitude بین -180 و 180.
  • پیام‌ها: «The :attribute must contain valid latitude and longitude.» / «... latitude must be between -90 and 90.» / «... longitude must be between -180 and 180.»
use Dornica\Foundation\Core\Rules\ValidPoint;

'location' => ['required', new ValidPoint()],

ValidPolygon

یک چندضلعیِ معتبر (آرایه‌ای از نقاط).

  • ورودی: آرایه‌ای از نقاط [['latitude'=>..,'longitude'=>..], …].
  • قواعد: حداقل minPoints نقطه (پیش‌فرض 3)، هر نقطه معتبر (مطابقِ ValidPoint)، و حداقل minPoints نقطهٔ متمایز — چندضلعیِ منحط (degenerate) رد می‌شود. نقطهٔ بستنِ حلقه (که با نقطهٔ اول یکی است) در شمارشِ نقاطِ متمایز نادیده گرفته می‌شود.
  • پارامتر: ValidPolygon(int $minPoints = 3).
use Dornica\Foundation\Core\Rules\ValidPolygon;

'area' => ['required', 'array', new ValidPolygon()],

ValidMultiPolygon

مجموعه‌ای از چندضلعی‌ها.

  • ورودی: آرایه‌ای از polygonها که هر polygon خود آرایه‌ای از نقاط است.
  • قواعد: حداقل یک polygon و هر polygon معتبر (مطابقِ ValidPolygon).
  • پارامتر: ValidMultiPolygon(int $minPoints = 3) — به هر polygon اعمال می‌شود.
use Dornica\Foundation\Core\Rules\ValidMultiPolygon;

'coverage' => ['required', 'array', new ValidMultiPolygon()],

ValidGeoJson

یک geometryِ ساختاراً معتبرِ GeoJSON.

  • ورودی: آرایه یا رشتهٔ JSON با کلیدهای type و coordinates.
  • typeهای پشتیبانی‌شده: Point، Polygon، MultiPolygon.
  • ساختار: Point یک position به‌صورتِ [lng, lat]؛ Polygon آرایه‌ای از linear ringها (هر ring حداقل ۴ position)؛ MultiPolygon آرایه‌ای از polygonها.
  • پارامترِ اختیاری: ValidGeoJson(?string $expectedType = null) برای محدودکردن به یک نوعِ مشخص.
use Dornica\Foundation\Core\Rules\ValidGeoJson;

// هر geometryِ پشتیبانی‌شده
'geometry' => ['required', new ValidGeoJson()],

// فقط Polygon
'geometry' => ['required', new ValidGeoJson(expectedType: 'Polygon')],

ValidUtmPoint

یک نقطهٔ UTM معتبر.

  • ورودی: آرایهٔ ['x' => .., 'y' => .., 'z' => ..] (کلیدِ z یا zone اختیاری) یا رشتهٔ "x,y" / "x,y,z" (مثلاً "500000,4000000,39").
  • قواعد: x (easting) و y (northing) الزامی و عددی؛ zone در صورتِ وجود عددِ صحیحِ بین 1 و 60.
use Dornica\Foundation\Core\Rules\ValidUtmPoint;

'utm' => ['required', new ValidUtmPoint()],

PointWithinBoundary

بررسی می‌کند که یک نقطه درونِ یک محدودهٔ چندضلعی قرار دارد.

  • ورودیِ نقطه: مانندِ ValidPoint (آرایهٔ latitude/longitude یا رشتهٔ "lat,lng").
  • محدوده (boundary): آرایه‌ای از نقاطِ [latitude, longitude] (حلقهٔ باز یا بسته). اگر پاس داده نشود، از کانفیگِ dornica-panel-kit.components.map.boundary خوانده می‌شود.
  • اگر محدودهٔ معتبری (حداقل ۳ نقطه) موجود نباشد، هیچ محدودیتی اعمال نمی‌شود (اعتبارسنجی رد نمی‌شود).
  • الگوریتم: ray-casting (even-odd).
  • پارامتر: PointWithinBoundary(?array $boundary = null).
use Dornica\Foundation\Core\Rules\PointWithinBoundary;

// استفاده از محدودهٔ پیش‌فرضِ کانفیگِ نقشه
'location' => ['required', new ValidPoint(), new PointWithinBoundary()],

// محدودهٔ سفارشی
'location' => ['required', new PointWithinBoundary(boundary: $polygonPoints)],

قوانینِ دامنه‌ای (تخصصی)

این قوانین هم در همان مسیر (Foundation\Core\Rules) هستند ولی مخصوصِ یک دامنهٔ خاص‌اند و معمولاً به‌صورتِ داخلی استفاده می‌شوند:

Ruleکاربرد
DisallowDeletedOnlyجلوگیری از ماندنِ فقط رکوردهای حذف‌شده در مدیریتِ فایل
RoleDateOverlapRuleبررسیِ همپوشانیِ بازهٔ تاریخِ نقش‌ها
SuperRoleConflictRuleجلوگیری از تعارضِ نقشِ سوپر
InvalidCodeRule · MultiAuthFieldRuleاعتبارسنجی‌های ورود/احرازِ هویت

قوانینِ مکانی (ValidPoint، ValidPolygon، ValidMultiPolygon، ValidGeoJson، ValidUtmPoint، PointWithinBoundary) عمومی‌اند و در بخشِ قوانینِ مکانی به‌طور کامل توضیح داده شده‌اند.

نکته

اگر قانونِ رشته‌ایِ جدیدی نیاز شد که در چند جا تکرار می‌شود، آن را نیز در Dornica\Foundation\Core\Rules تعریف کنید تا در یک مکانِ متمرکز نگه‌داری شود.