Skip to content

Commit c65b1fb

Browse files
authored
Fix #181: Fix incomplete rule options (#215)
1 parent 97a4be7 commit c65b1fb

13 files changed

Lines changed: 135 additions & 6 deletions

src/Rule/AtLeast.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111
use Yiisoft\Validator\ValidationContext;
1212

1313
/**
14-
* Checks if at least {@see AtLeast::$min} of many attributes are filled.
14+
* Checks if at least {@see AtLeast::$min} of many object attributes are filled.
1515
*/
1616
#[Attribute(Attribute::TARGET_PROPERTY)]
1717
final class AtLeast extends Rule
1818
{
1919
public function __construct(
2020
/**
21-
* The list of required attributes that will be checked.
21+
* @var string[] The list of required attributes that will be checked.
2222
*/
2323
private array $attributes,
2424
/**
25-
* The minimum required quantity of filled attributes to pass the validation.
25+
* @var int The minimum required quantity of filled attributes to pass the validation.
2626
* Defaults to 1.
2727
*/
2828
private int $min = 1,
2929
/**
30-
* Message to display in case of error.
30+
* @var string Message to display in case of error.
3131
*/
3232
private string $message = 'The model is not valid. Must have at least "{min}" filled attributes.',
3333
?FormatterInterface $formatter = null,
@@ -51,18 +51,24 @@ protected function validateValue($value, ?ValidationContext $context = null): Re
5151
$result = new Result();
5252

5353
if ($filledCount < $this->min) {
54-
$message = $this->formatMessage($this->message, ['min' => $this->min]);
54+
$message = $this->getFormattedMessage();
5555
$result->addError($message);
5656
}
5757

5858
return $result;
5959
}
6060

61+
private function getFormattedMessage(): string
62+
{
63+
return $this->formatMessage($this->message, ['min' => $this->min]);
64+
}
65+
6166
public function getOptions(): array
6267
{
6368
return array_merge(parent::getOptions(), [
69+
'attributes' => $this->attributes,
6470
'min' => $this->min,
65-
'message' => $this->formatMessage($this->message, ['min' => $this->min]),
71+
'message' => $this->getFormattedMessage(),
6672
]);
6773
}
6874
}

src/Rule/Each.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Yiisoft\Validator\Rule;
1212
use Yiisoft\Validator\RuleSet;
1313
use Yiisoft\Validator\ValidationContext;
14+
use function is_array;
15+
use function is_iterable;
1416

1517
/**
1618
* Validates an array by checking each of its elements against a set of rules.

src/Rule/Email.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ private function idnToAscii($idn)
142142
public function getOptions(): array
143143
{
144144
return array_merge(parent::getOptions(), [
145+
'pattern' => $this->pattern,
146+
'fullPattern' => $this->fullPattern,
147+
'idnEmailPattern' => $this->idnEmailPattern,
145148
'allowName' => $this->allowName,
146149
'checkDNS' => $this->checkDNS,
147150
'enableIDN' => $this->enableIDN,

src/Rule/Ip.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ public function getIpParsePattern(): string
363363
public function getOptions(): array
364364
{
365365
return array_merge(parent::getOptions(), [
366+
'networks' => $this->networks,
366367
'allowIpv4' => $this->allowIpv4,
367368
'allowIpv6' => $this->allowIpv6,
368369
'allowSubnet' => $this->allowSubnet,

src/Rule/Number.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public function getOptions(): array
102102
'notANumberMessage' => $this->formatMessage($this->getNotANumberMessage()),
103103
'tooSmallMessage' => $this->formatMessage($this->tooSmallMessage, ['min' => $this->min]),
104104
'tooBigMessage' => $this->formatMessage($this->tooBigMessage, ['max' => $this->max]),
105+
'integerPattern' => $this->integerPattern,
106+
'numberPattern' => $this->numberPattern,
105107
]);
106108
}
107109
}

src/Rule/Subset.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Yiisoft\Validator\Result;
1111
use Yiisoft\Validator\Rule;
1212
use Yiisoft\Validator\ValidationContext;
13+
use function is_array;
1314

1415
#[Attribute(Attribute::TARGET_PROPERTY)]
1516
final class Subset extends Rule

tests/Rule/AtLeastTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function getOptionsProvider(): array
8282
[
8383
new AtLeast(['attr1', 'attr2']),
8484
[
85+
'attributes' => ['attr1', 'attr2'],
8586
'min' => 1,
8687
'message' => 'The model is not valid. Must have at least "1" filled attributes.',
8788
'skipOnEmpty' => false,
@@ -91,6 +92,7 @@ public function getOptionsProvider(): array
9192
[
9293
new AtLeast(['attr1', 'attr2'], min: 2),
9394
[
95+
'attributes' => ['attr1', 'attr2'],
9496
'min' => 2,
9597
'message' => 'The model is not valid. Must have at least "2" filled attributes.',
9698
'skipOnEmpty' => false,

tests/Rule/EachTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public function testGetOptions(): void
4242
'tooBigMessage' => 'Value must be no greater than 13.',
4343
'skipOnEmpty' => false,
4444
'skipOnError' => false,
45+
'integerPattern' => '/^\s*[+-]?\d+\s*$/',
46+
'numberPattern' => '/^\s*[-+]?\d*\.?\d+([eE][-+]?\d+)?\s*$/',
4547
],
4648
[
4749
'number',
@@ -53,6 +55,8 @@ public function testGetOptions(): void
5355
'tooBigMessage' => 'Value must be no greater than 14.',
5456
'skipOnEmpty' => false,
5557
'skipOnError' => false,
58+
'integerPattern' => '/^\s*[+-]?\d+\s*$/',
59+
'numberPattern' => '/^\s*[-+]?\d*\.?\d+([eE][-+]?\d+)?\s*$/',
5660
],
5761
];
5862

tests/Rule/EmailTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ public function getOptionsProvider(): array
232232
'message' => 'This value is not a valid email address.',
233233
'skipOnEmpty' => false,
234234
'skipOnError' => false,
235+
'pattern' => "/^[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/",
236+
'fullPattern' => "/^[^@]*<[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/",
237+
'idnEmailPattern' => '/^([a-zA-Z0-9._%+-]+)@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|\d{1,3})(\]?)$/',
235238
],
236239
],
237240
[
@@ -243,6 +246,9 @@ public function getOptionsProvider(): array
243246
'message' => 'This value is not a valid email address.',
244247
'skipOnEmpty' => false,
245248
'skipOnError' => false,
249+
'pattern' => "/^[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/",
250+
'fullPattern' => "/^[^@]*<[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/",
251+
'idnEmailPattern' => '/^([a-zA-Z0-9._%+-]+)@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|\d{1,3})(\]?)$/',
246252
],
247253
],
248254
[
@@ -254,6 +260,9 @@ public function getOptionsProvider(): array
254260
'message' => 'This value is not a valid email address.',
255261
'skipOnEmpty' => false,
256262
'skipOnError' => false,
263+
'pattern' => "/^[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/",
264+
'fullPattern' => "/^[^@]*<[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/",
265+
'idnEmailPattern' => '/^([a-zA-Z0-9._%+-]+)@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|\d{1,3})(\]?)$/',
257266
],
258267
],
259268
[
@@ -265,6 +274,9 @@ public function getOptionsProvider(): array
265274
'message' => 'This value is not a valid email address.',
266275
'skipOnEmpty' => false,
267276
'skipOnError' => false,
277+
'pattern' => "/^[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/",
278+
'fullPattern' => "/^[^@]*<[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/",
279+
'idnEmailPattern' => '/^([a-zA-Z0-9._%+-]+)@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|\d{1,3})(\]?)$/',
268280
],
269281
],
270282
];

tests/Rule/IpTest.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,16 @@ public function getOptionsProvider(): array
403403
[
404404
new Ip(),
405405
[
406+
'networks' => [
407+
'*' => ['any'],
408+
'any' => ['0.0.0.0/0', '::/0'],
409+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
410+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
411+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
412+
'localhost' => ['127.0.0.0/8', '::1'],
413+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
414+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
415+
],
406416
'allowIpv4' => true,
407417
'allowIpv6' => true,
408418
'allowSubnet' => false,
@@ -423,6 +433,16 @@ public function getOptionsProvider(): array
423433
[
424434
new Ip(allowIpv4: false),
425435
[
436+
'networks' => [
437+
'*' => ['any'],
438+
'any' => ['0.0.0.0/0', '::/0'],
439+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
440+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
441+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
442+
'localhost' => ['127.0.0.0/8', '::1'],
443+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
444+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
445+
],
426446
'allowIpv4' => false,
427447
'allowIpv6' => true,
428448
'allowSubnet' => false,
@@ -443,6 +463,16 @@ public function getOptionsProvider(): array
443463
[
444464
new Ip(allowIpv6: false),
445465
[
466+
'networks' => [
467+
'*' => ['any'],
468+
'any' => ['0.0.0.0/0', '::/0'],
469+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
470+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
471+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
472+
'localhost' => ['127.0.0.0/8', '::1'],
473+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
474+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
475+
],
446476
'allowIpv4' => true,
447477
'allowIpv6' => false,
448478
'allowSubnet' => false,
@@ -463,6 +493,16 @@ public function getOptionsProvider(): array
463493
[
464494
new Ip(allowSubnet: true),
465495
[
496+
'networks' => [
497+
'*' => ['any'],
498+
'any' => ['0.0.0.0/0', '::/0'],
499+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
500+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
501+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
502+
'localhost' => ['127.0.0.0/8', '::1'],
503+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
504+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
505+
],
466506
'allowIpv4' => true,
467507
'allowIpv6' => true,
468508
'allowSubnet' => true,
@@ -483,6 +523,16 @@ public function getOptionsProvider(): array
483523
[
484524
new Ip(requireSubnet: true),
485525
[
526+
'networks' => [
527+
'*' => ['any'],
528+
'any' => ['0.0.0.0/0', '::/0'],
529+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
530+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
531+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
532+
'localhost' => ['127.0.0.0/8', '::1'],
533+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
534+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
535+
],
486536
'allowIpv4' => true,
487537
'allowIpv6' => true,
488538
'allowSubnet' => true,
@@ -503,6 +553,16 @@ public function getOptionsProvider(): array
503553
[
504554
new Ip(allowNegation: true),
505555
[
556+
'networks' => [
557+
'*' => ['any'],
558+
'any' => ['0.0.0.0/0', '::/0'],
559+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
560+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
561+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
562+
'localhost' => ['127.0.0.0/8', '::1'],
563+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
564+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
565+
],
506566
'allowIpv4' => true,
507567
'allowIpv6' => true,
508568
'allowSubnet' => false,
@@ -523,6 +583,16 @@ public function getOptionsProvider(): array
523583
[
524584
new Ip(ranges: ['private']),
525585
[
586+
'networks' => [
587+
'*' => ['any'],
588+
'any' => ['0.0.0.0/0', '::/0'],
589+
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
590+
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
591+
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
592+
'localhost' => ['127.0.0.0/8', '::1'],
593+
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
594+
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
595+
],
526596
'allowIpv4' => true,
527597
'allowIpv6' => true,
528598
'allowSubnet' => false,

0 commit comments

Comments
 (0)