diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml
index e8d6c80..d969f32 100644
--- a/.github/workflows/fix-php-code-style-issues.yml
+++ b/.github/workflows/fix-php-code-style-issues.yml
@@ -24,11 +24,23 @@ jobs:
with:
ref: ${{ github.head_ref }}
- - name: Fix PHP code style issues
- uses: aglipanci/laravel-pint-action@36de00d5f5a8a4e12d443e01671daa12a18f4c79 # 2.6
+ # NOT aglipanci/laravel-pint-action with `configPath: pint.json`. This
+ # package ships no pint.json, and Pint handed a config path that does not
+ # exist falls back to its OWN defaults and exits 0 rather than failing. So
+ # this job was rewriting the code to Pint's defaults and committing that -
+ # while `composer pint` checks the shared laranail config. The two
+ # disagreed, and this one won because it pushes.
+ - name: Setup PHP
+ uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
- configPath: pint.json
- verboseMode: true
+ php-version: '8.5'
+ coverage: none
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Fix PHP code style issues
+ run: composer pint-fix
- name: Pull latest changes
env:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4cd9abe..579bf46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,22 @@ Entries below `Unreleased` are written by CI from the GitHub release body — se
## Unreleased
-_Nothing yet._
+### Fixed
+
+- **The code-style CI job was formatting against Pint's defaults, not the shared laranail config.**
+ `fix-php-code-style-issues.yml` ran `aglipanci/laravel-pint-action` with `configPath: pint.json` -
+ a file this package does not ship. Pint handed a config path that does not exist falls back to its
+ own defaults and exits 0, so the job rewrote every touched file to the wrong style and committed
+ the result, while `composer pint` graded against
+ `vendor/laranail/package-tools/pint.json`. The job now installs dependencies and runs
+ `composer pint-fix`, which is the same command the `lint` gate checks. 259 files are reformatted
+ by this change; no behaviour is affected (6276 tests, 10486 assertions, identical before and after).
+
+### Changed
+
+- `PostIncDecToPreIncDecRector` is skipped. Rector rewrote `$i++` to `++$i` in 21 files and Pint's
+ `increment_style` rewrote every one of them back, so the two gates could never both pass.
+ Formatting belongs to Pint.
## v0.1.0 - 2026-08-27
diff --git a/benchmark.php b/benchmark.php
index 547ad9b..236fd1e 100644
--- a/benchmark.php
+++ b/benchmark.php
@@ -14,15 +14,15 @@
* php benchmark.php --json Output JSON
*/
-require __DIR__.'/vendor/autoload.php';
+require __DIR__ . '/vendor/autoload.php';
-use Illuminate\Contracts\Validation\ValidationRule;
-use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
+use Simtabi\Laranail\Validation\RuleSet;
+use Illuminate\Support\Facades\Validator;
+use Simtabi\Laranail\Validation\FluentRule;
use Illuminate\Validation\ValidationException;
use Orchestra\Testbench\Foundation\Application;
-use Simtabi\Laranail\Validation\FluentRule;
-use Simtabi\Laranail\Validation\RuleSet;
+use Illuminate\Contracts\Validation\ValidationRule;
$isSnapshot = in_array('--snapshot', $argv);
$isCi = in_array('--ci', $argv);
@@ -37,13 +37,13 @@
function makeProducts(int $count): array
{
return array_map(fn (int $i): array => [
- 'sku' => "SKU-{$i}",
- 'name' => "Product {$i}",
- 'price' => round(9.99 + ($i % 100) * 0.5, 2),
+ 'sku' => "SKU-{$i}",
+ 'name' => "Product {$i}",
+ 'price' => round(9.99 + ($i % 100) * 0.5, 2),
'quantity' => $i % 1000,
'category' => ['electronics', 'clothing', 'food', 'books', 'toys'][$i % 5],
- 'active' => $i % 2 === 0,
- 'tags' => 'tag-'.($i % 20),
+ 'active' => $i % 2 === 0,
+ 'tags' => 'tag-' . ($i % 20),
], range(1, $count));
}
@@ -51,11 +51,11 @@ function makeOrders(int $orders, int $lineItemsPerOrder): array
{
return array_map(fn (int $i): array => [
'order_number' => "ORD-{$i}",
- 'status' => ['pending', 'processing', 'shipped'][$i % 3],
- 'line_items' => array_map(fn (int $j): array => [
+ 'status' => ['pending', 'processing', 'shipped'][$i % 3],
+ 'line_items' => array_map(fn (int $j): array => [
'product_id' => ($i * 10 + $j) % 9999 + 1,
- 'quantity' => $j + 1,
- 'price' => round(10.00 + $j * 2.5, 2),
+ 'quantity' => $j + 1,
+ 'price' => round(10.00 + $j * 2.5, 2),
], range(1, $lineItemsPerOrder)),
], range(1, $orders));
}
@@ -63,19 +63,19 @@ function makeOrders(int $orders, int $lineItemsPerOrder): array
function makeEvents(int $count): array
{
return array_map(fn (int $i): array => [
- 'name' => "Event {$i}",
- 'start_date' => '2025-06-'.str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
- 'end_date' => '2025-07-'.str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
- 'registration_deadline' => '2025-05-'.str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
+ 'name' => "Event {$i}",
+ 'start_date' => '2025-06-' . str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
+ 'end_date' => '2025-07-' . str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
+ 'registration_deadline' => '2025-05-' . str_pad((string) ($i % 28 + 1), 2, '0', STR_PAD_LEFT),
], range(1, $count));
}
function makeArticles(int $count): array
{
return array_map(fn (int $i): array => [
- 'title' => "Article {$i}",
- 'slug' => "article-{$i}",
- 'content' => str_repeat('Word ', 120),
+ 'title' => "Article {$i}",
+ 'slug' => "article-{$i}",
+ 'content' => str_repeat('Word ', 120),
'category' => ['tech', 'science', 'art'][$i % 3],
'priority' => $i % 10,
], range(1, $count));
@@ -170,7 +170,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 1. Product import — 500 items, all fast-checkable ---
$scenarios['Product import — 500 items, simple rules'] = [
'optimizations' => 'Wildcard, fast-check',
- 'native' => [
+ 'native' => [
['products' => 'required|array', 'products.*.sku' => 'required|string|max:50|regex:/^SKU-/', 'products.*.name' => 'required|string|min:2|max:255', 'products.*.price' => 'required|numeric|min:0', 'products.*.quantity' => 'required|numeric|integer|min:0', 'products.*.category' => ['required', 'string', Rule::in(['electronics', 'clothing', 'food', 'books', 'toys'])], 'products.*.active' => 'required|boolean', 'products.*.tags' => 'nullable|string|max:50'],
['products' => $products500],
],
@@ -183,7 +183,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 2. Nested order lines — 1000 orders × 5 line items ---
$scenarios['Nested order lines — 1000 orders × 5 line items'] = [
'optimizations' => 'Wildcard, fast-check (nested)',
- 'native' => [
+ 'native' => [
['orders' => 'required|array', 'orders.*.order_number' => 'required|string|alpha_dash|min:5', 'orders.*.status' => ['required', 'string', Rule::in(['pending', 'processing', 'shipped'])], 'orders.*.line_items' => 'required|array|min:1', 'orders.*.line_items.*.product_id' => 'required|integer|min:1', 'orders.*.line_items.*.quantity' => 'required|integer|min:1', 'orders.*.line_items.*.price' => 'required|numeric|min:0.01'],
['orders' => $orders1000],
],
@@ -196,7 +196,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 3. Event scheduling — field-reference date comparisons (partial fast-check) ---
$scenarios['Event scheduling — 100 items, field-ref dates'] = [
'optimizations' => 'Wildcard, partial fast-check',
- 'native' => [
+ 'native' => [
['events' => 'required|array', 'events.*.name' => 'required|string|min:3|max:255', 'events.*.start_date' => 'required|date|after:2025-01-01', 'events.*.end_date' => 'required|date|after:events.*.start_date', 'events.*.registration_deadline' => 'required|date|before:events.*.start_date'],
['events' => $events100],
],
@@ -209,7 +209,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 4. Article submission — custom Rule objects (wildcard expansion only) ---
$scenarios['Article submission — 50 items, custom Rule objects'] = [
'optimizations' => 'Wildcard only',
- 'native' => [
+ 'native' => [
['articles' => 'required|array', 'articles.*.title' => 'required|string|min:3|max:255', 'articles.*.slug' => 'required|string|alpha_dash|max:255', 'articles.*.content' => ['required', 'string', $minWordCount], 'articles.*.category' => ['required', $validCategory], 'articles.*.priority' => ['required', $validPriority]],
['articles' => $articles50],
],
@@ -222,95 +222,95 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 5. Conditional import — 100 items, ~47 wildcard patterns with exclude_unless ---
$interactionTypes = ['button', 'hotspot', 'scroll_area', 'image', 'chapter', 'menu', 'frame', 'text', 'iframe'];
$interactions100 = array_map(fn (int $i): array => [
- 'type' => $interactionTypes[$i % count($interactionTypes)],
- 'title' => "Interaction {$i}",
- 'start_time' => $i * 10,
- 'end_time' => $i * 10 + 5,
- 'position' => 'bottom',
- 'should_start_collapsed' => false,
+ 'type' => $interactionTypes[$i % count($interactionTypes)],
+ 'title' => "Interaction {$i}",
+ 'start_time' => $i * 10,
+ 'end_time' => $i * 10 + 5,
+ 'position' => 'bottom',
+ 'should_start_collapsed' => false,
'should_collapse_after_menu_item_click' => true,
- 'should_pause_when_shown' => false,
- 'should_not_use_time' => false,
- 'should_use_menu_layout' => false,
- 'text' => '
Sample text
',
- 'text_stroke' => null,
- 'should_fade_volume' => false,
- 'sound_url' => null,
- 'should_enable_sound' => false,
- 'should_fade_in' => true,
- 'should_fade_out' => true,
- 'image_url' => $interactionTypes[$i % count($interactionTypes)] === 'image' ? 'https://example.com/image.png' : null,
- 'style' => [
- 'top' => '10%', 'left' => '20%', 'height' => '30%', 'width' => '40%',
+ 'should_pause_when_shown' => false,
+ 'should_not_use_time' => false,
+ 'should_use_menu_layout' => false,
+ 'text' => 'Sample text
',
+ 'text_stroke' => null,
+ 'should_fade_volume' => false,
+ 'sound_url' => null,
+ 'should_enable_sound' => false,
+ 'should_fade_in' => true,
+ 'should_fade_out' => true,
+ 'image_url' => $interactionTypes[$i % count($interactionTypes)] === 'image' ? 'https://example.com/image.png' : null,
+ 'style' => [
+ 'top' => '10%', 'left' => '20%', 'height' => '30%', 'width' => '40%',
'background_color' => '#ff0000', 'border_radius' => 5,
- 'padding_top' => 10, 'padding_bottom' => 10,
- 'border' => ['width' => 1, 'style' => 'solid', 'color' => '#000000'],
+ 'padding_top' => 10, 'padding_bottom' => 10,
+ 'border' => ['width' => 1, 'style' => 'solid', 'color' => '#000000'],
],
- 'action' => ['type' => 'link', 'link' => 'https://example.com', 'time' => 0],
+ 'action' => ['type' => 'link', 'link' => 'https://example.com', 'time' => 0],
'attributes' => [
'show_indicator' => true, 'indicator_color' => '#00ff00', 'blinking_speed' => 'normal',
- 'options' => ['menu_button_location' => 'top', 'menu_button_name' => 'Menu'],
+ 'options' => ['menu_button_location' => 'top', 'menu_button_name' => 'Menu'],
],
'chapters' => $i % count($interactionTypes) === 4 ? array_map(fn (int $j): array => [
- 'title' => "Chapter {$j}", 'title_short' => null,
+ 'title' => "Chapter {$j}", 'title_short' => null,
'start_time' => $j * 5, 'end_time' => $j * 5 + 4, 'sort_order' => $j,
], range(1, 4)) : [],
], range(1, 100));
$conditionalRules = [
- 'interactions' => 'required|array|min:1',
- 'interactions.*.type' => ['required', 'string', Rule::in($interactionTypes)],
- 'interactions.*.title' => ['nullable', 'string'],
- 'interactions.*.start_time' => ['required', 'numeric', 'min:0'],
- 'interactions.*.end_time' => ['required', 'numeric', 'gte:interactions.*.start_time'],
- 'interactions.*.position' => ['bail', ['exclude_unless', 'interactions.*.type', 'chapter', 'menu'], 'string'],
- 'interactions.*.should_start_collapsed' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'boolean'],
- 'interactions.*.should_collapse_after_menu_item_click' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'boolean'],
- 'interactions.*.should_pause_when_shown' => [['exclude_unless', 'interactions.*.type', 'chapter', 'menu'], 'nullable', 'boolean'],
- 'interactions.*.should_not_use_time' => [['exclude_unless', 'interactions.*.type', 'menu'], 'nullable', 'boolean'],
- 'interactions.*.should_use_menu_layout' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'nullable', 'boolean'],
- 'interactions.*.text' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'string'],
- 'interactions.*.text_stroke' => [['exclude_unless', 'interactions.*.type', 'text'], 'nullable', 'string'],
- 'interactions.*.should_fade_volume' => ['boolean'],
- 'interactions.*.sound_url' => ['bail', ['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image'], 'nullable', 'string'],
- 'interactions.*.should_enable_sound' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image'], 'boolean'],
- 'interactions.*.should_fade_in' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text'], 'boolean'],
- 'interactions.*.should_fade_out' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text'], 'boolean'],
- 'interactions.*.image_url' => ['bail', ['exclude_unless', 'interactions.*.type', 'image', 'hotspot'], ['required_if', 'interactions.*.type', 'image'], 'nullable', 'string'],
- 'interactions.*.style.top' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
- 'interactions.*.style.left' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
- 'interactions.*.style.height' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
- 'interactions.*.style.width' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
- 'interactions.*.style.background_color' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'string'],
- 'interactions.*.style.border_radius' => ['bail', ['exclude_unless', 'interactions.*.type', 'button', 'hotspot'], 'nullable', 'numeric', 'integer', 'between:0,360'],
- 'interactions.*.style.padding_top' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'numeric', 'integer'],
- 'interactions.*.style.padding_bottom' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'numeric', 'integer'],
- 'interactions.*.style.border' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'array'],
- 'interactions.*.style.border.width' => ['nullable', 'numeric', 'integer', 'min:0'],
- 'interactions.*.style.border.style' => ['nullable', 'string', Rule::in(['solid', 'dashed', 'dotted', 'none'])],
- 'interactions.*.style.border.color' => ['nullable', 'string'],
- 'interactions.*.action' => ['nullable', 'array'],
- 'interactions.*.action.type' => ['nullable', 'string', Rule::in(['link', 'time', 'video', 'none'])],
- 'interactions.*.action.link' => ['nullable', 'string'],
- 'interactions.*.action.time' => ['nullable', 'numeric'],
- 'interactions.*.attributes' => ['nullable', 'array'],
- 'interactions.*.attributes.show_indicator' => ['nullable', 'boolean'],
- 'interactions.*.attributes.indicator_color' => ['nullable', 'string'],
- 'interactions.*.attributes.blinking_speed' => ['nullable', 'string', Rule::in(['slow', 'normal', 'fast', 'none'])],
- 'interactions.*.attributes.options' => ['nullable', 'array'],
+ 'interactions' => 'required|array|min:1',
+ 'interactions.*.type' => ['required', 'string', Rule::in($interactionTypes)],
+ 'interactions.*.title' => ['nullable', 'string'],
+ 'interactions.*.start_time' => ['required', 'numeric', 'min:0'],
+ 'interactions.*.end_time' => ['required', 'numeric', 'gte:interactions.*.start_time'],
+ 'interactions.*.position' => ['bail', ['exclude_unless', 'interactions.*.type', 'chapter', 'menu'], 'string'],
+ 'interactions.*.should_start_collapsed' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'boolean'],
+ 'interactions.*.should_collapse_after_menu_item_click' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'boolean'],
+ 'interactions.*.should_pause_when_shown' => [['exclude_unless', 'interactions.*.type', 'chapter', 'menu'], 'nullable', 'boolean'],
+ 'interactions.*.should_not_use_time' => [['exclude_unless', 'interactions.*.type', 'menu'], 'nullable', 'boolean'],
+ 'interactions.*.should_use_menu_layout' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'nullable', 'boolean'],
+ 'interactions.*.text' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'string'],
+ 'interactions.*.text_stroke' => [['exclude_unless', 'interactions.*.type', 'text'], 'nullable', 'string'],
+ 'interactions.*.should_fade_volume' => ['boolean'],
+ 'interactions.*.sound_url' => ['bail', ['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image'], 'nullable', 'string'],
+ 'interactions.*.should_enable_sound' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image'], 'boolean'],
+ 'interactions.*.should_fade_in' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text'], 'boolean'],
+ 'interactions.*.should_fade_out' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text'], 'boolean'],
+ 'interactions.*.image_url' => ['bail', ['exclude_unless', 'interactions.*.type', 'image', 'hotspot'], ['required_if', 'interactions.*.type', 'image'], 'nullable', 'string'],
+ 'interactions.*.style.top' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
+ 'interactions.*.style.left' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
+ 'interactions.*.style.height' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
+ 'interactions.*.style.width' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'image', 'text', 'iframe'], 'string'],
+ 'interactions.*.style.background_color' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'string'],
+ 'interactions.*.style.border_radius' => ['bail', ['exclude_unless', 'interactions.*.type', 'button', 'hotspot'], 'nullable', 'numeric', 'integer', 'between:0,360'],
+ 'interactions.*.style.padding_top' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'numeric', 'integer'],
+ 'interactions.*.style.padding_bottom' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'numeric', 'integer'],
+ 'interactions.*.style.border' => [['exclude_unless', 'interactions.*.type', 'button', 'hotspot', 'text'], 'nullable', 'array'],
+ 'interactions.*.style.border.width' => ['nullable', 'numeric', 'integer', 'min:0'],
+ 'interactions.*.style.border.style' => ['nullable', 'string', Rule::in(['solid', 'dashed', 'dotted', 'none'])],
+ 'interactions.*.style.border.color' => ['nullable', 'string'],
+ 'interactions.*.action' => ['nullable', 'array'],
+ 'interactions.*.action.type' => ['nullable', 'string', Rule::in(['link', 'time', 'video', 'none'])],
+ 'interactions.*.action.link' => ['nullable', 'string'],
+ 'interactions.*.action.time' => ['nullable', 'numeric'],
+ 'interactions.*.attributes' => ['nullable', 'array'],
+ 'interactions.*.attributes.show_indicator' => ['nullable', 'boolean'],
+ 'interactions.*.attributes.indicator_color' => ['nullable', 'string'],
+ 'interactions.*.attributes.blinking_speed' => ['nullable', 'string', Rule::in(['slow', 'normal', 'fast', 'none'])],
+ 'interactions.*.attributes.options' => ['nullable', 'array'],
'interactions.*.attributes.options.menu_button_location' => ['nullable', 'string'],
- 'interactions.*.attributes.options.menu_button_name' => ['nullable', 'string'],
- 'interactions.*.chapters' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'array', 'min:1', 'max:16'],
- 'interactions.*.chapters.*.title' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'string'],
- 'interactions.*.chapters.*.title_short' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'nullable', 'string'],
- 'interactions.*.chapters.*.start_time' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'numeric', 'min:0'],
- 'interactions.*.chapters.*.end_time' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'numeric'],
- 'interactions.*.chapters.*.sort_order' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'integer', 'min:0'],
+ 'interactions.*.attributes.options.menu_button_name' => ['nullable', 'string'],
+ 'interactions.*.chapters' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'array', 'min:1', 'max:16'],
+ 'interactions.*.chapters.*.title' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'string'],
+ 'interactions.*.chapters.*.title_short' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'nullable', 'string'],
+ 'interactions.*.chapters.*.start_time' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'numeric', 'min:0'],
+ 'interactions.*.chapters.*.end_time' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'numeric'],
+ 'interactions.*.chapters.*.sort_order' => [['exclude_unless', 'interactions.*.type', 'chapter'], 'required', 'integer', 'min:0'],
];
$scenarios['Conditional import — 100 items, 47 conditional fields'] = [
'optimizations' => 'Wildcard, pre-evaluation',
- 'native' => [
+ 'native' => [
$conditionalRules,
['interactions' => $interactions100],
],
@@ -323,7 +323,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// --- 6. Login form — no wildcards, minimal rules ---
$scenarios['Login form — 3 fields, no wildcards'] = [
'optimizations' => 'Fast-check (flat)',
- 'native' => [
+ 'native' => [
['email' => 'required|string|email|max:255', 'password' => 'required|string|min:8', 'remember' => 'nullable|boolean'],
['email' => 'user@example.com', 'password' => 'secure-password-123', 'remember' => true],
],
@@ -350,9 +350,9 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
$results[$label] = [
'optimizations' => $config['optimizations'],
- 'native_ms' => round($native, 1),
- 'optimized_ms' => round($ruleSet, 1),
- 'speedup' => round($speedup, 1),
+ 'native_ms' => round($native, 1),
+ 'optimized_ms' => round($ruleSet, 1),
+ 'speedup' => round($speedup, 1),
];
}
@@ -360,16 +360,16 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
// Output
// =========================================================================
-$snapshotFile = __DIR__.'/benchmark-snapshot.json';
+$snapshotFile = __DIR__ . '/benchmark-snapshot.json';
if ($isSnapshot) {
- file_put_contents($snapshotFile, json_encode($results, JSON_PRETTY_PRINT)."\n");
+ file_put_contents($snapshotFile, json_encode($results, JSON_PRETTY_PRINT) . "\n");
echo "Snapshot saved to benchmark-snapshot.json\n";
exit(0);
}
if ($isJson) {
- echo json_encode($results, JSON_PRETTY_PRINT)."\n";
+ echo json_encode($results, JSON_PRETTY_PRINT) . "\n";
exit(0);
}
diff --git a/config/laranail-validation.php b/config/laranail-validation.php
index 98fb1ac..5d92d6a 100644
--- a/config/laranail-validation.php
+++ b/config/laranail-validation.php
@@ -24,7 +24,7 @@
'aliases' => [
'enabled' => env('LARANAIL_VALIDATION_ALIASES', false),
- 'prefix' => 'laranail_',
+ 'prefix' => 'laranail_',
],
/*
diff --git a/rector-migrate-1.0.php b/rector-migrate-1.0.php
index 16edec2..6703c8e 100644
--- a/rector-migrate-1.0.php
+++ b/rector-migrate-1.0.php
@@ -3,9 +3,9 @@
declare(strict_types=1);
use Rector\Config\RectorConfig;
-use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
+use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
/**
* The 0.x → 1.0 migration set (UPGRADING.md, v1.0.0). Run it against an
diff --git a/rector.php b/rector.php
index afec81e..008a7b7 100644
--- a/rector.php
+++ b/rector.php
@@ -2,21 +2,22 @@
declare(strict_types=1);
+use Rector\Config\RectorConfig;
+use RectorPest\Set\PestSetList;
+use RectorLaravel\Set\LaravelSetList;
+use RectorPest\Rules\UseToMatchRector;
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
-use Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector;
-use Rector\CodeQuality\Rector\BooleanOr\RepeatedOrEqualToInArrayRector;
-use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
-use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
-use Rector\Config\RectorConfig;
+use Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector;
+use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector;
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
+use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
+use Rector\CodeQuality\Rector\BooleanOr\RepeatedOrEqualToInArrayRector;
+use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
-use RectorLaravel\Set\LaravelSetList;
-use RectorPest\Rules\UseToMatchRector;
-use RectorPest\Set\PestSetList;
return RectorConfig::configure()
->withCache(
@@ -25,10 +26,10 @@
containerCacheDirectory: './.cache/rectorContainer',
)
->withPaths([
- __DIR__.'/src',
- __DIR__.'/tests',
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
])
- ->withSkipPath(__DIR__.'/tests/Fixtures/MacroableFootgun')
+ ->withSkipPath(__DIR__ . '/tests/Fixtures/MacroableFootgun')
->withPreparedSets(
deadCode: true,
codeQuality: true,
@@ -60,6 +61,11 @@
PestSetList::PEST_LARAVEL,
])
->withSkip([
+ // Pint owns formatting, and it disagrees: Rector rewrites $i++ to ++$i,
+ // Pint's laravel preset rewrites it straight back. Verified by running
+ // them in sequence - Rector changed 21 files, Pint reverted every one,
+ // so the two gates could never both pass. Formatting goes to Pint.
+ PostIncDecToPreIncDecRector::class,
DateFuncCallToCarbonRector::class,
NullToStrictStringFuncCallArgRector::class,
AddArrowFunctionReturnTypeRector::class,
@@ -78,6 +84,6 @@
// Hot-path closure allocates a literal array on every invocation
// when in_array() is used. Explicit === comparisons avoid that.
RepeatedOrEqualToInArrayRector::class => [
- __DIR__.'/src/FastCheckCompiler.php',
+ __DIR__ . '/src/FastCheckCompiler.php',
],
]);
diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php
index 20b147e..0fb18f6 100644
--- a/resources/lang/en/validation.php
+++ b/resources/lang/en/validation.php
@@ -17,27 +17,27 @@
return [
// Banking
- 'bic' => 'The :attribute must be a valid BIC/SWIFT code.',
+ 'bic' => 'The :attribute must be a valid BIC/SWIFT code.',
'bsb_number' => 'The :attribute must be a valid BSB number.',
- 'iban' => 'The :attribute must be a valid IBAN.',
- 'isin' => 'The :attribute must be a valid ISIN.',
- 'luhn' => 'The :attribute must pass the Luhn checksum.',
+ 'iban' => 'The :attribute must be a valid IBAN.',
+ 'isin' => 'The :attribute must be a valid ISIN.',
+ 'luhn' => 'The :attribute must pass the Luhn checksum.',
// Codes
- 'asin' => 'The :attribute must be a valid ASIN.',
- 'ean' => 'The :attribute must be a valid EAN barcode.',
- 'gtin' => 'The :attribute must be a valid GTIN.',
- 'isbn' => 'The :attribute must be a valid ISBN.',
- 'ismn' => 'The :attribute must be a valid ISMN.',
+ 'asin' => 'The :attribute must be a valid ASIN.',
+ 'ean' => 'The :attribute must be a valid EAN barcode.',
+ 'gtin' => 'The :attribute must be a valid GTIN.',
+ 'isbn' => 'The :attribute must be a valid ISBN.',
+ 'ismn' => 'The :attribute must be a valid ISMN.',
'upc_e' => 'The :attribute must be a valid UPC-E barcode.',
- 'issn' => 'The :attribute must be a valid ISSN.',
+ 'issn' => 'The :attribute must be a valid ISSN.',
// Identifiers
'hash_digest' => 'The :attribute must be a :length-character hex digest.',
- 'imei' => 'The :attribute must be a valid IMEI.',
- 'jwt' => 'The :attribute must be a valid JSON Web Token.',
- 'semver' => 'The :attribute must be a valid semantic version.',
- 'vin' => 'The :attribute must be a valid vehicle identification number.',
+ 'imei' => 'The :attribute must be a valid IMEI.',
+ 'jwt' => 'The :attribute must be a valid JSON Web Token.',
+ 'semver' => 'The :attribute must be a valid semantic version.',
+ 'vin' => 'The :attribute must be a valid vehicle identification number.',
// Telecom
//
@@ -45,21 +45,21 @@
// nothing they can act on; "must be a mobile number" and "must be a number from KE" each name
// the thing to change. None of the three upstream Filament phone packages ships any message at
// all — each tells you to add one to your own validation.php.
- 'phone' => 'The :attribute must be a valid phone number.',
- 'phone_possible' => 'The :attribute is not a possible phone number.',
- 'phone_country' => 'The :attribute must be a phone number from :country.',
- 'phone_type' => 'The :attribute must be a :type number.',
- 'phone_extension' => 'The :attribute must not include an extension.',
+ 'phone' => 'The :attribute must be a valid phone number.',
+ 'phone_possible' => 'The :attribute is not a possible phone number.',
+ 'phone_country' => 'The :attribute must be a phone number from :country.',
+ 'phone_type' => 'The :attribute must be a :type number.',
+ 'phone_extension' => 'The :attribute must not include an extension.',
'phone_short_code' => 'The :attribute must be a full phone number, not a short code.',
- 'phone_emergency' => 'The :attribute must not be an emergency number.',
- 'phone_unique' => 'The :attribute has already been taken.',
+ 'phone_emergency' => 'The :attribute must not be an emergency number.',
+ 'phone_unique' => 'The :attribute has already been taken.',
// Net
- 'cidr' => 'The :attribute must be a valid CIDR network.',
+ 'cidr' => 'The :attribute must be a valid CIDR network.',
'domain_name' => 'The :attribute must be a valid domain name.',
- 'private_ip' => 'The :attribute must be a private or reserved IP address.',
- 'public_ip' => 'The :attribute must be a publicly routable IP address.',
- 'subdomain' => 'The :attribute must be a valid subdomain.',
+ 'private_ip' => 'The :attribute must be a private or reserved IP address.',
+ 'public_ip' => 'The :attribute must be a publicly routable IP address.',
+ 'subdomain' => 'The :attribute must be a valid subdomain.',
//
// Several keys rather than one, because "that is not a URL" and "that
@@ -67,48 +67,48 @@
// single message for both makes a working link look broken for no
// stated reason.
'url' => [
- 'credentials' => 'The :attribute must not contain a username or password.',
- 'fragment' => 'The :attribute must not contain a fragment.',
- 'host' => 'The :attribute must have a valid host.',
- 'host_is' => 'The :attribute must be at one of: :hosts.',
- 'host_is_not' => 'The :attribute must not be at any of: :hosts.',
- 'malformed' => 'The :attribute must be a valid URL.',
- 'port' => 'The :attribute must use one of these ports: :ports.',
+ 'credentials' => 'The :attribute must not contain a username or password.',
+ 'fragment' => 'The :attribute must not contain a fragment.',
+ 'host' => 'The :attribute must have a valid host.',
+ 'host_is' => 'The :attribute must be at one of: :hosts.',
+ 'host_is_not' => 'The :attribute must not be at any of: :hosts.',
+ 'malformed' => 'The :attribute must be a valid URL.',
+ 'port' => 'The :attribute must use one of these ports: :ports.',
'private_host' => 'The :attribute must point at a public address.',
- 'query' => 'The :attribute must not contain a query string.',
- 'scheme' => 'The :attribute must use one of these schemes: :schemes.',
+ 'query' => 'The :attribute must not contain a query string.',
+ 'scheme' => 'The :attribute must use one of these schemes: :schemes.',
],
'mac_address' => [
'broadcast' => 'The :attribute must not be the broadcast address.',
- 'format' => 'The :attribute must be written in one of these notations: :formats.',
- 'length' => 'The :attribute must be :bytes bytes.',
- 'local' => 'The :attribute must be a manufacturer-assigned address, not a randomised one.',
+ 'format' => 'The :attribute must be written in one of these notations: :formats.',
+ 'length' => 'The :attribute must be :bytes bytes.',
+ 'local' => 'The :attribute must be a manufacturer-assigned address, not a randomised one.',
'malformed' => 'The :attribute must be a valid MAC address.',
'multicast' => 'The :attribute must be a unicast address.',
- 'null' => 'The :attribute must not be the null address.',
- 'oui' => 'The :attribute must begin with one of: :ouis.',
+ 'null' => 'The :attribute must not be the null address.',
+ 'oui' => 'The :attribute must begin with one of: :ouis.',
],
'in_cidr_range' => 'The :attribute must be within one of these networks: :networks.',
'slug' => 'The :attribute must be a URL slug: lowercase letters, digits and single hyphens, with no hyphen at the start or end.',
- 'username' => 'The :attribute may contain letters, digits, and single dots, hyphens or underscores between them — not at the start, at the end, or doubled.',
+ 'username' => 'The :attribute may contain letters, digits, and single dots, hyphens or underscores between them — not at the start, at the end, or doubled.',
'username_reserved' => 'The :attribute is reserved. Please choose another.',
// Three keys rather than one. A field whose characters were fine and whose count was not gets
// sent looking for a bad character that is not there.
- 'person_name' => 'The :attribute must be a name: letters, marks, spaces, apostrophes and hyphens.',
- 'person_name_min' => 'The :attribute must contain at least :min names.',
- 'person_name_max' => 'The :attribute must not contain more than :max names.',
+ 'person_name' => 'The :attribute must be a name: letters, marks, spaces, apostrophes and hyphens.',
+ 'person_name_min' => 'The :attribute must contain at least :min names.',
+ 'person_name_max' => 'The :attribute must not contain more than :max names.',
'person_name_required' => 'Please provide at least one of :values.',
'contains_html' => 'The :attribute must contain HTML markup.',
- 'html_clean' => 'The :attribute must not contain HTML tags.',
- 'max_words' => 'The :attribute must not contain more than :max words.',
- 'min_words' => 'The :attribute must contain at least :min words.',
- 'salutation' => 'The :attribute must be a recognised salutation.',
+ 'html_clean' => 'The :attribute must not contain HTML tags.',
+ 'max_words' => 'The :attribute must not contain more than :max words.',
+ 'min_words' => 'The :attribute must contain at least :min words.',
+ 'salutation' => 'The :attribute must be a recognised salutation.',
'without_spaces' => 'The :attribute must not contain any spaces, including non-breaking and zero-width ones.',
@@ -117,63 +117,63 @@
// Networking probes
'has_gravatar' => 'The :attribute must have a Gravatar.',
- 'image_url' => 'The :attribute must be a URL serving an image.',
+ 'image_url' => 'The :attribute must be a URL serving an image.',
// Payment
- 'card_cvc' => 'The :attribute must be a valid security code.',
- 'card_expiry' => 'The :attribute must be a valid expiry date that has not passed.',
- 'card_number' => 'The :attribute is not a recognised card number.',
- 'card_number_brand' => 'The :attribute must be one of these card brands: :brands.',
+ 'card_cvc' => 'The :attribute must be a valid security code.',
+ 'card_expiry' => 'The :attribute must be a valid expiry date that has not passed.',
+ 'card_number' => 'The :attribute is not a recognised card number.',
+ 'card_number_brand' => 'The :attribute must be one of these card brands: :brands.',
'card_number_checksum' => 'The :attribute fails the card number check digit.',
- 'card_number_length' => 'The :attribute must be :lengths digits for :brand.',
+ 'card_number_length' => 'The :attribute must be :lengths digits for :brand.',
// Chrono
- 'date_interval' => 'The :attribute must be an ISO 8601 duration.',
+ 'date_interval' => 'The :attribute must be an ISO 8601 duration.',
'date_interval_positive' => 'The :attribute must be a non-zero ISO 8601 duration.',
- 'max_date_difference' => 'The :attribute must be within :hours hours of the reference date.',
- 'minimum_age' => 'The :attribute must be a date of birth at least :years years ago.',
- 'minute_in' => 'The :attribute must be a time whose minutes are one of: :minutes.',
- 'rfc3339' => 'The :attribute must be an RFC 3339 timestamp.',
- 'time_of_day' => 'The :attribute must be a valid time of day.',
- 'timezone_abbreviation' => 'The :attribute must be a timezone abbreviation.',
- 'unix_timestamp' => 'The :attribute must be a Unix timestamp.',
+ 'max_date_difference' => 'The :attribute must be within :hours hours of the reference date.',
+ 'minimum_age' => 'The :attribute must be a date of birth at least :years years ago.',
+ 'minute_in' => 'The :attribute must be a time whose minutes are one of: :minutes.',
+ 'rfc3339' => 'The :attribute must be an RFC 3339 timestamp.',
+ 'time_of_day' => 'The :attribute must be a valid time of day.',
+ 'timezone_abbreviation' => 'The :attribute must be a timezone abbreviation.',
+ 'unix_timestamp' => 'The :attribute must be a Unix timestamp.',
// Encoding
- 'base64' => 'The :attribute must be a base64-encoded value.',
- 'base64_image' => 'The :attribute must be a base64-encoded image of an accepted type.',
+ 'base64' => 'The :attribute must be a base64-encoded value.',
+ 'base64_image' => 'The :attribute must be a base64-encoded image of an accepted type.',
'base64_image_size' => 'The :attribute must be an image no larger than :max.',
- 'data_uri' => 'The :attribute must be a valid data URI.',
+ 'data_uri' => 'The :attribute must be a valid data URI.',
// I18n
- 'country_code' => 'The :attribute must be a valid ISO 3166-1 country code.',
- 'currency_code' => 'The :attribute must be a valid ISO 4217 currency code.',
+ 'country_code' => 'The :attribute must be a valid ISO 3166-1 country code.',
+ 'currency_code' => 'The :attribute must be a valid ISO 4217 currency code.',
'currency_code_numeric' => 'The :attribute must be a valid ISO 4217 numeric currency code.',
- 'currency_symbol' => 'The :attribute must be a recognised currency symbol.',
- 'language_code' => 'The :attribute must be a valid ISO 639-1 language code.',
+ 'currency_symbol' => 'The :attribute must be a recognised currency symbol.',
+ 'language_code' => 'The :attribute must be a valid ISO 639-1 language code.',
// Geo
'ca_province' => 'The :attribute must be a Canadian province or territory.',
- 'lat_lng' => 'The :attribute must be a latitude,longitude pair.',
- 'latitude' => 'The :attribute must be a latitude between -90 and 90.',
- 'longitude' => 'The :attribute must be a longitude between -180 and 180.',
- 'us_state' => 'The :attribute must be a US state.',
+ 'lat_lng' => 'The :attribute must be a latitude,longitude pair.',
+ 'latitude' => 'The :attribute must be a latitude between -90 and 90.',
+ 'longitude' => 'The :attribute must be a longitude between -180 and 180.',
+ 'us_state' => 'The :attribute must be a US state.',
// Email
'email' => [
- 'disposable' => 'The :attribute must not be a disposable email address.',
- 'domain_is' => 'The :attribute must be at one of: :domains.',
+ 'disposable' => 'The :attribute must not be a disposable email address.',
+ 'domain_is' => 'The :attribute must be at one of: :domains.',
'domain_is_not' => 'The :attribute must not be at any of: :domains.',
- 'malformed' => 'The :attribute must be a valid email address.',
- 'role' => 'The :attribute must belong to a person, not a shared mailbox.',
- 'subaddress' => 'The :attribute must not contain a plus tag.',
+ 'malformed' => 'The :attribute must be a valid email address.',
+ 'role' => 'The :attribute must belong to a person, not a shared mailbox.',
+ 'subaddress' => 'The :attribute must not contain a plus tag.',
'undeliverable' => 'The :attribute is at a domain that cannot receive mail.',
],
// Database
- 'authorized' => 'The selected :attribute is invalid.',
+ 'authorized' => 'The selected :attribute is invalid.',
'compare_to_column' => 'The :attribute is outside the allowed bound.',
- 'models_exist' => [
- 'array' => 'The :attribute must be a list of identifiers.',
+ 'models_exist' => [
+ 'array' => 'The :attribute must be a list of identifiers.',
'missing' => 'The :attribute contains values that do not exist: :values.',
],
@@ -183,15 +183,15 @@
// the field holds a dozen values. Each key names what to change.
'delimited' => [
'distinct' => 'The :attribute must not repeat an entry.',
- 'empty' => 'Entry :position of :attribute is empty — check for a stray separator.',
- 'invalid' => 'The :attribute must be a delimited list.',
- 'item' => 'Entry :position of :attribute is not valid.',
- 'max' => 'The :attribute must not have more than :max entries.',
- 'min' => 'The :attribute must have at least :min entries.',
+ 'empty' => 'Entry :position of :attribute is empty — check for a stray separator.',
+ 'invalid' => 'The :attribute must be a delimited list.',
+ 'item' => 'Entry :position of :attribute is not valid.',
+ 'max' => 'The :attribute must not have more than :max entries.',
+ 'min' => 'The :attribute must have at least :min entries.',
],
// Crypto
- 'bitcoin_address' => 'The :attribute must be a valid Bitcoin address.',
+ 'bitcoin_address' => 'The :attribute must be a valid Bitcoin address.',
'ethereum_address' => 'The :attribute must be a valid Ethereum address.',
// Postal
@@ -200,7 +200,7 @@
// Numbers
'parity' => [
'even' => 'The :attribute must be an even number.',
- 'odd' => 'The :attribute must be an odd number.',
+ 'odd' => 'The :attribute must be an odd number.',
],
'monetary_amount' => 'The :attribute must be an amount with at most :decimals decimal places.',
@@ -208,17 +208,17 @@
'css_color' => 'The :attribute must be a colour in one of these notations: :notations.',
// Anti-spam
- 'honeypot' => 'The :attribute could not be submitted.',
+ 'honeypot' => 'The :attribute could not be submitted.',
'submission_timing' => [
'too_fast' => 'The form was submitted too quickly. Please try again.',
- 'expired' => 'The form has expired. Please reload and try again.',
+ 'expired' => 'The form has expired. Please reload and try again.',
],
// Vendor identifiers
'vendor_identifier' => 'The :attribute must be a valid :vendor identifier.',
// Fiscal
- 'vat_number' => 'The :attribute must be a valid VAT number.',
+ 'vat_number' => 'The :attribute must be a valid VAT number.',
'national_identifier' => 'The :attribute must be a valid :country national identification number.',
// Profanity
@@ -226,8 +226,8 @@
// Markup
'xml' => [
- 'malformed' => 'The :attribute must be well-formed XML.',
- 'schema' => 'The :attribute does not match the required schema.',
+ 'malformed' => 'The :attribute must be well-formed XML.',
+ 'schema' => 'The :attribute does not match the required schema.',
'schema_missing' => 'The :attribute could not be checked: the schema is unavailable.',
],
@@ -236,11 +236,11 @@
| parameter rather than five classes differing by a pattern and a message.
*/
'case_style' => [
- 'camel' => 'The :attribute must be camelCase.',
- 'kebab' => 'The :attribute must be kebab-case.',
+ 'camel' => 'The :attribute must be camelCase.',
+ 'kebab' => 'The :attribute must be kebab-case.',
'pascal' => 'The :attribute must be PascalCase.',
- 'snake' => 'The :attribute must be snake_case.',
- 'title' => 'The :attribute must be Title Case.',
+ 'snake' => 'The :attribute must be snake_case.',
+ 'title' => 'The :attribute must be Title Case.',
],
];
diff --git a/src/Actions/CachedDnsResolver.php b/src/Actions/CachedDnsResolver.php
index 573071e..a150859 100644
--- a/src/Actions/CachedDnsResolver.php
+++ b/src/Actions/CachedDnsResolver.php
@@ -4,10 +4,10 @@
namespace Simtabi\Laranail\Validation\Actions;
-use Illuminate\Contracts\Cache\Repository;
+use Throwable;
use Illuminate\Support\Facades\Cache;
+use Illuminate\Contracts\Cache\Repository;
use Simtabi\Laranail\Validation\Contracts\Email\DnsResolver;
-use Throwable;
/**
* The default {@see DnsResolver}: a cached MX lookup over PHP's resolver.
@@ -68,7 +68,7 @@ public function hasMailExchanger(string $domain): bool
}
/**
- * @param callable(): bool $callback
+ * @param callable(): bool $callback
*/
private function remember(string $domain, callable $callback): bool
{
@@ -80,7 +80,7 @@ private function remember(string $domain, callable $callback): bool
try {
$value = $store->remember(
- self::CACHE_PREFIX.$domain,
+ self::CACHE_PREFIX . $domain,
$this->ttl ?? $this->configuredTtl(),
static fn (): bool => $callback(),
);
diff --git a/src/BatchDatabaseChecker.php b/src/BatchDatabaseChecker.php
index aaa3ea3..ab5d0f2 100644
--- a/src/BatchDatabaseChecker.php
+++ b/src/BatchDatabaseChecker.php
@@ -4,19 +4,19 @@
namespace Simtabi\Laranail\Validation;
-use Illuminate\Validation\DatabasePresenceVerifier;
-use Illuminate\Validation\PresenceVerifierInterface;
+use Throwable;
+use Stringable;
+use ReflectionProperty;
+use ReflectionException;
use Illuminate\Validation\Rules\Exists;
use Illuminate\Validation\Rules\Unique;
-use ReflectionException;
-use ReflectionProperty;
-use Simtabi\Laranail\Validation\Exceptions\BatchLimitExceededException;
-use Simtabi\Laranail\Validation\Internal\BatchPresenceQuery;
+use Illuminate\Validation\DatabasePresenceVerifier;
+use Illuminate\Validation\PresenceVerifierInterface;
use Simtabi\Laranail\Validation\Internal\BatchRuleShape;
-use Simtabi\Laranail\Validation\Internal\PresenceMatchFidelity;
+use Simtabi\Laranail\Validation\Internal\BatchPresenceQuery;
use Simtabi\Laranail\Validation\Internal\ValueTypePredicates;
-use Stringable;
-use Throwable;
+use Simtabi\Laranail\Validation\Internal\PresenceMatchFidelity;
+use Simtabi\Laranail\Validation\Exceptions\BatchLimitExceededException;
/**
* Batches exists/unique database validation queries for wildcard arrays.
@@ -80,7 +80,8 @@ public static function isBatchable(Exists|Unique $rule): bool
/**
* Batch-query which values exist in the database for an Exists rule.
*
- * @param array $values Deduplicated, non-null values to check
+ * @param array $values Deduplicated, non-null values to check
+ *
* @return array Values that exist in the DB
*/
public static function fetchExisting(array $values, Exists $rule): array
@@ -101,7 +102,8 @@ public static function fetchExisting(array $values, Exists $rule): array
/**
* Batch-query which values are already taken for a Unique rule.
*
- * @param array $values Deduplicated, non-null values to check
+ * @param array $values Deduplicated, non-null values to check
+ *
* @return array Values that already exist (taken)
*/
public static function fetchTaken(array $values, Unique $rule): array
@@ -166,7 +168,8 @@ public static function batchableSignature(Exists|Unique $rule, string $table, st
/**
* Find batchable Exists/Unique rules in a set of compiled rules.
*
- * @param array $rules
+ * @param array $rules
+ *
* @return array Field name → rule object
*/
public static function findBatchableRules(array $rules): array
@@ -192,9 +195,10 @@ public static function findBatchableRules(array $rules): array
/**
* Collect values from items for batchable rules and group by table:column.
*
- * @param array $batchableFields
- * @param array $items
- * @param array $fieldRules Per-field rule array used to derive type predicates.
+ * @param array $batchableFields
+ * @param array $items
+ * @param array $fieldRules Per-field rule array used to derive type predicates.
+ *
* @return array}>
*/
public static function collectValues(array $batchableFields, array $items, bool $isScalar, array $fieldRules = []): array
@@ -263,8 +267,9 @@ public static function collectValues(array $batchableFields, array $items, bool
* Unlike collectValues() which iterates items, this iterates expanded
* rules like 'items.0.email', 'items.1.email' and uses data_get().
*
- * @param array $preparedRules Expanded rules with concrete paths
- * @param array $data
+ * @param array $preparedRules Expanded rules with concrete paths
+ * @param array $data
+ *
* @return array}>
*/
public static function collectExpandedValues(array $preparedRules, array $data): array
@@ -331,8 +336,9 @@ public static function collectExpandedValues(array $preparedRules, array $data):
* Object-form rules fall through unchanged; if no known type rule is
* present, values are returned as-is (matches previous behaviour).
*
- * @param array $values
- * @param array|string $itemRules Either a pipe-delimited string or an array of rules.
+ * @param array $values
+ * @param array|string $itemRules Either a pipe-delimited string or an array of rules.
+ *
* @return array
*/
public static function filterValuesByType(array $values, array|string $itemRules): array
@@ -346,9 +352,9 @@ public static function filterValuesByType(array $values, array|string $itemRules
* Groups arrive already filtered (Phase 1) and deduplicated (collectors
* own the dedup). Canonical order is filter → dedup → cap check → query.
*
- * @param array}> $groups
- * @param array $poisonedTableColumns Extra table:columns that must not
- * register a lookup ({@see findPoisonedTableColumns})
+ * @param array}> $groups
+ * @param array $poisonedTableColumns Extra table:columns that must not
+ * register a lookup ({@see findPoisonedTableColumns})
*
* @throws BatchLimitExceededException When any group's value count exceeds `$maxValuesPerGroup`.
*/
@@ -393,11 +399,12 @@ public static function buildVerifier(array $groups, array $poisonedTableColumns
* handles each rule correctly via per-item queries. Rare case, small
* perf hit — exists and unique on the same (table, column) is unusual.
*
- * @param array}> $groups Keyed by "table:column:ruleType"
- * @param array $poisonedTableColumns Table:columns claimed by rules the
- * collectors never saw (a field's second DB rule,
- * non-batchable or string-form rules) — treated
- * exactly like a detected group conflict.
+ * @param array}> $groups Keyed by "table:column:ruleType"
+ * @param array $poisonedTableColumns Table:columns claimed by rules the
+ * collectors never saw (a field's second DB rule,
+ * non-batchable or string-form rules) — treated
+ * exactly like a detected group conflict.
+ *
* @return bool False if any group was skipped, so the caller knows a
* fallback verifier is required to answer it.
*/
@@ -415,7 +422,7 @@ public static function registerLookups(PrecomputedPresenceVerifier $verifier, ar
[$table, $column] = self::parseGroupKey($key);
- if (isset($conflicting[$table.':'.$column])) {
+ if (isset($conflicting[$table . ':' . $column])) {
$complete = false;
continue;
@@ -440,7 +447,8 @@ public static function registerLookups(PrecomputedPresenceVerifier $verifier, ar
/**
* Deduplicate and cast values to strings for batch queries.
*
- * @param array $values
+ * @param array $values
+ *
* @return list
*/
public static function uniqueStringValues(array $values): array
@@ -461,9 +469,9 @@ public static function uniqueStringValues(array $values): array
*/
private static function groupKey(string $table, string $column, Exists|Unique $rule): string
{
- return $table.':'.$column.':'
- .($rule instanceof Unique ? 'unique' : 'exists').':'
- .BatchRuleShape::of(self::extractMeta($rule));
+ return $table . ':' . $column . ':'
+ . ($rule instanceof Unique ? 'unique' : 'exists') . ':'
+ . BatchRuleShape::of(self::extractMeta($rule));
}
/**
@@ -471,7 +479,7 @@ private static function groupKey(string $table, string $column, Exists|Unique $r
* Called after filter/dedup so the cap sees the same normalised set the
* query will.
*
- * @param array}> $groups
+ * @param array}> $groups
*/
private static function assertWithinCap(array $groups): void
{
@@ -500,7 +508,8 @@ private static function assertWithinCap(array $groups): void
* one rule type in the grouped rules (i.e. both an exists and a unique
* group exist for the same physical column).
*
- * @param array}> $groups
+ * @param array}> $groups
+ *
* @return array
*/
private static function findConflictingTableColumns(array $groups): array
@@ -514,7 +523,7 @@ private static function findConflictingTableColumns(array $groups): array
// Keyed by rule type AND query shape: the verifier looks up by
// table and column only, so anything that would have queried
// differently cannot share that lookup.
- $seen[$table.':'.$column][$ruleType.':'.$shape] = true;
+ $seen[$table . ':' . $column][$ruleType . ':' . $shape] = true;
}
$conflicting = [];
@@ -584,11 +593,11 @@ private static function extractMeta(Exists|Unique $rule): ?array
return [
'connection' => $connection,
- 'table' => $table,
- 'column' => $column === 'NULL' ? '' : $column,
- 'wheres' => $typedWheres,
- 'ignore' => $ignore,
- 'idColumn' => $idColumn,
+ 'table' => $table,
+ 'column' => $column === 'NULL' ? '' : $column,
+ 'wheres' => $typedWheres,
+ 'ignore' => $ignore,
+ 'idColumn' => $idColumn,
];
} catch (ReflectionException) {
return null;
diff --git a/src/Builder/Concerns/HasEmbeddedRules.php b/src/Builder/Concerns/HasEmbeddedRules.php
index 5273037..2485cb7 100644
--- a/src/Builder/Concerns/HasEmbeddedRules.php
+++ b/src/Builder/Concerns/HasEmbeddedRules.php
@@ -4,10 +4,10 @@
namespace Simtabi\Laranail\Validation\Builder\Concerns;
-use BackedEnum;
use Closure;
-use Illuminate\Contracts\Support\Arrayable;
+use BackedEnum;
use Illuminate\Validation\Rule;
+use Illuminate\Contracts\Support\Arrayable;
trait HasEmbeddedRules
{
diff --git a/src/Builder/Concerns/HasFieldModifiers.php b/src/Builder/Concerns/HasFieldModifiers.php
index 8967644..14bd115 100644
--- a/src/Builder/Concerns/HasFieldModifiers.php
+++ b/src/Builder/Concerns/HasFieldModifiers.php
@@ -4,24 +4,24 @@
namespace Simtabi\Laranail\Validation\Builder\Concerns;
-use BackedEnum;
use Closure;
+use BackedEnum;
+use LogicException;
use Illuminate\Support\Arr;
use Illuminate\Support\Fluent;
use Illuminate\Validation\Rule;
-use Illuminate\Validation\Rules\Contains;
-use Illuminate\Validation\Rules\DoesntContain;
-use Illuminate\Validation\Rules\ExcludeIf;
-use Illuminate\Validation\Rules\ExcludeUnless;
-use Illuminate\Validation\Rules\Exists;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\Rules\NotIn;
-use Illuminate\Validation\Rules\ProhibitedIf;
-use Illuminate\Validation\Rules\ProhibitedUnless;
+use Illuminate\Validation\Rules\Exists;
+use Illuminate\Validation\Rules\Unique;
+use Illuminate\Validation\Rules\Contains;
+use Illuminate\Validation\Rules\ExcludeIf;
use Illuminate\Validation\Rules\RequiredIf;
+use Illuminate\Validation\Rules\ProhibitedIf;
+use Illuminate\Validation\Rules\DoesntContain;
+use Illuminate\Validation\Rules\ExcludeUnless;
use Illuminate\Validation\Rules\RequiredUnless;
-use Illuminate\Validation\Rules\Unique;
-use LogicException;
+use Illuminate\Validation\Rules\ProhibitedUnless;
trait HasFieldModifiers
{
@@ -132,22 +132,22 @@ public function present(?string $message = null): static
public function presentIf(string $field, string|int|bool|BackedEnum ...$values): static
{
- return $this->addRule('present_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('present_if:' . $field . ',' . self::serializeValues($values));
}
public function presentUnless(string $field, string|int|bool|BackedEnum ...$values): static
{
- return $this->addRule('present_unless:'.$field.','.self::serializeValues($values));
+ return $this->addRule('present_unless:' . $field . ',' . self::serializeValues($values));
}
public function presentWith(string ...$fields): static
{
- return $this->addRule('present_with:'.implode(',', $fields));
+ return $this->addRule('present_with:' . implode(',', $fields));
}
public function presentWithAll(string ...$fields): static
{
- return $this->addRule('present_with_all:'.implode(',', $fields));
+ return $this->addRule('present_with_all:' . implode(',', $fields));
}
public function prohibited(?string $message = null): static
@@ -167,22 +167,22 @@ public function missing(?string $message = null): static
public function missingIf(string $field, string|int|bool|BackedEnum ...$values): static
{
- return $this->addRule('missing_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('missing_if:' . $field . ',' . self::serializeValues($values));
}
public function missingUnless(string $field, string|int|bool|BackedEnum ...$values): static
{
- return $this->addRule('missing_unless:'.$field.','.self::serializeValues($values));
+ return $this->addRule('missing_unless:' . $field . ',' . self::serializeValues($values));
}
public function missingWith(string ...$fields): static
{
- return $this->addRule('missing_with:'.implode(',', $fields));
+ return $this->addRule('missing_with:' . implode(',', $fields));
}
public function missingWithAll(string ...$fields): static
{
- return $this->addRule('missing_with_all:'.implode(',', $fields));
+ return $this->addRule('missing_with_all:' . implode(',', $fields));
}
public function requiredIf(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -191,7 +191,7 @@ public function requiredIf(Closure|bool|string $field, string|int|bool|BackedEnu
return $this->addRule(new RequiredIf($field));
}
- return $this->addRule('required_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('required_if:' . $field . ',' . self::serializeValues($values));
}
public function requiredUnless(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -205,37 +205,37 @@ public function requiredUnless(Closure|bool|string $field, string|int|bool|Backe
return $this->addRule(new RequiredUnless($field));
}
- return $this->addRule('required_unless:'.$field.','.self::serializeValues($values));
+ return $this->addRule('required_unless:' . $field . ',' . self::serializeValues($values));
}
public function requiredWith(string ...$fields): static
{
- return $this->addRule('required_with:'.implode(',', $fields));
+ return $this->addRule('required_with:' . implode(',', $fields));
}
public function requiredWithAll(string ...$fields): static
{
- return $this->addRule('required_with_all:'.implode(',', $fields));
+ return $this->addRule('required_with_all:' . implode(',', $fields));
}
public function requiredWithout(string ...$fields): static
{
- return $this->addRule('required_without:'.implode(',', $fields));
+ return $this->addRule('required_without:' . implode(',', $fields));
}
public function requiredWithoutAll(string ...$fields): static
{
- return $this->addRule('required_without_all:'.implode(',', $fields));
+ return $this->addRule('required_without_all:' . implode(',', $fields));
}
public function requiredIfAccepted(string $field, ?string $message = null): static
{
- return $this->addRule('required_if_accepted:'.$field, $message);
+ return $this->addRule('required_if_accepted:' . $field, $message);
}
public function requiredIfDeclined(string $field, ?string $message = null): static
{
- return $this->addRule('required_if_declined:'.$field, $message);
+ return $this->addRule('required_if_declined:' . $field, $message);
}
public function excludeIf(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -251,7 +251,7 @@ public function excludeIf(Closure|bool|string $field, string|int|bool|BackedEnum
return $shouldExclude ? $this->addRule('exclude') : $this;
}
- return $this->addRule('exclude_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('exclude_if:' . $field . ',' . self::serializeValues($values));
}
public function excludeUnless(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -267,17 +267,17 @@ public function excludeUnless(Closure|bool|string $field, string|int|bool|Backed
return $shouldExclude ? $this->addRule('exclude') : $this;
}
- return $this->addRule('exclude_unless:'.$field.','.self::serializeValues($values));
+ return $this->addRule('exclude_unless:' . $field . ',' . self::serializeValues($values));
}
public function excludeWith(string $field): static
{
- return $this->addRule('exclude_with:'.$field);
+ return $this->addRule('exclude_with:' . $field);
}
public function excludeWithout(string $field): static
{
- return $this->addRule('exclude_without:'.$field);
+ return $this->addRule('exclude_without:' . $field);
}
public function prohibitedIf(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -286,7 +286,7 @@ public function prohibitedIf(Closure|bool|string $field, string|int|bool|BackedE
return $this->addRule(new ProhibitedIf($field));
}
- return $this->addRule('prohibited_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('prohibited_if:' . $field . ',' . self::serializeValues($values));
}
public function prohibitedUnless(Closure|bool|string $field, string|int|bool|BackedEnum ...$values): static
@@ -298,22 +298,22 @@ public function prohibitedUnless(Closure|bool|string $field, string|int|bool|Bac
return $this->addRule(new ProhibitedUnless($field));
}
- return $this->addRule('prohibited_unless:'.$field.','.self::serializeValues($values));
+ return $this->addRule('prohibited_unless:' . $field . ',' . self::serializeValues($values));
}
public function prohibits(string ...$fields): static
{
- return $this->addRule('prohibits:'.implode(',', $fields));
+ return $this->addRule('prohibits:' . implode(',', $fields));
}
public function prohibitedIfAccepted(string $field, ?string $message = null): static
{
- return $this->addRule('prohibited_if_accepted:'.$field, $message);
+ return $this->addRule('prohibited_if_accepted:' . $field, $message);
}
public function prohibitedIfDeclined(string $field, ?string $message = null): static
{
- return $this->addRule('prohibited_if_declined:'.$field, $message);
+ return $this->addRule('prohibited_if_declined:' . $field, $message);
}
/**
@@ -328,14 +328,14 @@ public function prohibitedIfDeclined(string $field, ?string $message = null): st
* instance — there is no defensive copy. Clone first if you need
* isolation: `(clone $ruleSet->get($field))->rule($extra)`.
*
- * @param object|string|array $rule
+ * @param object|string|array $rule
*/
public function rule(object|string|array $rule, ?string $message = null): static
{
if (is_array($rule)) {
$params = array_slice($rule, 1);
- return $this->addRule($params === [] ? $rule[0] : $rule[0].':'.implode(',', $params), $message);
+ return $this->addRule($params === [] ? $rule[0] : $rule[0] . ':' . implode(',', $params), $message);
}
return $this->addRule($rule, $message);
@@ -353,9 +353,9 @@ public function rule(object|string|array $rule, ?string $message = null): static
* fn ($r) => $r->sometimes()->max(100),
* )
*
- * @param Closure(Fluent): bool $condition
- * @param Closure(static): static|string|list $rules
- * @param Closure(static): static|string|list $defaultRules
+ * @param Closure(Fluent): bool $condition
+ * @param Closure(static): static|string|list $rules
+ * @param Closure(static): static|string|list $defaultRules
*/
public function whenInput(Closure $condition, Closure|string|array $rules, Closure|string|array $defaultRules = []): static
{
@@ -385,7 +385,7 @@ protected function seedLastConstraint(string $name): void
* resolved $lastConstraint key. Throws LogicException if $message is
* set but no rule was added (e.g. an early-return branch in a caller).
*
- * @param array|string|object $rules
+ * @param array|string|object $rules
*/
protected function addRule(array|string|object $rules, ?string $message = null): static
{
@@ -395,19 +395,19 @@ protected function addRule(array|string|object $rules, ?string $message = null):
$this->rules[] = $rules;
$this->lastConstraint = match (true) {
- $rules instanceof RequiredIf => 'required',
- $rules instanceof RequiredUnless => 'required',
- $rules instanceof ProhibitedIf => 'prohibited',
+ $rules instanceof RequiredIf => 'required',
+ $rules instanceof RequiredUnless => 'required',
+ $rules instanceof ProhibitedIf => 'prohibited',
$rules instanceof ProhibitedUnless => 'prohibited',
- $rules instanceof ExcludeIf => 'exclude',
- $rules instanceof ExcludeUnless => 'exclude',
- $rules instanceof In => 'in',
- $rules instanceof NotIn => 'not_in',
- $rules instanceof Unique => 'unique',
- $rules instanceof Exists => 'exists',
- $rules instanceof Contains => 'contains',
- $rules instanceof DoesntContain => 'doesnt_contain',
- default => lcfirst(class_basename($rules)),
+ $rules instanceof ExcludeIf => 'exclude',
+ $rules instanceof ExcludeUnless => 'exclude',
+ $rules instanceof In => 'in',
+ $rules instanceof NotIn => 'not_in',
+ $rules instanceof Unique => 'unique',
+ $rules instanceof Exists => 'exists',
+ $rules instanceof Contains => 'contains',
+ $rules instanceof DoesntContain => 'doesnt_contain',
+ default => lcfirst(class_basename($rules)),
};
} else {
$this->constraints = array_merge($this->constraints, Arr::wrap($rules));
@@ -432,7 +432,8 @@ protected function addRule(array|string|object $rules, ?string $message = null):
* appear before type and size constraints ("required" must come
* before "must be a string").
*
- * @param list $constraints
+ * @param list $constraints
+ *
* @return list
*/
protected function reorderConstraints(array $constraints): array
@@ -457,8 +458,8 @@ private static function serializeValues(array $values): string
return implode(',', array_map(
static fn (string|int|bool|BackedEnum $v): string|int => match (true) {
$v instanceof BackedEnum => $v->value,
- is_bool($v) => $v ? '1' : '0',
- default => $v,
+ is_bool($v) => $v ? '1' : '0',
+ default => $v,
},
$values,
));
@@ -474,7 +475,8 @@ private function isPresenceConstraint(string $constraint): bool
}
/**
- * @param Closure(static): static|string|list $rules
+ * @param Closure(static): static|string|list $rules
+ *
* @return string|list
*/
private function compileConditionalBranch(Closure|string|array $rules): string|array
diff --git a/src/Builder/Concerns/SelfValidates.php b/src/Builder/Concerns/SelfValidates.php
index f8666f9..4183987 100644
--- a/src/Builder/Concerns/SelfValidates.php
+++ b/src/Builder/Concerns/SelfValidates.php
@@ -5,18 +5,18 @@
namespace Simtabi\Laranail\Validation\Builder\Concerns;
use Closure;
+use Stringable;
+use ReflectionProperty;
use Illuminate\Support\Arr;
-use Illuminate\Support\Facades\Validator;
-use Illuminate\Validation\Rules\ExcludeIf;
-use Illuminate\Validation\Rules\ExcludeUnless;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\Rules\NotIn;
-use Illuminate\Validation\Rules\ProhibitedIf;
-use Illuminate\Validation\Rules\ProhibitedUnless;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rules\ExcludeIf;
use Illuminate\Validation\Rules\RequiredIf;
+use Illuminate\Validation\Rules\ProhibitedIf;
+use Illuminate\Validation\Rules\ExcludeUnless;
use Illuminate\Validation\Rules\RequiredUnless;
-use ReflectionProperty;
-use Stringable;
+use Illuminate\Validation\Rules\ProhibitedUnless;
trait SelfValidates
{
@@ -189,7 +189,7 @@ private function buildMessages(string $attribute): array
$messages = $this->validator->customMessages ?? [];
foreach ($this->getCustomMessages() as $ruleName => $message) {
- $messages[$ruleName === '' ? $attribute : $attribute.'.'.$ruleName] = $message;
+ $messages[$ruleName === '' ? $attribute : $attribute . '.' . $ruleName] = $message;
}
return $messages;
@@ -427,7 +427,7 @@ private function buildCompiledRules(): string|array
* `regex:/^(a|b)$/` pattern) cannot be safely pipe-joined — Laravel's parser
* would split it. Rules with one fall back to array form instead.
*
- * @param list $rules
+ * @param list $rules
*/
private function anyContainsPipe(array $rules): bool
{
diff --git a/src/Builder/Nodes/AcceptedRule.php b/src/Builder/Nodes/AcceptedRule.php
index 7ade6f1..3b98c5a 100644
--- a/src/Builder/Nodes/AcceptedRule.php
+++ b/src/Builder/Nodes/AcceptedRule.php
@@ -4,13 +4,13 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class AcceptedRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -36,7 +36,7 @@ public function acceptedIf(string $field, string|int|bool ...$values): static
static fn (string $rule): bool => $rule !== 'accepted',
));
- return $this->addRule('accepted_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('accepted_if:' . $field . ',' . self::serializeValues($values));
}
/** @return list */
diff --git a/src/Builder/Nodes/ArrayRule.php b/src/Builder/Nodes/ArrayRule.php
index 280d8be..27a459f 100644
--- a/src/Builder/Nodes/ArrayRule.php
+++ b/src/Builder/Nodes/ArrayRule.php
@@ -4,22 +4,22 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use UnitEnum;
use BackedEnum;
+use LogicException;
+use InvalidArgumentException;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Validation\Rules\Contains;
use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Support\Traits\Conditionable;
+use Illuminate\Validation\Rules\DoesntContain;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Illuminate\Validation\Rules\Contains;
-use Illuminate\Validation\Rules\DoesntContain;
-use InvalidArgumentException;
-use LogicException;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
use Simtabi\Laranail\Validation\Exceptions\CannotExtendListShapedEach;
-use UnitEnum;
class ArrayRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -143,7 +143,7 @@ public function addEachRule(string $key, ValidationRule $rule): static
if (array_key_exists($key, $existing)) {
throw new LogicException(sprintf(
"addEachRule('%s'): key '%s' already exists in each(). "
- .'Use mergeEachRules() if replacement is intentional.',
+ . 'Use mergeEachRules() if replacement is intentional.',
$key,
$key,
));
@@ -159,7 +159,7 @@ public function addEachRule(string $key, ValidationRule $rule): static
* Merge multiple keyed sub-rules into the current each() shape,
* later-wins on collision.
*
- * @param array $rules
+ * @param array $rules
*
* @throws CannotExtendListShapedEach when `eachRules` is list-shaped.
*/
@@ -187,7 +187,7 @@ public function mergeEachRules(array $rules): static
* Unlike each() which produces wildcard paths (items.*.name),
* children() produces fixed paths (search.value, search.regex).
*
- * @param array $rules
+ * @param array $rules
*/
public function children(array $rules): static
{
@@ -214,22 +214,22 @@ public function withoutEachRules(): static
public function min(int $value, ?string $message = null): static
{
- return $this->addRule('min:'.$value, $message);
+ return $this->addRule('min:' . $value, $message);
}
public function max(int $value, ?string $message = null): static
{
- return $this->addRule('max:'.$value, $message);
+ return $this->addRule('max:' . $value, $message);
}
public function between(int $min, int $max, ?string $message = null): static
{
- return $this->addRule('between:'.$min.','.$max, $message);
+ return $this->addRule('between:' . $min . ',' . $max, $message);
}
public function exactly(int $value, ?string $message = null): static
{
- return $this->addRule('size:'.$value, $message);
+ return $this->addRule('size:' . $value, $message);
}
public function list(?string $message = null): static
@@ -239,16 +239,16 @@ public function list(?string $message = null): static
public function requiredArrayKeys(string ...$keys): static
{
- return $this->addRule('required_array_keys:'.implode(',', $keys));
+ return $this->addRule('required_array_keys:' . implode(',', $keys));
}
public function distinct(?string $mode = null, ?string $message = null): static
{
- return $this->addRule($mode ? 'distinct:'.$mode : 'distinct', $message);
+ return $this->addRule($mode ? 'distinct:' . $mode : 'distinct', $message);
}
/**
- * @param Arrayable|UnitEnum|array|string|int ...$values
+ * @param Arrayable|UnitEnum|array|string|int ...$values
*
* Note: `Arrayable` is template-invariant, so concrete types like
* `Collection` don't satisfy `Arrayable`.
@@ -285,7 +285,7 @@ protected function buildArrayRule(): string
$this->keys,
);
- return 'array:'.implode(',', $keys);
+ return 'array:' . implode(',', $keys);
}
/** @return list */
@@ -306,7 +306,8 @@ protected function buildValidationRules(): array
* Laravel's Rule::contains silently ignores extras, and leaving nested
* arrays/Arrayables in the value list would crash Contains::__toString.
*
- * @param array $values
+ * @param array $values
+ *
* @return array
*/
private function flattenContainsValues(array $values): array
@@ -327,7 +328,7 @@ private function flattenContainsValues(array $values): array
if (is_array($value) || $value instanceof Arrayable) {
throw new InvalidArgumentException(
'contains()/doesntContain() does not accept multiple array or Arrayable arguments. '
- .'Pass either a single iterable (->contains($values)) or variadic scalars (->contains($a, $b, $c)).',
+ . 'Pass either a single iterable (->contains($values)) or variadic scalars (->contains($a, $b, $c)).',
);
}
}
@@ -339,7 +340,7 @@ private function flattenContainsValues(array $values): array
private function buildEachNestedRules(string $attribute): array
{
if ($this->eachListRule instanceof ValidationRule) {
- $key = $attribute.'.*';
+ $key = $attribute . '.*';
$rules = [$key => $this->eachListRule];
return $this->eachListRule instanceof self
@@ -356,7 +357,7 @@ private function buildEachNestedRules(string $attribute): array
$nested = [];
foreach ($this->eachRules as $field => $rule) {
- $key = $attribute.'.*.'.$field;
+ $key = $attribute . '.*.' . $field;
$rules[$key] = $rule;
if ($rule instanceof self) {
@@ -375,7 +376,7 @@ private function buildChildNestedRules(string $attribute): array
$nested = [];
foreach ($this->childRules ?? [] as $field => $rule) {
- $key = $attribute.'.'.$field;
+ $key = $attribute . '.' . $field;
$rules[$key] = $rule;
if ($rule instanceof self) {
diff --git a/src/Builder/Nodes/BooleanRule.php b/src/Builder/Nodes/BooleanRule.php
index 021c9c5..cae9fd0 100644
--- a/src/Builder/Nodes/BooleanRule.php
+++ b/src/Builder/Nodes/BooleanRule.php
@@ -4,13 +4,13 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class BooleanRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -34,7 +34,7 @@ public function accepted(?string $message = null): static
public function acceptedIf(string $field, string|int|bool ...$values): static
{
- return $this->addRule('accepted_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('accepted_if:' . $field . ',' . self::serializeValues($values));
}
public function declined(?string $message = null): static
@@ -44,7 +44,7 @@ public function declined(?string $message = null): static
public function declinedIf(string $field, string|int|bool ...$values): static
{
- return $this->addRule('declined_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('declined_if:' . $field . ',' . self::serializeValues($values));
}
/** @return list */
diff --git a/src/Builder/Nodes/DateRule.php b/src/Builder/Nodes/DateRule.php
index 7daa01e..6356462 100644
--- a/src/Builder/Nodes/DateRule.php
+++ b/src/Builder/Nodes/DateRule.php
@@ -5,14 +5,14 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
use DateTimeInterface;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
class DateRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -109,22 +109,22 @@ public function nowOrFuture(?string $message = null): static
public function before(DateTimeInterface|string $date, ?string $message = null): static
{
- return $this->addRule('before:'.$this->formatDate($date), $message);
+ return $this->addRule('before:' . $this->formatDate($date), $message);
}
public function after(DateTimeInterface|string $date, ?string $message = null): static
{
- return $this->addRule('after:'.$this->formatDate($date), $message);
+ return $this->addRule('after:' . $this->formatDate($date), $message);
}
public function beforeOrEqual(DateTimeInterface|string $date, ?string $message = null): static
{
- return $this->addRule('before_or_equal:'.$this->formatDate($date), $message);
+ return $this->addRule('before_or_equal:' . $this->formatDate($date), $message);
}
public function afterOrEqual(DateTimeInterface|string $date, ?string $message = null): static
{
- return $this->addRule('after_or_equal:'.$this->formatDate($date), $message);
+ return $this->addRule('after_or_equal:' . $this->formatDate($date), $message);
}
/**
@@ -148,17 +148,17 @@ public function betweenOrEqual(DateTimeInterface|string $from, DateTimeInterface
public function dateEquals(DateTimeInterface|string $date, ?string $message = null): static
{
- return $this->addRule('date_equals:'.$this->formatDate($date), $message);
+ return $this->addRule('date_equals:' . $this->formatDate($date), $message);
}
public function same(string $field, ?string $message = null): static
{
- return $this->addRule('same:'.$field, $message);
+ return $this->addRule('same:' . $field, $message);
}
public function different(string $field, ?string $message = null): static
{
- return $this->addRule('different:'.$field, $message);
+ return $this->addRule('different:' . $field, $message);
}
protected function formatDate(DateTimeInterface|string $date): string
@@ -172,7 +172,7 @@ protected function formatDate(DateTimeInterface|string $date): string
protected function buildValidationRules(): array
{
return [
- ...$this->reorderConstraints([$this->format === null ? 'date' : 'date_format:'.$this->format, ...$this->constraints]),
+ ...$this->reorderConstraints([$this->format === null ? 'date' : 'date_format:' . $this->format, ...$this->constraints]),
...$this->rules,
];
}
diff --git a/src/Builder/Nodes/DeclinedRule.php b/src/Builder/Nodes/DeclinedRule.php
index d2eb086..9bcd014 100644
--- a/src/Builder/Nodes/DeclinedRule.php
+++ b/src/Builder/Nodes/DeclinedRule.php
@@ -4,13 +4,13 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class DeclinedRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -35,7 +35,7 @@ public function declinedIf(string $field, string|int|bool ...$values): static
static fn (string $rule): bool => $rule !== 'declined',
));
- return $this->addRule('declined_if:'.$field.','.self::serializeValues($values));
+ return $this->addRule('declined_if:' . $field . ',' . self::serializeValues($values));
}
/** @return list */
diff --git a/src/Builder/Nodes/EmailRule.php b/src/Builder/Nodes/EmailRule.php
index 557ce92..82888ab 100644
--- a/src/Builder/Nodes/EmailRule.php
+++ b/src/Builder/Nodes/EmailRule.php
@@ -4,21 +4,21 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Validation\Rules\Email;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Illuminate\Validation\Rules\Email;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Rules\Email\NotRoleEmail;
use Simtabi\Laranail\Validation\Rules\Email\EmailDomainIs;
-use Simtabi\Laranail\Validation\Rules\Email\EmailDomainIsNot;
use Simtabi\Laranail\Validation\Rules\Email\NoSubaddressing;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Rules\Email\EmailDomainIsNot;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Rules\Email\NotDisposableEmail;
-use Simtabi\Laranail\Validation\Rules\Email\NotRoleEmail;
use Simtabi\Laranail\Validation\Rules\Network\DeliverableEmail;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class EmailRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -99,7 +99,7 @@ public function notRole(?string $message = null): static
* `*.example.com` matches any subdomain and NOT the bare domain; list
* both when both are wanted. See EmailDomainIs for why that is strict.
*
- * @param list|string $domains
+ * @param list|string $domains
*/
public function domainIs(array|string $domains, ?string $message = null): static
{
@@ -109,7 +109,7 @@ public function domainIs(array|string $domains, ?string $message = null): static
/**
* Bar the address from the given domains, same pattern syntax.
*
- * @param list|string $domains
+ * @param list|string $domains
*/
public function domainIsNot(array|string $domains, ?string $message = null): static
{
@@ -171,7 +171,7 @@ public function maxRfcLength(?string $message = null): static
public function max(int $value, ?string $message = null): static
{
- return $this->addRule('max:'.$value, $message);
+ return $this->addRule('max:' . $value, $message);
}
public function confirmed(?string $message = null): static
@@ -181,12 +181,12 @@ public function confirmed(?string $message = null): static
public function same(string $field, ?string $message = null): static
{
- return $this->addRule('same:'.$field, $message);
+ return $this->addRule('same:' . $field, $message);
}
public function different(string $field, ?string $message = null): static
{
- return $this->addRule('different:'.$field, $message);
+ return $this->addRule('different:' . $field, $message);
}
/**
@@ -203,7 +203,7 @@ protected function buildValidationRules(): array
{
// Explicit modes always take precedence.
if ($this->modes !== []) {
- return [...$this->reorderConstraints($this->constraints), 'email:'.implode(',', $this->modes), ...$this->rules];
+ return [...$this->reorderConstraints($this->constraints), 'email:' . implode(',', $this->modes), ...$this->rules];
}
// Use Email::default() when defaults are enabled and the app has configured them.
diff --git a/src/Builder/Nodes/FieldRule.php b/src/Builder/Nodes/FieldRule.php
index 4990b91..921e605 100644
--- a/src/Builder/Nodes/FieldRule.php
+++ b/src/Builder/Nodes/FieldRule.php
@@ -5,17 +5,17 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
use Closure;
+use LogicException;
+use InvalidArgumentException;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use InvalidArgumentException;
-use LogicException;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
use Simtabi\Laranail\Validation\Exceptions\UnknownFluentRuleMethod;
/**
@@ -50,7 +50,7 @@ class FieldRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
* pointing at the correct typed builder instead of a bare
* `BadMethodCallException`. See `UnknownFluentRuleMethod`.
*
- * @param array $parameters
+ * @param array $parameters
*/
public function __call(string $method, array $parameters): mixed
{
@@ -96,7 +96,7 @@ public static function __callStatic(string $method, array $parameters): mixed
*
* Produces fixed paths (answer.email_address) without wildcards.
*
- * @param array $rules
+ * @param array $rules
*/
public function children(array $rules): static
{
@@ -137,7 +137,7 @@ public function addChildRule(string $key, ValidationRule $rule): static
if (array_key_exists($key, $existing)) {
throw new LogicException(sprintf(
"addChildRule('%s'): key '%s' already exists in children(). "
- .'Use mergeChildRules() if replacement is intentional.',
+ . 'Use mergeChildRules() if replacement is intentional.',
$key,
$key,
));
@@ -152,7 +152,7 @@ public function addChildRule(string $key, ValidationRule $rule): static
/**
* Merge multiple keyed child rules, later-wins on collision.
*
- * @param array $rules
+ * @param array $rules
*/
public function mergeChildRules(array $rules): static
{
@@ -170,12 +170,12 @@ public function mergeChildRules(array $rules): static
public function same(string $field, ?string $message = null): static
{
- return $this->addRule('same:'.$field, $message);
+ return $this->addRule('same:' . $field, $message);
}
public function different(string $field, ?string $message = null): static
{
- return $this->addRule('different:'.$field, $message);
+ return $this->addRule('different:' . $field, $message);
}
public function confirmed(?string $message = null): static
@@ -191,7 +191,7 @@ public function buildNestedRules(string $attribute): array
$nested = [];
foreach ($this->childRules ?? [] as $field => $rule) {
- $key = $attribute.'.'.$field;
+ $key = $attribute . '.' . $field;
$rules[$key] = $rule;
if ($rule instanceof ArrayRule
diff --git a/src/Builder/Nodes/FileRule.php b/src/Builder/Nodes/FileRule.php
index 9bd75db..c29b764 100644
--- a/src/Builder/Nodes/FileRule.php
+++ b/src/Builder/Nodes/FileRule.php
@@ -4,13 +4,13 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class FileRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -29,37 +29,37 @@ public function __construct()
public function min(int|string $size, ?string $message = null): static
{
- return $this->addRule('min:'.$this->toKilobytes($size), $message);
+ return $this->addRule('min:' . $this->toKilobytes($size), $message);
}
public function max(int|string $size, ?string $message = null): static
{
- return $this->addRule('max:'.$this->toKilobytes($size), $message);
+ return $this->addRule('max:' . $this->toKilobytes($size), $message);
}
public function between(int|string $min, int|string $max, ?string $message = null): static
{
- return $this->addRule('between:'.$this->toKilobytes($min).','.$this->toKilobytes($max), $message);
+ return $this->addRule('between:' . $this->toKilobytes($min) . ',' . $this->toKilobytes($max), $message);
}
public function exactly(int|string $size, ?string $message = null): static
{
- return $this->addRule('size:'.$this->toKilobytes($size), $message);
+ return $this->addRule('size:' . $this->toKilobytes($size), $message);
}
public function extensions(string ...$extensions): static
{
- return $this->addRule('extensions:'.implode(',', $extensions));
+ return $this->addRule('extensions:' . implode(',', $extensions));
}
public function mimes(string ...$mimes): static
{
- return $this->addRule('mimes:'.implode(',', $mimes));
+ return $this->addRule('mimes:' . implode(',', $mimes));
}
public function mimetypes(string ...$mimetypes): static
{
- return $this->addRule('mimetypes:'.implode(',', $mimetypes));
+ return $this->addRule('mimetypes:' . implode(',', $mimetypes));
}
/**
@@ -82,10 +82,10 @@ protected function toKilobytes(int|string $size): int
$unit = strtolower($matches[2]);
return (int) round(match ($unit) {
- 'kb' => $value,
- 'mb' => $value * 1_000,
- 'gb' => $value * 1_000_000,
- 'tb' => $value * 1_000_000_000,
+ 'kb' => $value,
+ 'mb' => $value * 1_000,
+ 'gb' => $value * 1_000_000,
+ 'tb' => $value * 1_000_000_000,
default => $value,
});
}
diff --git a/src/Builder/Nodes/IpAddressRule.php b/src/Builder/Nodes/IpAddressRule.php
index 357a694..81b1eb0 100644
--- a/src/Builder/Nodes/IpAddressRule.php
+++ b/src/Builder/Nodes/IpAddressRule.php
@@ -4,17 +4,17 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
+use Simtabi\Laranail\Validation\Rules\Net\PublicIp;
+use Simtabi\Laranail\Validation\Rules\Net\PrivateIp;
+use Simtabi\Laranail\Validation\Rules\Net\InCidrRange;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
-use Simtabi\Laranail\Validation\Rules\Net\InCidrRange;
-use Simtabi\Laranail\Validation\Rules\Net\PrivateIp;
-use Simtabi\Laranail\Validation\Rules\Net\PublicIp;
/**
* An IP address field.
@@ -102,7 +102,7 @@ public function private(?string $message = null): static
* FluentRule::ip()->inRange(['203.0.113.0/24', '2001:db8::/32'])
* ```
*
- * @param list|string $networks
+ * @param list|string $networks
*/
public function inRange(array|string $networks, ?string $message = null): static
{
diff --git a/src/Builder/Nodes/MacAddressRule.php b/src/Builder/Nodes/MacAddressRule.php
index 3aac8d0..59b9286 100644
--- a/src/Builder/Nodes/MacAddressRule.php
+++ b/src/Builder/Nodes/MacAddressRule.php
@@ -4,15 +4,15 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
+use Simtabi\Laranail\Validation\Rules\Net\MacAddress;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
-use Simtabi\Laranail\Validation\Rules\Net\MacAddress;
/**
* A MAC address field.
@@ -85,7 +85,7 @@ public function bare(): static
/**
* Accept only these notations.
*
- * @param list|string $formats {@see MacAddress::COLON} and friends.
+ * @param list|string $formats {@see MacAddress::COLON} and friends.
*/
public function format(array|string $formats): static
{
@@ -141,7 +141,7 @@ public function universal(): static
* Written in any notation and any length — a 24-bit OUI, or a longer
* MA-M/MA-S assignment.
*
- * @param list|string $ouis
+ * @param list|string $ouis
*/
public function oui(array|string $ouis): static
{
diff --git a/src/Builder/Nodes/NumericRule.php b/src/Builder/Nodes/NumericRule.php
index 29806b5..1332407 100644
--- a/src/Builder/Nodes/NumericRule.php
+++ b/src/Builder/Nodes/NumericRule.php
@@ -4,14 +4,14 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
class NumericRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -31,14 +31,14 @@ public function __construct()
public function between(int|float $min, int|float $max, ?string $message = null): static
{
- return $this->addRule('between:'.$min.','.$max, $message);
+ return $this->addRule('between:' . $min . ',' . $max, $message);
}
public function decimal(int $min, ?int $max = null, ?string $message = null): static
{
- $r = 'decimal:'.$min;
+ $r = 'decimal:' . $min;
if ($max !== null) {
- $r .= ','.$max;
+ $r .= ',' . $max;
}
return $this->addRule($r, $message);
@@ -46,7 +46,7 @@ public function decimal(int $min, ?int $max = null, ?string $message = null): st
public function different(string $field, ?string $message = null): static
{
- return $this->addRule('different:'.$field, $message);
+ return $this->addRule('different:' . $field, $message);
}
/**
@@ -56,7 +56,7 @@ public function different(string $field, ?string $message = null): static
*/
public function digits(int $length, ?string $message = null): static
{
- return $this->integer()->addRule('digits:'.$length, $message);
+ return $this->integer()->addRule('digits:' . $length, $message);
}
/**
@@ -65,17 +65,17 @@ public function digits(int $length, ?string $message = null): static
*/
public function digitsBetween(int $min, int $max, ?string $message = null): static
{
- return $this->integer()->addRule('digits_between:'.$min.','.$max, $message);
+ return $this->integer()->addRule('digits_between:' . $min . ',' . $max, $message);
}
public function greaterThan(string $field, ?string $message = null): static
{
- return $this->addRule('gt:'.$field, $message);
+ return $this->addRule('gt:' . $field, $message);
}
public function greaterThanOrEqualTo(string $field, ?string $message = null): static
{
- return $this->addRule('gte:'.$field, $message);
+ return $this->addRule('gte:' . $field, $message);
}
public function integer(bool $strict = false, ?string $message = null): static
@@ -85,37 +85,37 @@ public function integer(bool $strict = false, ?string $message = null): static
public function lessThan(string $field, ?string $message = null): static
{
- return $this->addRule('lt:'.$field, $message);
+ return $this->addRule('lt:' . $field, $message);
}
public function lessThanOrEqualTo(string $field, ?string $message = null): static
{
- return $this->addRule('lte:'.$field, $message);
+ return $this->addRule('lte:' . $field, $message);
}
public function max(int|float $value, ?string $message = null): static
{
- return $this->addRule('max:'.$value, $message);
+ return $this->addRule('max:' . $value, $message);
}
public function maxDigits(int $value, ?string $message = null): static
{
- return $this->addRule('max_digits:'.$value, $message);
+ return $this->addRule('max_digits:' . $value, $message);
}
public function min(int|float $value, ?string $message = null): static
{
- return $this->addRule('min:'.$value, $message);
+ return $this->addRule('min:' . $value, $message);
}
public function minDigits(int $value, ?string $message = null): static
{
- return $this->addRule('min_digits:'.$value, $message);
+ return $this->addRule('min_digits:' . $value, $message);
}
public function multipleOf(int|float $value, ?string $message = null): static
{
- return $this->addRule('multiple_of:'.$value, $message);
+ return $this->addRule('multiple_of:' . $value, $message);
}
public function positive(?string $message = null): static
@@ -140,7 +140,7 @@ public function nonPositive(?string $message = null): static
public function same(string $field, ?string $message = null): static
{
- return $this->addRule('same:'.$field, $message);
+ return $this->addRule('same:' . $field, $message);
}
/**
@@ -149,7 +149,7 @@ public function same(string $field, ?string $message = null): static
*/
public function exactly(int $value, ?string $message = null): static
{
- return $this->integer()->addRule('size:'.$value, $message);
+ return $this->integer()->addRule('size:' . $value, $message);
}
public function confirmed(?string $message = null): static
@@ -159,17 +159,17 @@ public function confirmed(?string $message = null): static
public function inArray(string $field, ?string $message = null): static
{
- return $this->addRule('in_array:'.$field, $message);
+ return $this->addRule('in_array:' . $field, $message);
}
public function inArrayKeys(string $field, ?string $message = null): static
{
- return $this->addRule('in_array_keys:'.$field, $message);
+ return $this->addRule('in_array_keys:' . $field, $message);
}
public function distinct(?string $mode = null, ?string $message = null): static
{
- return $this->addRule($mode ? 'distinct:'.$mode : 'distinct', $message);
+ return $this->addRule($mode ? 'distinct:' . $mode : 'distinct', $message);
}
/** @return list */
diff --git a/src/Builder/Nodes/PasswordRule.php b/src/Builder/Nodes/PasswordRule.php
index 55d9259..acc4f62 100644
--- a/src/Builder/Nodes/PasswordRule.php
+++ b/src/Builder/Nodes/PasswordRule.php
@@ -4,15 +4,15 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
-use Illuminate\Contracts\Validation\DataAwareRule;
-use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
+use ReflectionProperty;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Validation\Rules\Password;
-use ReflectionProperty;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Illuminate\Support\Traits\Conditionable;
+use Illuminate\Contracts\Validation\DataAwareRule;
+use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
class PasswordRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
diff --git a/src/Builder/Nodes/PhoneRule.php b/src/Builder/Nodes/PhoneRule.php
index b65e9f0..a43cad1 100644
--- a/src/Builder/Nodes/PhoneRule.php
+++ b/src/Builder/Nodes/PhoneRule.php
@@ -5,17 +5,17 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
use Closure;
-use Illuminate\Contracts\Validation\DataAwareRule;
-use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Simtabi\Laranail\Phone\Enums\PhoneNumberType;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Illuminate\Contracts\Validation\DataAwareRule;
use Simtabi\Laranail\Validation\Rules\Telecom\Phone;
+use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Simtabi\Laranail\Validation\Rules\Telecom\UniquePhone;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
/**
* A phone-number field.
@@ -72,7 +72,7 @@ public function __construct()
* does not — picking one arbitrarily would make the outcome depend on array order — so pair a
* multi-country list with {@see countryFrom()} or expect international input.
*
- * @param string|list $countries ISO 3166-1 alpha-2
+ * @param string|list $countries ISO 3166-1 alpha-2
*/
public function country(string|array $countries): static
{
@@ -110,7 +110,7 @@ public function countryFrom(string $field): static
*
* `FixedLineOrMobile` satisfies a request for either — see {@see Phone::typeMatches()}.
*
- * @param PhoneNumberType|list $types
+ * @param PhoneNumberType|list $types
*/
public function type(PhoneNumberType|array $types): static
{
@@ -202,7 +202,7 @@ public function rejectEmergency(): static
* FluentRule::phone()->unique('contacts', 'phone', fn ($rule) => $rule->ignore($id));
* ```
*
- * @param (Closure(UniquePhone): void)|null $callback Receives the rule, for `ignore()`
+ * @param (Closure(UniquePhone): void)|null $callback Receives the rule, for `ignore()`
*/
public function unique(string $table, ?string $column = null, ?Closure $callback = null, ?string $message = null): static
{
diff --git a/src/Builder/Nodes/StringRule.php b/src/Builder/Nodes/StringRule.php
index 3ec54e7..669cd75 100644
--- a/src/Builder/Nodes/StringRule.php
+++ b/src/Builder/Nodes/StringRule.php
@@ -5,15 +5,15 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
use Closure;
+use Simtabi\Laranail\Validation\Regex;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
-use Simtabi\Laranail\Validation\Regex;
class StringRule implements DataAwareRule, FluentRuleContract, ValidatorAwareRule
{
@@ -53,32 +53,32 @@ public function ascii(?string $message = null): static
public function encoding(string $encoding, ?string $message = null): static
{
- return $this->addRule('encoding:'.$encoding, $message);
+ return $this->addRule('encoding:' . $encoding, $message);
}
public function between(int $min, int $max, ?string $message = null): static
{
- return $this->addRule('between:'.$min.','.$max, $message);
+ return $this->addRule('between:' . $min . ',' . $max, $message);
}
public function doesntEndWith(string ...$values): static
{
- return $this->addRule('doesnt_end_with:'.implode(',', $values));
+ return $this->addRule('doesnt_end_with:' . implode(',', $values));
}
public function doesntStartWith(string ...$values): static
{
- return $this->addRule('doesnt_start_with:'.implode(',', $values));
+ return $this->addRule('doesnt_start_with:' . implode(',', $values));
}
public function endsWith(string ...$values): static
{
- return $this->addRule('ends_with:'.implode(',', $values));
+ return $this->addRule('ends_with:' . implode(',', $values));
}
public function exactly(int $value, ?string $message = null): static
{
- return $this->addRule('size:'.$value, $message);
+ return $this->addRule('size:' . $value, $message);
}
public function lowercase(?string $message = null): static
@@ -88,17 +88,17 @@ public function lowercase(?string $message = null): static
public function max(int $value, ?string $message = null): static
{
- return $this->addRule('max:'.$value, $message);
+ return $this->addRule('max:' . $value, $message);
}
public function min(int $value, ?string $message = null): static
{
- return $this->addRule('min:'.$value, $message);
+ return $this->addRule('min:' . $value, $message);
}
public function startsWith(string ...$values): static
{
- return $this->addRule('starts_with:'.implode(',', $values));
+ return $this->addRule('starts_with:' . implode(',', $values));
}
public function uppercase(?string $message = null): static
@@ -157,11 +157,11 @@ public function macAddress(?string $message = null): static
* accepts a {@see Regex} or a builder closure; see {@see matches()} for
* the raw-string spelling that adds delimiters and `D` for you.
*
- * @param string|Regex|Closure(Regex): Regex $pattern
+ * @param string|Regex|Closure(Regex): Regex $pattern
*/
public function regex(string|Regex|Closure $pattern, ?string $message = null): static
{
- return $this->addRule('regex:'.(is_string($pattern) ? $pattern : $this->compileRegex($pattern)), $message);
+ return $this->addRule('regex:' . (is_string($pattern) ? $pattern : $this->compileRegex($pattern)), $message);
}
/**
@@ -176,7 +176,7 @@ public function regex(string|Regex|Closure $pattern, ?string $message = null): s
* The builder is never required — a team that already has a pattern
* just uses it.
*
- * @param string|Regex|Closure(Regex): Regex $pattern
+ * @param string|Regex|Closure(Regex): Regex $pattern
*/
public function matches(string|Regex|Closure $pattern, ?string $message = null): static
{
@@ -184,12 +184,12 @@ public function matches(string|Regex|Closure $pattern, ?string $message = null):
? Regex::of($pattern)->compile()
: $this->compileRegex($pattern);
- return $this->addRule('regex:'.$compiled, $message);
+ return $this->addRule('regex:' . $compiled, $message);
}
public function notRegex(string $pattern, ?string $message = null): static
{
- return $this->addRule('not_regex:'.$pattern, $message);
+ return $this->addRule('not_regex:' . $pattern, $message);
}
public function timezone(?string $message = null): static
@@ -209,12 +209,12 @@ public function date(?string $message = null): static
public function email(string ...$modes): static
{
- return $this->addRule($modes === [] ? 'email' : 'email:'.implode(',', $modes));
+ return $this->addRule($modes === [] ? 'email' : 'email:' . implode(',', $modes));
}
public function dateFormat(string $format, ?string $message = null): static
{
- return $this->addRule('date_format:'.$format, $message);
+ return $this->addRule('date_format:' . $format, $message);
}
public function confirmed(?string $message = null): static
@@ -224,32 +224,32 @@ public function confirmed(?string $message = null): static
public function currentPassword(?string $guard = null, ?string $message = null): static
{
- return $this->addRule($guard ? 'current_password:'.$guard : 'current_password', $message);
+ return $this->addRule($guard ? 'current_password:' . $guard : 'current_password', $message);
}
public function same(string $field, ?string $message = null): static
{
- return $this->addRule('same:'.$field, $message);
+ return $this->addRule('same:' . $field, $message);
}
public function different(string $field, ?string $message = null): static
{
- return $this->addRule('different:'.$field, $message);
+ return $this->addRule('different:' . $field, $message);
}
public function inArray(string $field, ?string $message = null): static
{
- return $this->addRule('in_array:'.$field, $message);
+ return $this->addRule('in_array:' . $field, $message);
}
public function inArrayKeys(string $field, ?string $message = null): static
{
- return $this->addRule('in_array_keys:'.$field, $message);
+ return $this->addRule('in_array_keys:' . $field, $message);
}
public function distinct(?string $mode = null, ?string $message = null): static
{
- return $this->addRule($mode ? 'distinct:'.$mode : 'distinct', $message);
+ return $this->addRule($mode ? 'distinct:' . $mode : 'distinct', $message);
}
/** @return list */
diff --git a/src/Builder/Nodes/UrlRule.php b/src/Builder/Nodes/UrlRule.php
index b11fc4e..7bb6ac4 100644
--- a/src/Builder/Nodes/UrlRule.php
+++ b/src/Builder/Nodes/UrlRule.php
@@ -4,16 +4,16 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
+use Simtabi\Laranail\Validation\Rules\Net\Url;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
-use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
use Simtabi\Laranail\Validation\Rules\Net\Support\HostPattern;
-use Simtabi\Laranail\Validation\Rules\Net\Url;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
+use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
/**
* A URL field.
@@ -77,7 +77,7 @@ public function __construct()
/**
* Accept only these schemes. Written without `://`.
*
- * @param list|string $schemes
+ * @param list|string $schemes
*/
public function scheme(array|string $schemes): static
{
@@ -97,7 +97,7 @@ public function secure(): static
* bare domain. List both when both are wanted — see the note on
* {@see HostPattern}.
*
- * @param list|string $hosts
+ * @param list|string $hosts
*/
public function hostIs(array|string $hosts): static
{
@@ -109,7 +109,7 @@ public function hostIs(array|string $hosts): static
/**
* Bar these hosts, same syntax. Applied after the allow-list.
*
- * @param list|string $hosts
+ * @param list|string $hosts
*/
public function hostIsNot(array|string $hosts): static
{
@@ -122,7 +122,7 @@ public function hostIsNot(array|string $hosts): static
* Accept only these ports. A URL with no port is accepted only if the
* default for its scheme is in the list — state 80 or 443 explicitly.
*
- * @param list|int $ports
+ * @param list|int $ports
*/
public function port(array|int $ports): static
{
diff --git a/src/Builder/Nodes/UsernameRule.php b/src/Builder/Nodes/UsernameRule.php
index d1de9aa..4bcf78d 100644
--- a/src/Builder/Nodes/UsernameRule.php
+++ b/src/Builder/Nodes/UsernameRule.php
@@ -4,15 +4,15 @@
namespace Simtabi\Laranail\Validation\Builder\Nodes;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Support\Traits\Conditionable;
use Illuminate\Contracts\Validation\DataAwareRule;
+use Simtabi\Laranail\Validation\Rules\Text\Username;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
-use Illuminate\Support\Traits\Conditionable;
-use Illuminate\Support\Traits\Macroable;
+use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
+use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
use Simtabi\Laranail\Validation\Builder\Concerns\HasEmbeddedRules;
use Simtabi\Laranail\Validation\Builder\Concerns\HasFieldModifiers;
-use Simtabi\Laranail\Validation\Builder\Concerns\SelfValidates;
-use Simtabi\Laranail\Validation\Contracts\FluentRuleContract;
-use Simtabi\Laranail\Validation\Rules\Text\Username;
/**
* A username field.
@@ -120,7 +120,7 @@ public function lowercase(): static
* ->reserved([...Username::DEFAULT_RESERVED, 'acme', 'enterprise'])
* ```
*
- * @param list $names
+ * @param list $names
*/
public function reserved(array $names): static
{
@@ -132,7 +132,7 @@ public function reserved(array $names): static
/**
* Add to the shipped list rather than replacing it.
*
- * @param list|string $names
+ * @param list|string $names
*/
public function alsoReserved(array|string $names): static
{
diff --git a/src/Check.php b/src/Check.php
index 565d0c7..564d30f 100644
--- a/src/Check.php
+++ b/src/Check.php
@@ -5,32 +5,32 @@
namespace Simtabi\Laranail\Validation;
use Closure;
-use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Validator;
+use Simtabi\Laranail\Validation\Rules\Net\Cidr;
+use Simtabi\Laranail\Validation\Rules\Codes\Ean;
+use Simtabi\Laranail\Validation\Rules\Text\Slug;
+use Simtabi\Laranail\Validation\Rules\Codes\Isbn;
+use Simtabi\Laranail\Validation\Rules\Codes\Issn;
use Illuminate\Validation\InvokableValidationRule;
use Simtabi\Laranail\Validation\Rules\Banking\Bic;
+use Illuminate\Contracts\Validation\ValidationRule;
use Simtabi\Laranail\Validation\Rules\Banking\Iban;
use Simtabi\Laranail\Validation\Rules\Banking\Isin;
use Simtabi\Laranail\Validation\Rules\Banking\Luhn;
-use Simtabi\Laranail\Validation\Rules\Codes\Ean;
-use Simtabi\Laranail\Validation\Rules\Codes\Isbn;
-use Simtabi\Laranail\Validation\Rules\Codes\Issn;
-use Simtabi\Laranail\Validation\Rules\Colour\CssColor;
use Simtabi\Laranail\Validation\Rules\Geo\Latitude;
use Simtabi\Laranail\Validation\Rules\Geo\Longitude;
-use Simtabi\Laranail\Validation\Rules\Identifiers\Imei;
-use Simtabi\Laranail\Validation\Rules\Identifiers\Jwt;
-use Simtabi\Laranail\Validation\Rules\Identifiers\SemVer;
-use Simtabi\Laranail\Validation\Rules\Identifiers\Vin;
-use Simtabi\Laranail\Validation\Rules\Net\Cidr;
+use Simtabi\Laranail\Validation\Rules\Net\Subdomain;
+use Simtabi\Laranail\Validation\Rules\Text\Username;
use Simtabi\Laranail\Validation\Rules\Net\DomainName;
use Simtabi\Laranail\Validation\Rules\Net\MacAddress;
-use Simtabi\Laranail\Validation\Rules\Net\Subdomain;
-use Simtabi\Laranail\Validation\Rules\Numbers\MonetaryAmount;
-use Simtabi\Laranail\Validation\Rules\Postal\PostalCode;
+use Simtabi\Laranail\Validation\Rules\Colour\CssColor;
+use Simtabi\Laranail\Validation\Rules\Identifiers\Jwt;
+use Simtabi\Laranail\Validation\Rules\Identifiers\Vin;
use Simtabi\Laranail\Validation\Rules\Text\PersonName;
-use Simtabi\Laranail\Validation\Rules\Text\Slug;
-use Simtabi\Laranail\Validation\Rules\Text\Username;
+use Simtabi\Laranail\Validation\Rules\Identifiers\Imei;
+use Simtabi\Laranail\Validation\Rules\Postal\PostalCode;
+use Simtabi\Laranail\Validation\Rules\Identifiers\SemVer;
+use Simtabi\Laranail\Validation\Rules\Numbers\MonetaryAmount;
/**
* One-off boolean guards over the rule library — `Check::iban($v)` where
diff --git a/src/Commands/BenchmarkCommand.php b/src/Commands/BenchmarkCommand.php
index 4700dd1..c0142b1 100644
--- a/src/Commands/BenchmarkCommand.php
+++ b/src/Commands/BenchmarkCommand.php
@@ -4,9 +4,9 @@
namespace Simtabi\Laranail\Validation\Commands;
+use Symfony\Component\Process\Process;
use Simtabi\Laranail\Console\Tools\Commands\Command;
use Simtabi\Laranail\Console\Tools\Commands\Concerns\SupportsNamespacedNames;
-use Symfony\Component\Process\Process;
/**
* The official face of the repo's benchmark harness. `benchmark.php` is a
@@ -25,12 +25,12 @@ final class BenchmarkCommand extends Command
public function handle(): int
{
- $script = dirname(__DIR__, 2).'/benchmark.php';
+ $script = dirname(__DIR__, 2) . '/benchmark.php';
if (! is_file($script)) {
$this->error(
'benchmark.php ships only with a repository checkout, not the Composer archive. '
- .'Clone laranail/validation to benchmark: https://github.com/laranail/validation',
+ . 'Clone laranail/validation to benchmark: https://github.com/laranail/validation',
);
return self::FAILURE;
diff --git a/src/Commands/DoctorCommand.php b/src/Commands/DoctorCommand.php
index e403457..1f2d6f4 100644
--- a/src/Commands/DoctorCommand.php
+++ b/src/Commands/DoctorCommand.php
@@ -4,15 +4,15 @@
namespace Simtabi\Laranail\Validation\Commands;
-use Simtabi\Laranail\Console\Tools\Commands\Command;
-use Simtabi\Laranail\Console\Tools\Commands\Concerns\SupportsNamespacedNames;
+use Throwable;
use Simtabi\Laranail\Phone\PhoneFormatter;
+use Simtabi\Laranail\Console\Tools\Commands\Command;
use Simtabi\Laranail\Validation\BatchDatabaseChecker;
-use Simtabi\Laranail\Validation\Contracts\Email\DisposableDomainList;
+use Simtabi\Laranail\Validation\Support\RuleRegistrar;
use Simtabi\Laranail\Validation\Contracts\Email\DnsResolver;
use Simtabi\Laranail\Validation\Contracts\Email\RoleAccountList;
-use Simtabi\Laranail\Validation\Support\RuleRegistrar;
-use Throwable;
+use Simtabi\Laranail\Validation\Contracts\Email\DisposableDomainList;
+use Simtabi\Laranail\Console\Tools\Commands\Concerns\SupportsNamespacedNames;
/**
* The package's boot-health surface (failure-handling standard: degraded
@@ -46,7 +46,7 @@ public function handle(RuleRegistrar $registrar): int
$count = count($registrar->classes());
return $count > 0
- ? ['OK', $count.' rules ('.count($registrar->clientCheckable()).' client-checkable)']
+ ? ['OK', $count . ' rules (' . count($registrar->clientCheckable()) . ' client-checkable)']
: ['FAIL', 'no rules discovered'];
}],
['disposable-domain list', function (): array {
@@ -54,16 +54,16 @@ public function handle(RuleRegistrar $registrar): int
return $list->contains('mailinator.com')
? ['OK', $list::class]
- : ['WARN', $list::class.' does not flag a canonical disposable domain'];
+ : ['WARN', $list::class . ' does not flag a canonical disposable domain'];
}],
['role-account list', fn (): array => ['OK', resolve(RoleAccountList::class)::class]],
- ['dns resolver', fn (): array => ['OK', resolve(DnsResolver::class)::class]],
+ ['dns resolver', fn (): array => ['OK', resolve(DnsResolver::class)::class]],
['batch query cap', function (): array {
$limit = BatchDatabaseChecker::$maxValuesPerGroup;
return $limit > 0
? ['OK', (string) $limit]
- : ['FAIL', 'cap is '.$limit.' — every batch would be refused'];
+ : ['FAIL', 'cap is ' . $limit . ' — every batch would be refused'];
}],
['string aliases', function (): array {
if (config('laranail.validation.aliases.enabled') !== true) {
@@ -73,7 +73,7 @@ public function handle(RuleRegistrar $registrar): int
$prefix = config('laranail.validation.aliases.prefix');
return is_string($prefix) && $prefix !== ''
- ? ['OK', 'enabled, prefix "'.$prefix.'"']
+ ? ['OK', 'enabled, prefix "' . $prefix . '"']
: ['FAIL', 'enabled with an empty prefix — bare generic names collide silently'];
}],
['ext-intl', fn (): array => extension_loaded('intl')
@@ -88,7 +88,7 @@ public function handle(RuleRegistrar $registrar): int
try {
[$status, $detail] = $check();
} catch (Throwable $e) {
- [$status, $detail] = ['FAIL', $e::class.': '.$e->getMessage()];
+ [$status, $detail] = ['FAIL', $e::class . ': ' . $e->getMessage()];
}
$failed = $failed || $status === 'FAIL';
diff --git a/src/Commands/RulesCommand.php b/src/Commands/RulesCommand.php
index 774f963..abd442c 100644
--- a/src/Commands/RulesCommand.php
+++ b/src/Commands/RulesCommand.php
@@ -6,10 +6,10 @@
use Illuminate\Foundation\Auth\User;
use Simtabi\Laranail\Console\Tools\Commands\Command;
-use Simtabi\Laranail\Console\Tools\Commands\Concerns\SupportsNamespacedNames;
-use Simtabi\Laranail\Validation\Contracts\ClientCheckable;
use Simtabi\Laranail\Validation\Support\RuleAliases;
use Simtabi\Laranail\Validation\Support\RuleRegistrar;
+use Simtabi\Laranail\Validation\Contracts\ClientCheckable;
+use Simtabi\Laranail\Console\Tools\Commands\Concerns\SupportsNamespacedNames;
/**
* Lists every rule the registry knows — the package's discovered library
@@ -64,19 +64,19 @@ class_basename($class),
private function aliasIndex(): array
{
$samples = [
- 'models_exist' => [User::class],
- 'authorized' => ['view', User::class],
- 'parity' => ['even'],
- 'vendor_identifier' => ['aws_region'],
+ 'models_exist' => [User::class],
+ 'authorized' => ['view', User::class],
+ 'parity' => ['even'],
+ 'vendor_identifier' => ['aws_region'],
'national_identifier' => ['nl'],
- 'minute_in' => ['0', '15', '30', '45'],
+ 'minute_in' => ['0', '15', '30', '45'],
'max_date_difference' => ['48', '2026-08-24 00:00:00'],
- 'minimum_age' => ['18'],
- 'compare_to_column' => ['posts', 'owner_id', 'gte', 'id', '1'],
+ 'minimum_age' => ['18'],
+ 'compare_to_column' => ['posts', 'owner_id', 'gte', 'id', '1'],
'file_exists_on_disk' => ['local'],
- 'hash_digest' => ['sha256'],
- 'max_words' => ['200'],
- 'min_words' => ['2'],
+ 'hash_digest' => ['sha256'],
+ 'max_words' => ['200'],
+ 'min_words' => ['2'],
];
$index = [];
diff --git a/src/Concerns/SkipsPrecognition.php b/src/Concerns/SkipsPrecognition.php
index aeae9cc..23be9fb 100644
--- a/src/Concerns/SkipsPrecognition.php
+++ b/src/Concerns/SkipsPrecognition.php
@@ -4,8 +4,8 @@
namespace Simtabi\Laranail\Validation\Concerns;
-use Illuminate\Container\Container;
use Illuminate\Http\Request;
+use Illuminate\Container\Container;
use Simtabi\Laranail\Validation\Contracts\PrecognitionSkippable;
/**
diff --git a/src/Contracts/FluentRuleContract.php b/src/Contracts/FluentRuleContract.php
index c8e44f3..450aa39 100644
--- a/src/Contracts/FluentRuleContract.php
+++ b/src/Contracts/FluentRuleContract.php
@@ -4,11 +4,11 @@
namespace Simtabi\Laranail\Validation\Contracts;
-use BackedEnum;
use Closure;
-use Illuminate\Contracts\Validation\ValidationRule;
+use BackedEnum;
use Illuminate\Support\Fluent;
use Illuminate\Support\HigherOrderWhenProxy;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Contract implemented by every rule class shipped in
@@ -133,7 +133,7 @@ public function prohibitedIfDeclined(string $field): static;
// ---------- Escape hatch ----------
/**
- * @param object|string|array $rule
+ * @param object|string|array $rule
*/
public function rule(object|string|array $rule): static;
@@ -151,25 +151,27 @@ public function rule(object|string|array $rule): static;
* return is `$this|\Illuminate\Conditionable\HigherOrderWhenProxy`
* depending on whether a callback is supplied.
*
- * @param mixed $value
- * @param (callable(static, mixed): mixed)|null $callback
- * @param (callable(static, mixed): mixed)|null $default
+ * @param mixed $value
+ * @param (callable(static, mixed): mixed)|null $callback
+ * @param (callable(static, mixed): mixed)|null $default
+ *
* @return static|HigherOrderWhenProxy
*/
public function when($value = null, ?callable $callback = null, ?callable $default = null);
/**
- * @param mixed $value
- * @param (callable(static, mixed): mixed)|null $callback
- * @param (callable(static, mixed): mixed)|null $default
+ * @param mixed $value
+ * @param (callable(static, mixed): mixed)|null $callback
+ * @param (callable(static, mixed): mixed)|null $default
+ *
* @return static|HigherOrderWhenProxy
*/
public function unless($value = null, ?callable $callback = null, ?callable $default = null);
/**
- * @param Closure(Fluent): bool $condition
- * @param Closure(static): static|string|list $rules
- * @param Closure(static): static|string|list $defaultRules
+ * @param Closure(Fluent): bool $condition
+ * @param Closure(static): static|string|list $rules
+ * @param Closure(static): static|string|list $defaultRules
*/
public function whenInput(Closure $condition, Closure|string|array $rules, Closure|string|array $defaultRules = []): static;
diff --git a/src/Events/RuleSetCompiling.php b/src/Events/RuleSetCompiling.php
index 1f0bc1b..1b00b7a 100644
--- a/src/Events/RuleSetCompiling.php
+++ b/src/Events/RuleSetCompiling.php
@@ -20,10 +20,10 @@
final class RuleSetCompiling
{
/**
- * @param array $rules Field → rule input, as the rule set holds it. Mutable.
- * @param array $messages Custom messages. Mutable.
- * @param array $attributes Human attribute names. Mutable.
- * @param array $data The data about to be validated. Mutable.
+ * @param array $rules Field → rule input, as the rule set holds it. Mutable.
+ * @param array $messages Custom messages. Mutable.
+ * @param array $attributes Human attribute names. Mutable.
+ * @param array $data The data about to be validated. Mutable.
*/
public function __construct(
public readonly RuleSet $ruleSet,
diff --git a/src/Events/ValidationCompleted.php b/src/Events/ValidationCompleted.php
index 9a5c709..2f54934 100644
--- a/src/Events/ValidationCompleted.php
+++ b/src/Events/ValidationCompleted.php
@@ -14,8 +14,8 @@
final readonly class ValidationCompleted
{
/**
- * @param array $data
- * @param array $validated
+ * @param array $data
+ * @param array $validated
*/
public function __construct(
public RuleSet $ruleSet,
diff --git a/src/Events/ValidationFailed.php b/src/Events/ValidationFailed.php
index 92c8dcc..43b8557 100644
--- a/src/Events/ValidationFailed.php
+++ b/src/Events/ValidationFailed.php
@@ -5,8 +5,8 @@
namespace Simtabi\Laranail\Validation\Events;
use Illuminate\Support\MessageBag;
-use Illuminate\Validation\ValidationException;
use Simtabi\Laranail\Validation\RuleSet;
+use Illuminate\Validation\ValidationException;
/**
* Fired when a {@see RuleSet} run FAILS — the notification seam.
diff --git a/src/Exceptions/CannotExtendListShapedEach.php b/src/Exceptions/CannotExtendListShapedEach.php
index 9530806..ce88abe 100644
--- a/src/Exceptions/CannotExtendListShapedEach.php
+++ b/src/Exceptions/CannotExtendListShapedEach.php
@@ -22,8 +22,8 @@ public static function on(string $method): self
{
return new self(sprintf(
'Cannot call %s() on an ArrayRule whose each() is list-shaped '
- .'(e.g. each(FluentRule::string())). Convert to keyed form '
- ."first: each(['key' => FluentRule::…]).",
+ . '(e.g. each(FluentRule::string())). Convert to keyed form '
+ . "first: each(['key' => FluentRule::…]).",
$method,
));
}
diff --git a/src/Exceptions/TypedBuilderHint.php b/src/Exceptions/TypedBuilderHint.php
index ad9058a..4f72b49 100644
--- a/src/Exceptions/TypedBuilderHint.php
+++ b/src/Exceptions/TypedBuilderHint.php
@@ -6,17 +6,17 @@
use ReflectionClass;
use ReflectionMethod;
-use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
use Simtabi\Laranail\Validation\Builder\Nodes\DateRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
use Simtabi\Laranail\Validation\Builder\Nodes\EmailRule;
use Simtabi\Laranail\Validation\Builder\Nodes\FieldRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
use Simtabi\Laranail\Validation\Builder\Nodes\ImageRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\StringRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
use Simtabi\Laranail\Validation\Builder\Nodes\NumericRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
use Simtabi\Laranail\Validation\Builder\Nodes\PasswordRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\StringRule;
/**
* Maps method names to hints pointing at the typed builder(s) that
@@ -47,16 +47,16 @@ final class TypedBuilderHint
* factory name inserted into generated hints.
*/
private const array TYPED_BUILDERS = [
- StringRule::class => 'string',
- NumericRule::class => 'numeric',
- DateRule::class => 'date',
- ArrayRule::class => 'array',
- FileRule::class => 'file',
- ImageRule::class => 'image',
- BooleanRule::class => 'boolean',
+ StringRule::class => 'string',
+ NumericRule::class => 'numeric',
+ DateRule::class => 'date',
+ ArrayRule::class => 'array',
+ FileRule::class => 'file',
+ ImageRule::class => 'image',
+ BooleanRule::class => 'boolean',
AcceptedRule::class => 'accepted',
PasswordRule::class => 'password',
- EmailRule::class => 'email',
+ EmailRule::class => 'email',
];
/**
@@ -113,14 +113,14 @@ public static function for(string $method): ?string
private static function specialCase(string $method): ?string
{
return match ($method) {
- 'accepted' => 'Use `FluentRule::accepted()` for permissive accepted values (`\'yes\'`, `\'on\'`, `\'1\'`, `true`). Avoid `FluentRule::boolean()->accepted()` — the `boolean` base rule rejects `\'yes\'`/`\'on\'`.',
- 'declined' => "Use `FluentRule::boolean()->declined(...)` for strict boolean-only input. If HTML form values (`'no'`, `'off'`) need to pass, use `->rule('declined')` on the untyped builder instead.",
- 'size' => 'No `size()` method — use `->exactly(...)` on a typed builder. (This package renames Laravel\'s `size:` rule to `exactly()` for clarity.)',
+ 'accepted' => 'Use `FluentRule::accepted()` for permissive accepted values (`\'yes\'`, `\'on\'`, `\'1\'`, `true`). Avoid `FluentRule::boolean()->accepted()` — the `boolean` base rule rejects `\'yes\'`/`\'on\'`.',
+ 'declined' => "Use `FluentRule::boolean()->declined(...)` for strict boolean-only input. If HTML form values (`'no'`, `'off'`) need to pass, use `->rule('declined')` on the untyped builder instead.",
+ 'size' => 'No `size()` method — use `->exactly(...)` on a typed builder. (This package renames Laravel\'s `size:` rule to `exactly()` for clarity.)',
'gt', 'gte', 'lt', 'lte' => 'No `gt()`/`lt()` methods — use `FluentRule::numeric()->greaterThan(FIELD)`, `->greaterThanOrEqualTo(FIELD)`, `->lessThan(FIELD)`, `->lessThanOrEqualTo(FIELD)`.',
- 'alphaNum' => 'No `alphaNum()` method — use `FluentRule::string()->alphaNumeric(...)`.',
- 'contains' => 'Use `FluentRule::array()->contains(...)` (this package exposes `contains` on `array()`, not `string()`).',
- 'format' => 'Use `FluentRule::date()->format(...)` for date format; for string-format regex use `FluentRule::string()->regex(...)`.',
- default => null,
+ 'alphaNum' => 'No `alphaNum()` method — use `FluentRule::string()->alphaNumeric(...)`.',
+ 'contains' => 'Use `FluentRule::array()->contains(...)` (this package exposes `contains` on `array()`, not `string()`).',
+ 'format' => 'Use `FluentRule::date()->format(...)` for date format; for string-format regex use `FluentRule::string()->regex(...)`.',
+ default => null,
};
}
@@ -157,7 +157,8 @@ private static function methodMap(): array
}
/**
- * @param class-string $class
+ * @param class-string $class
+ *
* @return array
*/
private static function publicInstanceMethods(string $class): array
@@ -186,7 +187,7 @@ private static function publicInstanceMethods(string $class): array
}
/**
- * @param list $factories
+ * @param list $factories
*/
private static function formatFactoryList(array $factories): string
{
@@ -201,6 +202,6 @@ private static function formatFactoryList(array $factories): string
$last = array_pop($formatted);
- return implode(', ', $formatted).', or '.$last;
+ return implode(', ', $formatted) . ', or ' . $last;
}
}
diff --git a/src/FastCheck/ItemContextCompiler.php b/src/FastCheck/ItemContextCompiler.php
index d660355..f1a5a0b 100644
--- a/src/FastCheck/ItemContextCompiler.php
+++ b/src/FastCheck/ItemContextCompiler.php
@@ -74,9 +74,9 @@ private static function rewriteConfirmedRule(string $ruleString, string $attribu
foreach ($parts as $i => $part) {
if ($part === 'confirmed') {
- $parts[$i] = 'same:'.$attributeName.'_confirmation';
+ $parts[$i] = 'same:' . $attributeName . '_confirmation';
} elseif (str_starts_with($part, 'confirmed:')) {
- $parts[$i] = 'same:'.substr($part, 10);
+ $parts[$i] = 'same:' . substr($part, 10);
}
}
@@ -143,7 +143,8 @@ private static function parseWithItemContext(string $ruleString): ?array
}
/**
- * @param array $config
+ * @param array $config
+ *
* @return array|null
*/
private static function parsePartWithItemContext(string $part, array $config): ?array
@@ -151,18 +152,18 @@ private static function parsePartWithItemContext(string $part, array $config): ?
// For date rules, use the field-ref-aware parser. For everything else,
// delegate to the value-only parser in RuleConfigBuilder.
return match (true) {
- str_starts_with($part, 'date_equals:') => self::parseDateParamWithFieldRef($config, 'dateEquals', substr($part, 12)),
- str_starts_with($part, 'after_or_equal:') => self::parseDateParamWithFieldRef($config, 'afterOrEqual', substr($part, 15)),
+ str_starts_with($part, 'date_equals:') => self::parseDateParamWithFieldRef($config, 'dateEquals', substr($part, 12)),
+ str_starts_with($part, 'after_or_equal:') => self::parseDateParamWithFieldRef($config, 'afterOrEqual', substr($part, 15)),
str_starts_with($part, 'before_or_equal:') => self::parseDateParamWithFieldRef($config, 'beforeOrEqual', substr($part, 16)),
- str_starts_with($part, 'after:') => self::parseDateParamWithFieldRef($config, 'after', substr($part, 6)),
- str_starts_with($part, 'before:') => self::parseDateParamWithFieldRef($config, 'before', substr($part, 7)),
- str_starts_with($part, 'same:') => self::parseFieldOnlyRef($config, 'sameField', substr($part, 5)),
- str_starts_with($part, 'different:') => self::parseFieldOnlyRef($config, 'differentField', substr($part, 10)),
- str_starts_with($part, 'gte:') => self::parseFieldOnlyRef($config, 'gteField', substr($part, 4)),
- str_starts_with($part, 'lte:') => self::parseFieldOnlyRef($config, 'lteField', substr($part, 4)),
- str_starts_with($part, 'gt:') => self::parseFieldOnlyRef($config, 'gtField', substr($part, 3)),
- str_starts_with($part, 'lt:') => self::parseFieldOnlyRef($config, 'ltField', substr($part, 3)),
- default => RuleConfigBuilder::parseValuePart($part, $config),
+ str_starts_with($part, 'after:') => self::parseDateParamWithFieldRef($config, 'after', substr($part, 6)),
+ str_starts_with($part, 'before:') => self::parseDateParamWithFieldRef($config, 'before', substr($part, 7)),
+ str_starts_with($part, 'same:') => self::parseFieldOnlyRef($config, 'sameField', substr($part, 5)),
+ str_starts_with($part, 'different:') => self::parseFieldOnlyRef($config, 'differentField', substr($part, 10)),
+ str_starts_with($part, 'gte:') => self::parseFieldOnlyRef($config, 'gteField', substr($part, 4)),
+ str_starts_with($part, 'lte:') => self::parseFieldOnlyRef($config, 'lteField', substr($part, 4)),
+ str_starts_with($part, 'gt:') => self::parseFieldOnlyRef($config, 'gtField', substr($part, 3)),
+ str_starts_with($part, 'lt:') => self::parseFieldOnlyRef($config, 'ltField', substr($part, 3)),
+ default => RuleConfigBuilder::parseValuePart($part, $config),
};
}
@@ -171,7 +172,8 @@ private static function parsePartWithItemContext(string $part, array $config): ?
* is a date literal, behaves like a literal parse. Otherwise, if it's a
* plausible field name, stores it under `{$key}Field` for item-time resolution.
*
- * @param array $config
+ * @param array $config
+ *
* @return array|null
*/
private static function parseDateParamWithFieldRef(array $config, string $key, string $param): ?array
@@ -187,7 +189,7 @@ private static function parseDateParamWithFieldRef(array $config, string $key, s
return null;
}
- return [...$config, $key.'Field' => $param];
+ return [...$config, $key . 'Field' => $param];
}
/**
@@ -195,7 +197,8 @@ private static function parseDateParamWithFieldRef(array $config, string $key, s
* parameter isn't a single plausible identifier — so multi-param forms
* like `different:a,b` fall through to Laravel.
*
- * @param array $config
+ * @param array $config
+ *
* @return array|null
*/
private static function parseFieldOnlyRef(array $config, string $key, string $param): ?array
@@ -212,7 +215,8 @@ private static function parseFieldOnlyRef(array $config, string $key, string $pa
* against the item array. Delegates most checks to CoreValueCompiler's
* value-only closure.
*
- * @param array $c
+ * @param array $c
+ *
* @return Closure(mixed, array): bool
*/
private static function buildItemAwareClosure(array $c): Closure
@@ -434,7 +438,7 @@ private static function sizePair(mixed $value, mixed $ref, bool $isNumeric, bool
* missing, empty, non-string, unparseable) coerce to 0 — matches Laravel's
* loose-comparison behavior when a referenced field doesn't parse.
*
- * @param array $item
+ * @param array $item
*/
private static function resolveRefTimestamp(array $item, string $field): int
{
diff --git a/src/FastCheck/PresenceConditionalCompiler.php b/src/FastCheck/PresenceConditionalCompiler.php
index b448018..48077f2 100644
--- a/src/FastCheck/PresenceConditionalCompiler.php
+++ b/src/FastCheck/PresenceConditionalCompiler.php
@@ -5,8 +5,8 @@
namespace Simtabi\Laranail\Validation\FastCheck;
use Closure;
-use Simtabi\Laranail\Validation\FastCheck\Shared\ItemAwareBranchBuilder;
use Simtabi\Laranail\Validation\FastCheck\Shared\LaravelEmptiness;
+use Simtabi\Laranail\Validation\FastCheck\Shared\ItemAwareBranchBuilder;
/**
* Compiles rule strings that contain presence conditionals —
@@ -95,8 +95,8 @@ public static function compile(string $ruleString): ?Closure
* A field is "present" by Laravel's `validateRequired` criteria: not null,
* not whitespace-only string, not empty array/Countable.
*
- * @param list $fields
- * @param array $item
+ * @param list $fields
+ * @param array $item
*/
private static function presenceConditionActive(string $type, array $fields, array $item): bool
{
@@ -106,11 +106,11 @@ private static function presenceConditionActive(string $type, array $fields, arr
}
return match ($type) {
- 'required_with' => in_array(true, $present, true),
- 'required_without' => in_array(false, $present, true),
- 'required_with_all' => ! in_array(false, $present, true),
+ 'required_with' => in_array(true, $present, true),
+ 'required_without' => in_array(false, $present, true),
+ 'required_with_all' => ! in_array(false, $present, true),
'required_without_all' => ! in_array(true, $present, true),
- default => false,
+ default => false,
};
}
}
diff --git a/src/FastCheck/RuleConfigBuilder.php b/src/FastCheck/RuleConfigBuilder.php
index d0f8437..b32dc4a 100644
--- a/src/FastCheck/RuleConfigBuilder.php
+++ b/src/FastCheck/RuleConfigBuilder.php
@@ -34,28 +34,28 @@ final class RuleConfigBuilder
public static function initialConfig(): array
{
return [
- 'required' => false, 'filled' => false,
- 'nullable' => false, 'sometimes' => false,
- 'string' => false, 'numeric' => false, 'integer' => false, 'integer.strict' => false,
- 'boolean' => false, 'array' => false, 'email' => false, 'date' => false,
- 'url' => false, 'ip' => false, 'uuid' => false, 'ulid' => false,
- 'accepted' => false, 'declined' => false,
- 'alpha' => false, 'alphaDash' => false, 'alphaNum' => false,
- 'min' => null, 'max' => null,
- 'digits' => null, 'digitsMin' => null, 'digitsMax' => null,
- 'in' => null, 'notIn' => null,
- 'regex' => null, 'notRegex' => null,
- 'dateFormat' => null,
- 'after' => null, 'before' => null,
+ 'required' => false, 'filled' => false,
+ 'nullable' => false, 'sometimes' => false,
+ 'string' => false, 'numeric' => false, 'integer' => false, 'integer.strict' => false,
+ 'boolean' => false, 'array' => false, 'email' => false, 'date' => false,
+ 'url' => false, 'ip' => false, 'uuid' => false, 'ulid' => false,
+ 'accepted' => false, 'declined' => false,
+ 'alpha' => false, 'alphaDash' => false, 'alphaNum' => false,
+ 'min' => null, 'max' => null,
+ 'digits' => null, 'digitsMin' => null, 'digitsMax' => null,
+ 'in' => null, 'notIn' => null,
+ 'regex' => null, 'notRegex' => null,
+ 'dateFormat' => null,
+ 'after' => null, 'before' => null,
'afterOrEqual' => null, 'beforeOrEqual' => null,
- 'dateEquals' => null,
+ 'dateEquals' => null,
// Item-context field-reference keys — populated by ItemContextCompiler.
- 'afterField' => null, 'beforeField' => null,
+ 'afterField' => null, 'beforeField' => null,
'afterOrEqualField' => null, 'beforeOrEqualField' => null,
- 'dateEqualsField' => null,
- 'sameField' => null, 'differentField' => null,
- 'gtField' => null, 'gteField' => null,
- 'ltField' => null, 'lteField' => null,
+ 'dateEqualsField' => null,
+ 'sameField' => null, 'differentField' => null,
+ 'gtField' => null, 'gteField' => null,
+ 'ltField' => null, 'lteField' => null,
];
}
@@ -65,7 +65,8 @@ public static function initialConfig(): array
* rules (`same:FIELD`, `gt:FIELD`, etc.) are NOT handled here — see
* `ItemContextCompiler::parsePartWithItemContext` for that path.
*
- * @param array $config
+ * @param array $config
+ *
* @return array|null
*/
public static function parseValuePart(string $part, array $config): ?array
@@ -85,34 +86,34 @@ public static function parseValuePart(string $part, array $config): ?array
}
return match (true) {
- $part === 'integer' => [...$config, 'integer' => true],
- $part === 'integer:strict' => [...$config, 'integer' => true, 'integer.strict' => true],
- $part === 'alpha', $part === 'alpha:ascii' => [...$config, 'alpha' => true],
+ $part === 'integer' => [...$config, 'integer' => true],
+ $part === 'integer:strict' => [...$config, 'integer' => true, 'integer.strict' => true],
+ $part === 'alpha', $part === 'alpha:ascii' => [...$config, 'alpha' => true],
$part === 'alpha_dash', $part === 'alpha_dash:ascii' => [...$config, 'alphaDash' => true],
- $part === 'alpha_num', $part === 'alpha_num:ascii' => [...$config, 'alphaNum' => true],
- $part === 'nullable' => [...$config, 'nullable' => true],
+ $part === 'alpha_num', $part === 'alpha_num:ascii' => [...$config, 'alphaNum' => true],
+ $part === 'nullable' => [...$config, 'nullable' => true],
// 'sometimes' not fast-checkable: distinguishing absent from
// present-null requires presence info the closure doesn't have.
$part === 'sometimes' => null,
- $part === 'bail' => $config,
+ $part === 'bail' => $config,
// Not (int): NumericRule::min() accepts int|float, and Laravel
// compares with BigNumber against the raw parameter. Casting
// `min:2.5` to 2 lets 2.2 through.
- str_starts_with($part, 'min:') => [...$config, 'min' => self::parseSize(substr($part, 4))],
- str_starts_with($part, 'max:') => [...$config, 'max' => self::parseSize(substr($part, 4))],
- str_starts_with($part, 'digits:') => [...$config, 'digits' => (int) substr($part, 7)],
- str_starts_with($part, 'digits_between:') => self::parseDigitsBetween($config, substr($part, 15)),
- str_starts_with($part, 'in:') => [...$config, 'in' => self::parseInValues(substr($part, 3))],
- str_starts_with($part, 'not_in:') => [...$config, 'notIn' => self::parseInValues(substr($part, 7))],
- str_starts_with($part, 'regex:') => [...$config, 'regex' => substr($part, 6)],
- str_starts_with($part, 'not_regex:') => [...$config, 'notRegex' => substr($part, 10)],
- str_starts_with($part, 'date_format:') => [...$config, 'dateFormat' => substr($part, 12)],
- str_starts_with($part, 'date_equals:') => self::parseDateLiteral($config, 'dateEquals', substr($part, 12)),
- str_starts_with($part, 'after_or_equal:') => self::parseDateLiteral($config, 'afterOrEqual', substr($part, 15)),
+ str_starts_with($part, 'min:') => [...$config, 'min' => self::parseSize(substr($part, 4))],
+ str_starts_with($part, 'max:') => [...$config, 'max' => self::parseSize(substr($part, 4))],
+ str_starts_with($part, 'digits:') => [...$config, 'digits' => (int) substr($part, 7)],
+ str_starts_with($part, 'digits_between:') => self::parseDigitsBetween($config, substr($part, 15)),
+ str_starts_with($part, 'in:') => [...$config, 'in' => self::parseInValues(substr($part, 3))],
+ str_starts_with($part, 'not_in:') => [...$config, 'notIn' => self::parseInValues(substr($part, 7))],
+ str_starts_with($part, 'regex:') => [...$config, 'regex' => substr($part, 6)],
+ str_starts_with($part, 'not_regex:') => [...$config, 'notRegex' => substr($part, 10)],
+ str_starts_with($part, 'date_format:') => [...$config, 'dateFormat' => substr($part, 12)],
+ str_starts_with($part, 'date_equals:') => self::parseDateLiteral($config, 'dateEquals', substr($part, 12)),
+ str_starts_with($part, 'after_or_equal:') => self::parseDateLiteral($config, 'afterOrEqual', substr($part, 15)),
str_starts_with($part, 'before_or_equal:') => self::parseDateLiteral($config, 'beforeOrEqual', substr($part, 16)),
- str_starts_with($part, 'after:') => self::parseDateLiteral($config, 'after', substr($part, 6)),
- str_starts_with($part, 'before:') => self::parseDateLiteral($config, 'before', substr($part, 7)),
- default => null,
+ str_starts_with($part, 'after:') => self::parseDateLiteral($config, 'after', substr($part, 6)),
+ str_starts_with($part, 'before:') => self::parseDateLiteral($config, 'before', substr($part, 7)),
+ default => null,
};
}
@@ -121,7 +122,7 @@ public static function parseValuePart(string $part, array $config): ?array
* measure: string length, array count, or numeric value. Without one,
* Laravel infers from runtime type — not fast-checkable.
*
- * @param array $config
+ * @param array $config
*/
public static function validateSizeRuleHasType(array $config): bool
{
@@ -146,7 +147,7 @@ public static function validateSizeRuleHasType(array $config): bool
* loose subset semantics (array_diff), which the scalar closure
* cannot reproduce.
*
- * @param array $config
+ * @param array $config
*/
public static function validateCompilableCombinations(array $config): bool
{
@@ -169,7 +170,8 @@ public static function validateCompilableCombinations(array $config): bool
* Build the value-only closure from a parsed config. ItemContextCompiler
* wraps the result in an item-aware closure for cross-field comparisons.
*
- * @param array $c
+ * @param array $c
+ *
* @return Closure(mixed): bool
*/
public static function buildValueClosure(array $c): Closure
@@ -313,7 +315,8 @@ public static function buildValueClosure(array $c): Closure
}
/**
- * @param array $config
+ * @param array $config
+ *
* @return array
*/
private static function parseDigitsBetween(array $config, string $value): array
@@ -378,7 +381,7 @@ private static function parseSize(string $value): int|float
* through a strict-comparison-friendly operator. Used to detect the
* loose/strict DISAGREEMENT zone the fast path must not decide.
*
- * @param list $haystack
+ * @param list $haystack
*/
private static function matchesLoosely(string $needle, array $haystack): bool
{
@@ -407,7 +410,8 @@ private static function parseInValues(string $values): array
* Parse a date comparison rule. Only compiles when the parameter is a
* date literal (resolvable by strtotime), not a field reference.
*
- * @param array $config
+ * @param array $config
+ *
* @return array|null
*/
private static function parseDateLiteral(array $config, string $key, string $param): ?array
@@ -428,8 +432,8 @@ private static function parseDateLiteral(array $config, string $key, string $par
* Mutates `$checks` in place; closures capture the type literals they
* compare against.
*
- * @param array $c
- * @param list $checks
+ * @param array $c
+ * @param list $checks
*/
private static function addTypeChecks(array $c, array &$checks): void
{
@@ -467,8 +471,8 @@ private static function addTypeChecks(array $c, array &$checks): void
/**
* Append format-check closures (email, url, ip, uuid, ulid, alpha-family).
*
- * @param array $c
- * @param list $checks
+ * @param array $c
+ * @param list $checks
*/
private static function addFormatChecks(array $c, array &$checks): void
{
@@ -513,8 +517,8 @@ private static function addFormatChecks(array $c, array &$checks): void
/**
* Append date-check closure when any date-literal rule is set.
*
- * @param array $c
- * @param list $checks
+ * @param array $c
+ * @param list $checks
*/
private static function addDateChecks(array $c, array &$checks): void
{
@@ -543,7 +547,7 @@ private static function addDateChecks(array $c, array &$checks): void
}
if ($dateFormat !== null) {
- $d = DateTime::createFromFormat('!'.$dateFormat, $v);
+ $d = DateTime::createFromFormat('!' . $dateFormat, $v);
return $d !== false && $d->format($dateFormat) === $v;
}
@@ -590,8 +594,8 @@ private static function timestampWithinBounds(
/**
* Append digit-check closure(s) when `digits:` or `digits_between:` is set.
*
- * @param array $c
- * @param list $checks
+ * @param array $c
+ * @param list $checks
*/
private static function addDigitChecks(array $c, array &$checks): void
{
diff --git a/src/FastCheckCompiler.php b/src/FastCheckCompiler.php
index e0a611d..1d3f8a3 100644
--- a/src/FastCheckCompiler.php
+++ b/src/FastCheckCompiler.php
@@ -6,9 +6,9 @@
use Closure;
use Simtabi\Laranail\Validation\FastCheck\CoreValueCompiler;
+use Simtabi\Laranail\Validation\FastCheck\ProhibitedCompiler;
use Simtabi\Laranail\Validation\FastCheck\ItemContextCompiler;
use Simtabi\Laranail\Validation\FastCheck\PresenceConditionalCompiler;
-use Simtabi\Laranail\Validation\FastCheck\ProhibitedCompiler;
/**
* Thin dispatcher over per-family compilers under {@see FastCheck}.
diff --git a/src/FluentRule.php b/src/FluentRule.php
index be18ada..6993c9c 100644
--- a/src/FluentRule.php
+++ b/src/FluentRule.php
@@ -4,31 +4,31 @@
namespace Simtabi\Laranail\Validation;
-use BackedEnum;
use Closure;
-use Illuminate\Contracts\Support\Arrayable;
-use Illuminate\Support\Traits\Macroable;
+use BackedEnum;
use Illuminate\Validation\Rules\AnyOf;
-use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
+use Illuminate\Support\Traits\Macroable;
+use Illuminate\Contracts\Support\Arrayable;
+use Simtabi\Laranail\Validation\Rules\Net\Subdomain;
+use Simtabi\Laranail\Validation\Rules\Text\Username;
+use Simtabi\Laranail\Validation\Rules\Net\DomainName;
+use Simtabi\Laranail\Validation\Builder\Nodes\UrlRule;
use Simtabi\Laranail\Validation\Builder\Nodes\DateRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\DeclinedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
use Simtabi\Laranail\Validation\Builder\Nodes\EmailRule;
use Simtabi\Laranail\Validation\Builder\Nodes\FieldRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
use Simtabi\Laranail\Validation\Builder\Nodes\ImageRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\IpAddressRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\MacAddressRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\NumericRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\PasswordRule;
use Simtabi\Laranail\Validation\Builder\Nodes\PhoneRule;
use Simtabi\Laranail\Validation\Builder\Nodes\StringRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\UrlRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\NumericRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\DeclinedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\PasswordRule;
use Simtabi\Laranail\Validation\Builder\Nodes\UsernameRule;
-use Simtabi\Laranail\Validation\Rules\Net\DomainName;
-use Simtabi\Laranail\Validation\Rules\Net\Subdomain;
-use Simtabi\Laranail\Validation\Rules\Text\Username;
+use Simtabi\Laranail\Validation\Builder\Nodes\IpAddressRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\MacAddressRule;
class FluentRule
{
@@ -395,7 +395,7 @@ public static function field(?string $label = null): FieldRule
}
/**
- * @param array $rules
+ * @param array $rules
*/
public static function anyOf(array $rules): AnyOf
{
diff --git a/src/FluentSchema.php b/src/FluentSchema.php
index 09e4e14..7667fd3 100644
--- a/src/FluentSchema.php
+++ b/src/FluentSchema.php
@@ -4,27 +4,27 @@
namespace Simtabi\Laranail\Validation;
-use BackedEnum;
use Closure;
-use Illuminate\Contracts\Support\Arrayable;
+use BackedEnum;
use Illuminate\Validation\Rules\AnyOf;
-use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
+use Illuminate\Contracts\Support\Arrayable;
+use Simtabi\Laranail\Validation\Builder\Nodes\UrlRule;
use Simtabi\Laranail\Validation\Builder\Nodes\DateRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\DeclinedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\ArrayRule;
use Simtabi\Laranail\Validation\Builder\Nodes\EmailRule;
use Simtabi\Laranail\Validation\Builder\Nodes\FieldRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\FileRule;
use Simtabi\Laranail\Validation\Builder\Nodes\ImageRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\IpAddressRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\MacAddressRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\NumericRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\PasswordRule;
use Simtabi\Laranail\Validation\Builder\Nodes\PhoneRule;
use Simtabi\Laranail\Validation\Builder\Nodes\StringRule;
-use Simtabi\Laranail\Validation\Builder\Nodes\UrlRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\BooleanRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\NumericRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\AcceptedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\DeclinedRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\PasswordRule;
use Simtabi\Laranail\Validation\Builder\Nodes\UsernameRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\IpAddressRule;
+use Simtabi\Laranail\Validation\Builder\Nodes\MacAddressRule;
/**
* Instance-based mirror of the {@see FluentRule} static factory.
@@ -51,7 +51,7 @@ final class FluentSchema
* Forward anything not declared above to {@see FluentRule}, so macros
* registered on the static factory are also reachable on the instance.
*
- * @param array $arguments
+ * @param array $arguments
*/
public function __call(string $name, array $arguments): mixed
{
@@ -223,7 +223,7 @@ public function field(?string $label = null): FieldRule
}
/**
- * @param array $rules
+ * @param array $rules
*/
public function anyOf(array $rules): AnyOf
{
diff --git a/src/FluentValidator.php b/src/FluentValidator.php
index f0bbabe..b114e2a 100644
--- a/src/FluentValidator.php
+++ b/src/FluentValidator.php
@@ -4,9 +4,9 @@
namespace Simtabi\Laranail\Validation;
+use ReflectionProperty;
use Illuminate\Contracts\Translation\Translator;
use Illuminate\Validation\DatabasePresenceVerifier;
-use ReflectionProperty;
use Simtabi\Laranail\Validation\Internal\PreparesOptimizedRules;
/**
@@ -35,10 +35,10 @@ abstract class FluentValidator extends OptimizedValidator
use PreparesOptimizedRules;
/**
- * @param array $data
- * @param array $rules
- * @param array $messages
- * @param array $attributes
+ * @param array $data
+ * @param array $rules
+ * @param array $messages
+ * @param array $attributes
*/
public function __construct(
array $data,
diff --git a/src/HasFluentRules.php b/src/HasFluentRules.php
index f7d6676..110bc14 100644
--- a/src/HasFluentRules.php
+++ b/src/HasFluentRules.php
@@ -4,14 +4,14 @@
namespace Simtabi\Laranail\Validation;
-use Illuminate\Container\Container;
-use Illuminate\Contracts\Validation\Factory as ValidationFactory;
-use Illuminate\Validation\Validator;
use ReflectionMethod;
-use ReflectionNamedType;
use ReflectionProperty;
-use Simtabi\Laranail\Validation\Internal\PreparesOptimizedRules;
+use ReflectionNamedType;
+use Illuminate\Container\Container;
+use Illuminate\Validation\Validator;
use Simtabi\Laranail\Validation\Internal\ValidatorStateCopier;
+use Simtabi\Laranail\Validation\Internal\PreparesOptimizedRules;
+use Illuminate\Contracts\Validation\Factory as ValidationFactory;
/**
* Add this trait to a FormRequest to enable FluentRule features:
@@ -99,8 +99,8 @@ protected function createDefaultValidator(ValidationFactory $factory): Validator
$this->container->call([$this, 'rules']),
),
$hasSchema => $this->container->call([$this, 'schema']),
- $hasRules => $this->container->call([$this, 'rules']),
- default => [],
+ $hasRules => $this->container->call([$this, 'rules']),
+ default => [],
};
/** @var array $data */
@@ -252,10 +252,10 @@ private function definesOwnRules(): bool
* (extensions, container, presence verifier, excludeUnvalidatedArrayKeys)
* without mutating the shared factory's resolver. Octane-safe.
*
- * @param array $data
- * @param array $rules
- * @param array $messages
- * @param array $attributes
+ * @param array $data
+ * @param array $rules
+ * @param array $messages
+ * @param array $attributes
*/
private function makeOptimizedValidator(
ValidationFactory $factory,
diff --git a/src/HasFluentValidation.php b/src/HasFluentValidation.php
index 18b2237..9bf9cf5 100644
--- a/src/HasFluentValidation.php
+++ b/src/HasFluentValidation.php
@@ -167,9 +167,10 @@ public function validateOnly(mixed $field, mixed $rules = null, mixed $messages
* Compile FluentRule objects to native format, expand wildcards
* against actual data, and extract labels/messages.
*
- * @param array|null $rules
- * @param array $messages
- * @param array $attributes
+ * @param array|null $rules
+ * @param array $messages
+ * @param array $attributes
+ *
* @return array{0: array|null, 1: array, 2: array}
*/
protected function compileFluentRules(?array $rules, array $messages, array $attributes): array
@@ -218,7 +219,8 @@ protected function compileFluentRules(?array $rules, array $messages, array $att
/**
* Merge with Livewire's rulesFromOutside (same as parent::getRules()).
*
- * @param array $rules
+ * @param array $rules
+ *
* @return array
*/
private function mergeRulesFromOutside(array $rules): array
diff --git a/src/Internal/AbstractConditionalReducer.php b/src/Internal/AbstractConditionalReducer.php
index 76f98f3..f517bfb 100644
--- a/src/Internal/AbstractConditionalReducer.php
+++ b/src/Internal/AbstractConditionalReducer.php
@@ -28,7 +28,7 @@ abstract class AbstractConditionalReducer
* reducer recognises? Used by callers to decide whether the per-item
* reducer path must engage.
*
- * @param array $itemRules
+ * @param array $itemRules
*/
public static function hasAny(array $itemRules): bool
{
@@ -57,7 +57,7 @@ public static function hasAny(array $itemRules): bool
* Subclasses' `apply()` methods bind their per-call context (field,
* itemData, etc.) into a closure and hand it here.
*
- * @param Closure(string): ?string $rewriteOne
+ * @param Closure(string): ?string $rewriteOne
*/
protected static function applyTemplate(mixed $rule, Closure $rewriteOne): mixed
{
@@ -105,7 +105,7 @@ protected static function applyTemplate(mixed $rule, Closure $rewriteOne): mixed
* rewrite path doesn't bypass a `{field}.{rule}`-style override at
* message-formatting time. Identical across all conditional reducers.
*
- * @param array $itemMessages
+ * @param array $itemMessages
*/
protected static function hasCustomMessage(string $field, string $ruleName, array $itemMessages): bool
{
@@ -115,8 +115,8 @@ protected static function hasCustomMessage(string $field, string $ruleName, arra
// Match any message whose key equals `{field}.{rule}` or ends with
// `.{field}.{rule}` — covers bare-field, wildcard-prefixed, and
// any parent-prefixed variant.
- $suffix = '.'.$field.'.'.$ruleName;
- $exactKey = $field.'.'.$ruleName;
+ $suffix = '.' . $field . '.' . $ruleName;
+ $exactKey = $field . '.' . $ruleName;
foreach (array_keys($itemMessages) as $key) {
$key = (string) $key;
if ($key === $exactKey || str_ends_with($key, $suffix)) {
@@ -125,7 +125,7 @@ protected static function hasCustomMessage(string $field, string $ruleName, arra
}
if (function_exists('trans')) {
- $translatorKey = 'validation.custom.'.$field.'.'.$ruleName;
+ $translatorKey = 'validation.custom.' . $field . '.' . $ruleName;
$translated = trans($translatorKey);
if (is_string($translated) && $translated !== $translatorKey) {
return true;
@@ -137,10 +137,10 @@ protected static function hasCustomMessage(string $field, string $ruleName, arra
// `validation.custom` namespace — mirror Validator::getCustomMessageFromTranslator.
$custom = trans('validation.custom');
if (is_array($custom)) {
- $shortKey = $field.'.'.$ruleName;
+ $shortKey = $field . '.' . $ruleName;
foreach (array_keys(Arr::dot($custom)) as $customKey) {
$customKey = (string) $customKey;
- if ($customKey === $shortKey || str_ends_with($customKey, '.'.$shortKey)) {
+ if ($customKey === $shortKey || str_ends_with($customKey, '.' . $shortKey)) {
return true;
}
}
diff --git a/src/Internal/BatchLimitRemap.php b/src/Internal/BatchLimitRemap.php
index a34f7c2..653633a 100644
--- a/src/Internal/BatchLimitRemap.php
+++ b/src/Internal/BatchLimitRemap.php
@@ -4,10 +4,10 @@
namespace Simtabi\Laranail\Validation\Internal;
+use ReflectionProperty;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Validation\Validator as IlluminateValidator;
-use ReflectionProperty;
use Simtabi\Laranail\Validation\Exceptions\BatchLimitExceededException;
/**
diff --git a/src/Internal/BatchPresenceQuery.php b/src/Internal/BatchPresenceQuery.php
index 20b72de..4211dc9 100644
--- a/src/Internal/BatchPresenceQuery.php
+++ b/src/Internal/BatchPresenceQuery.php
@@ -4,8 +4,8 @@
namespace Simtabi\Laranail\Validation\Internal;
-use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
+use Illuminate\Database\Query\Builder;
/**
* Runs the batched whereIn query for exists/unique presence verification,
@@ -19,8 +19,9 @@ final class BatchPresenceQuery
private const int CHUNK_SIZE = 1000;
/**
- * @param array $values
- * @param array $wheres
+ * @param array $values
+ * @param array $wheres
+ *
* @return array
*/
public static function run(
@@ -62,7 +63,7 @@ public static function run(
/**
* Apply a single Laravel-style where condition to the query.
*
- * @param array{column: string, value: string} $where
+ * @param array{column: string, value: string} $where
*/
private static function applyWhere(Builder $query, array $where): void
{
diff --git a/src/Internal/BatchRuleShape.php b/src/Internal/BatchRuleShape.php
index c6af149..feb86aa 100644
--- a/src/Internal/BatchRuleShape.php
+++ b/src/Internal/BatchRuleShape.php
@@ -24,7 +24,7 @@ final class BatchRuleShape
* the whole shape, so the annotation stays honest about its one caller,
* even though only three of the keys are read.
*
- * @param array{connection: string|null, table: string, column: string, wheres: array, ignore: mixed, idColumn: string}|null $meta
+ * @param array{connection: string|null, table: string, column: string, wheres: array, ignore: mixed, idColumn: string}|null $meta
*/
public static function of(?array $meta): string
{
diff --git a/src/Internal/ConditionalEvaluationPhase.php b/src/Internal/ConditionalEvaluationPhase.php
index a4a2f09..088eccc 100644
--- a/src/Internal/ConditionalEvaluationPhase.php
+++ b/src/Internal/ConditionalEvaluationPhase.php
@@ -59,7 +59,8 @@ public static function resolveWildcard(string $attribute, string $conditionField
* rule shape. Accepts the Validator's untyped `$rules` array directly;
* non-string keys are filtered inside.
*
- * @param array $rules
+ * @param array $rules
+ *
* @return array}>>
*/
public function indexConditionalAttrs(array $rules): array
@@ -97,13 +98,13 @@ public function indexConditionalAttrs(array $rules): array
* because `Validator::getValue()` is protected — the closure must be
* constructed inside the validator subclass to capture scope.
*
- * @param list}> $tuples
- * @param Closure(string): mixed $getValue
- * @param array $rules The validator's parsed rules, read
- * only to learn whether a dependent
- * is declared `boolean`. Defaults to
- * none, which simply skips the
- * conversion.
+ * @param list}> $tuples
+ * @param Closure(string): mixed $getValue
+ * @param array $rules The validator's parsed rules, read
+ * only to learn whether a dependent
+ * is declared `boolean`. Defaults to
+ * none, which simply skips the
+ * conversion.
*/
public function evaluate(string $attribute, array $tuples, Closure $getValue, array $rules = []): ConditionalVerdict
{
diff --git a/src/Internal/ConditionalValueMatcher.php b/src/Internal/ConditionalValueMatcher.php
index 85845cc..45e179b 100644
--- a/src/Internal/ConditionalValueMatcher.php
+++ b/src/Internal/ConditionalValueMatcher.php
@@ -25,9 +25,9 @@ final class ConditionalValueMatcher
* Does the dependent at `$depPath` match `$rawValues` under Laravel's
* `validateRequiredIf`/`…Unless` comparison semantics?
*
- * @param list $rawValues The rule's value parameters.
- * @param array $itemData
- * @param array $itemRules Item-scoped rules, for the `boolean` declaration check.
+ * @param list $rawValues The rule's value parameters.
+ * @param array $itemData
+ * @param array $itemRules Item-scoped rules, for the `boolean` declaration check.
*/
public static function matches(string $depPath, array $rawValues, array $itemData, array $itemRules): bool
{
@@ -44,7 +44,7 @@ public static function matches(string $depPath, array $rawValues, array $itemDat
* through a validator's protected `getValue()`), so they don't re-resolve
* via `data_get`.
*
- * @param list $rawValues
+ * @param list $rawValues
*/
public static function matchesValue(mixed $other, array $rawValues, bool $dependentHasBooleanRule = false): bool
{
@@ -74,7 +74,7 @@ public static function matchesValue(mixed $other, array $rawValues, bool $depend
* `array-key`, not `string`: the top-level caller hands over the
* validator's own `$rules`, which Laravel types as a bare array.
*
- * @param array $itemRules
+ * @param array $itemRules
*/
public static function dependentHasBooleanRule(string $depPath, array $itemRules): bool
{
@@ -103,7 +103,7 @@ public static function dependentHasBooleanRule(string $depPath, array $itemRules
* - any other scalar compares by string coercion, covering numeric-string ↔
* numeric (`'1'` ↔ `1`).
*
- * @param list $values
+ * @param list $values
*/
private static function scalarLooseIn(int|float|string $other, array $values): bool
{
@@ -128,14 +128,15 @@ private static function scalarLooseIn(int|float|string $other, array $values): b
* value is already a bool; null conversion when the resolved value is
* null. Order matters — bool first, then null.
*
- * @param list $values
+ * @param list $values
+ *
* @return list
*/
private static function convertValues(array $values, mixed $other, bool $dependentHasBooleanRule): array
{
if (is_bool($other) || $dependentHasBooleanRule) {
$values = array_map(static fn (mixed $v): mixed => match ($v) {
- 'true' => true,
+ 'true' => true,
'false' => false,
default => $v,
}, $values);
diff --git a/src/Internal/DatabaseClaimScanner.php b/src/Internal/DatabaseClaimScanner.php
index 1fbd9ae..8d21d5b 100644
--- a/src/Internal/DatabaseClaimScanner.php
+++ b/src/Internal/DatabaseClaimScanner.php
@@ -33,7 +33,8 @@
final class DatabaseClaimScanner
{
/**
- * @param array $rules Field (or expanded attribute) → rules
+ * @param array $rules Field (or expanded attribute) → rules
+ *
* @return array
*/
public static function findPoisonedTableColumns(array $rules): array
@@ -114,9 +115,9 @@ private static function describeObjectClaim(string $field, Exists|Unique $rule,
$signature = BatchDatabaseChecker::isBatchable($rule)
? BatchDatabaseChecker::batchableSignature($rule, $table, $column)
- : 'unbatchable#'.$marker++;
+ : 'unbatchable#' . $marker++;
- return [$table.':'.$column, $signature];
+ return [$table . ':' . $column, $signature];
}
/** @return array{0: string, 1: string}|null */
@@ -141,7 +142,7 @@ private static function describeStringClaim(string $field, string $rule, int &$m
$column = self::leafAttribute($field);
}
- return [$table.':'.$column, 'string#'.$marker++];
+ return [$table . ':' . $column, 'string#' . $marker++];
}
/**
diff --git a/src/Internal/ExcludeConditionExtractor.php b/src/Internal/ExcludeConditionExtractor.php
index 3414f14..6f1b3d9 100644
--- a/src/Internal/ExcludeConditionExtractor.php
+++ b/src/Internal/ExcludeConditionExtractor.php
@@ -97,7 +97,8 @@ private static function parseSegment(mixed $segment): ?array
}
/**
- * @param array $segment
+ * @param array