Skip to content

Commit

Permalink
[11.x] Introduce method Rule::array() (laravel#51250)
Browse files Browse the repository at this point in the history
* [11.x] Introduce method `Rule::array()`

* CS fixes

* Add `func_get_args` test

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
Jacobs63 and taylorotwell authored May 3, 2024
1 parent 8f9cba8 commit 8c684a2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/Illuminate/Validation/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Validation\Rules\ArrayRule;
use Illuminate\Validation\Rules\Can;
use Illuminate\Validation\Rules\Dimensions;
use Illuminate\Validation\Rules\Enum;
Expand Down Expand Up @@ -59,6 +60,17 @@ public static function unless($condition, $rules, $defaultRules = [])
return new ConditionalRules($condition, $defaultRules, $rules);
}

/**
* Get an array rule builder instance.
*
* @param array|null $keys
* @return \Illuminate\Validation\ArrayRule
*/
public static function array($keys = null)
{
return new ArrayRule(...func_get_args());
}

/**
* Create a new nested rule set.
*
Expand Down Expand Up @@ -95,7 +107,7 @@ public static function exists($table, $column = 'NULL')
}

/**
* Get an in constraint builder instance.
* Get an in rule builder instance.
*
* @param \Illuminate\Contracts\Support\Arrayable|\BackedEnum|\UnitEnum|array|string $values
* @return \Illuminate\Validation\Rules\In
Expand All @@ -110,7 +122,7 @@ public static function in($values)
}

/**
* Get a not_in constraint builder instance.
* Get a not_in rule builder instance.
*
* @param \Illuminate\Contracts\Support\Arrayable|\BackedEnum|\UnitEnum|array|string $values
* @return \Illuminate\Validation\Rules\NotIn
Expand All @@ -125,7 +137,7 @@ public static function notIn($values)
}

/**
* Get a required_if constraint builder instance.
* Get a required_if rule builder instance.
*
* @param callable|bool $callback
* @return \Illuminate\Validation\Rules\RequiredIf
Expand All @@ -136,7 +148,7 @@ public static function requiredIf($callback)
}

/**
* Get a exclude_if constraint builder instance.
* Get a exclude_if rule builder instance.
*
* @param callable|bool $callback
* @return \Illuminate\Validation\Rules\ExcludeIf
Expand All @@ -147,7 +159,7 @@ public static function excludeIf($callback)
}

/**
* Get a prohibited_if constraint builder instance.
* Get a prohibited_if rule builder instance.
*
* @param callable|bool $callback
* @return \Illuminate\Validation\Rules\ProhibitedIf
Expand All @@ -158,7 +170,7 @@ public static function prohibitedIf($callback)
}

/**
* Get an enum constraint builder instance.
* Get an enum rule builder instance.
*
* @param class-string $type
* @return \Illuminate\Validation\Rules\Enum
Expand All @@ -169,7 +181,7 @@ public static function enum($type)
}

/**
* Get a file constraint builder instance.
* Get a file rule builder instance.
*
* @return \Illuminate\Validation\Rules\File
*/
Expand All @@ -179,7 +191,7 @@ public static function file()
}

/**
* Get an image file constraint builder instance.
* Get an image file rule builder instance.
*
* @return \Illuminate\Validation\Rules\ImageFile
*/
Expand All @@ -189,7 +201,7 @@ public static function imageFile()
}

/**
* Get a dimensions constraint builder instance.
* Get a dimensions rule builder instance.
*
* @param array $constraints
* @return \Illuminate\Validation\Rules\Dimensions
Expand Down
56 changes: 56 additions & 0 deletions src/Illuminate/Validation/Rules/ArrayRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Illuminate\Validation\Rules;

use BackedEnum;
use Illuminate\Contracts\Support\Arrayable;
use Stringable;
use UnitEnum;

class ArrayRule implements Stringable
{
/**
* The accepted keys.
*
* @var array
*/
protected $keys;

/**
* Create a new array rule instance.
*
* @param array|null $keys
* @return void
*/
public function __construct($keys = null)
{
if ($keys instanceof Arrayable) {
$keys = $keys->toArray();
}

$this->keys = is_array($keys) ? $keys : func_get_args();
}

/**
* Convert the rule to a validation string.
*
* @return string
*/
public function __toString()
{
if (empty($this->keys)) {
return 'array';
}

$keys = array_map(
static fn ($key) => match (true) {
$key instanceof BackedEnum => $key->value,
$key instanceof UnitEnum => $key->name,
default => $key,
},
$this->keys,
);

return 'array:'.implode(',', $keys);
}
}
14 changes: 14 additions & 0 deletions tests/Validation/Enums.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,17 @@ enum PureEnum
case one;
case two;
}

enum ArrayKeys
{
case key_1;
case key_2;
case key_3;
}

enum ArrayKeysBacked: string
{
case key_1 = 'key_1';
case key_2 = 'key_2';
case key_3 = 'key_3';
}
38 changes: 38 additions & 0 deletions tests/Validation/ValidationArrayRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Illuminate\Tests\Validation;

use Illuminate\Validation\Rule;
use PHPUnit\Framework\TestCase;

include_once 'Enums.php';

class ValidationArrayRuleTest extends TestCase
{
public function testItCorrectlyFormatsAStringVersionOfTheRule()
{
$rule = Rule::array();

$this->assertSame('array', (string) $rule);

$rule = Rule::array('key_1', 'key_2', 'key_3');

$this->assertSame('array:key_1,key_2,key_3', (string) $rule);

$rule = Rule::array(['key_1', 'key_2', 'key_3']);

$this->assertSame('array:key_1,key_2,key_3', (string) $rule);

$rule = Rule::array(collect(['key_1', 'key_2', 'key_3']));

$this->assertSame('array:key_1,key_2,key_3', (string) $rule);

$rule = Rule::array([ArrayKeys::key_1, ArrayKeys::key_2, ArrayKeys::key_3]);

$this->assertSame('array:key_1,key_2,key_3', (string) $rule);

$rule = Rule::array([ArrayKeysBacked::key_1, ArrayKeysBacked::key_2, ArrayKeysBacked::key_3]);

$this->assertSame('array:key_1,key_2,key_3', (string) $rule);
}
}

0 comments on commit 8c684a2

Please sign in to comment.