Skip to content

Add rules : prohibited_with, prohibited_with_all, prohibited_without, prohibited_without_all + Modify rules In + NotIn to manage array values #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ protected function registerDefaultRules(): void
'prohibited' => new Rules\Prohibited,
'prohibited_if' => new Rules\ProhibitedIf,
'prohibited_unless' => new Rules\ProhibitedUnless,
'prohibited_with' => new Rules\ProhibitedWith,
'prohibited_with_all' => new Rules\ProhibitedWithAll,
'prohibited_without' => new Rules\ProhibitedWithout,
'prohibited_without_all' => new Rules\ProhibitedWithoutAll,
'regex' => new Rules\Regex,
'rejected' => new Rules\Rejected,
'required' => new Rules\Required,
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/i18n/de.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
'rule.prohibited' => ':attribute ist nicht erlaubt',
'rule.prohibited_if' => ':attribute ist nicht erlaubt, wenn :field einen der folgenden Werte entspricht: :values',
'rule.prohibited_unless' => ':attribute ist nicht erlaubt, wenn :field nicht einem der folgenden Werte entspricht: :values',
// 'rule.prohibited_with' => ':attribute ist nicht erlaubt mit: :fields',
// 'rule.prohibited_with_all' => ':attribute ist nicht mit allen :fields erlaubt',
// 'rule.prohibited_without' => ':attribute ist verboten, wenn alle der folgenden Felder vorhanden sind: :fields',
// 'rule.prohibited_without_all' => ' :attribute ist verboten, wenn eines der folgenden Felder nicht vorhanden ist: :fields',
'rule.regex' => ':attribute entspricht nicht dem erwarteten Format',
'rule.rejected' => ':attribute muss einen der folgenden Werte enthalten: :rejected',
'rule.required' => ':attribute ist erforderlich',
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/i18n/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
'rule.prohibited' => ':attribute is not allowed',
'rule.prohibited_if' => ':attribute is not allowed if :field has value(s) :values',
'rule.prohibited_unless' => ':attribute is not allowed if :field does not have value(s) :values',
'rule.prohibited_with' => ':attribute is not allowed with :fields',
'rule.prohibited_with_all' => ':attribute is not allowed with all of :fields',
'rule.prohibited_without' => ':attribute is not allowed when one of the following fields is absent: :fields',
'rule.prohibited_without_all' => ':attribute is not allowed when all of the following fields are absents: :fields',
'rule.regex' => ':attribute does not meet required format',
'rule.rejected' => ':attribute must be one of: :rejected',
'rule.required' => ':attribute is required',
Expand Down
6 changes: 5 additions & 1 deletion src/Resources/i18n/fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@
'rule.prohibited' => 'Le champ :attribute est interdit.',
'rule.prohibited_if' => 'Le champ :attribute est interdit quand :field a la/les valeur(s) :values',
'rule.prohibited_unless' => 'Le champ :attribute est interdit à moins que :field est l\'une des valeurs :values',
'rule.prohibited_with' => 'Le champ :attribute est interdit l\'un des champs suivants est présent : {fields}.',
'rule.prohibited_with_all' => 'Le champ :attribute est interdit quand tous les champs suivants sont présents : :fields.',
'rule.prohibited_without' => 'Le champ :attribute est interdit quand l\'un des champs suivants est absent : :fields.',
'rule.prohibited_without_all' => 'Le champ :attribute est interdit quand tous les champs suivants sont absents : :fields.',
'rule.regex' => 'Le format du champ :attribute est invalide.',
'rule.rejected' => 'Le champ :attribute doit être parmi: :rejected',
'rule.required' => 'Le champ :attribute est obligatoire.',
'rule.required_if' => 'Le champ :attribute est obligatoire quand la valeur de :field est :values.',
'rule.required_unless' => 'Le champ :attribute est obligatoire sauf si :fields est :values.',
'rule.required_with' => 'Le champ :attribute est obligatoire quand :fields est présent.',
'rule.required_with' => 'Le champ :attribute est obligatoire quand l\'un des champs suivants est présent: :fields.',
'rule.required_with_all' => 'Le champ :attribute est obligatoire quand :fields sont présents.',
'rule.required_without' => 'Le champ :attribute est obligatoire quand :fields n\'est pas présent.',
'rule.required_without_all' => 'Le champ :attribute est requis quand aucun de :fields n\'est présent.',
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/i18n/tr.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
'rule.prohibited' => ':attribute izin verilmez',
'rule.prohibited_if' => ':attribute izin verilmez eğer :field değeri :values ise',
'rule.prohibited_unless' => ':attribute izin verilmez eğer :field değeri :values içermiyorsa',
// 'rule.prohibited_with' => ':attribute :fields ile izin verilmez',
// 'rule.prohibited_with_all' => ':attribute :fields\'ın tümü ile izin verilmez',
// 'rule.prohibited_with_all' => 'Aşağıdaki tüm alanlar mevcut olduğunda :attribute alanı yasaktır: :fields',
// 'rule.prohibited_with_all' => 'Aşağıdaki alanların tümü olmadığında :attribute alanı yasaktır: :fields',
'rule.regex' => ':attribute gerekli formata uymaz',
'rule.rejected' => ':attribute şunlardan biri olmalıdır: :rejected',
'rule.required' => ':attribute zorunludur',
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/i18n/zh.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
'rule.prohibited' => ':attribute 禁止使用',
'rule.prohibited_if' => '如果 :field 字段存在以下值::values,:attribute 禁止使用',
'rule.prohibited_unless' => '如果 :field 字段不存在以下值::values,:attribute 禁止使用',
// 'rule.prohibited_with' => '如果存在下列欄位之一,則禁止使用 :attribute 欄位:{fields}.',
// 'rule.prohibited_with_all' => '當以下所有欄位都存在時,禁止使用 :attribute 欄位 : :fields.',
// 'rule.prohibited_without' => '當下列欄位之一不存在時,禁止使用 :attribute 欄位 : :fields.',
// 'rule.prohibited_without_all' => '當以下所有欄位都不存在時,禁止使用 :attribute 欄位 : :fields.',
'rule.regex' => ':attribute 格式不正确',
'rule.rejected' => ':attribute 必须是以下值: :rejected',
'rule.required' => ':attribute 必须存在',
Expand Down
10 changes: 10 additions & 0 deletions src/Rules/In.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ public function check(mixed $value): bool
{
$this->assertHasRequiredParameters(['allowed_values']);

if (is_array($value)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is "AnyOf" that allows for validating an array of values are each within an array of allowed values. I am not sure how I feel about combining "In" to do both. I checked Laravels code and see that it does allow this, though "AnyOf" allows a string of delineated values as well.

foreach ($value as $v) {
if (!in_array($v, $this->parameter('allowed_values'), $this->strict)) {
return false;
}
}

return true;
}

return in_array($value, $this->parameter('allowed_values'), $this->strict);
}
}
10 changes: 10 additions & 0 deletions src/Rules/NotIn.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public function check(mixed $value): bool
{
$this->assertHasRequiredParameters(['disallowed_values']);

if (is_array($value)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the comments from In, I am not sure about combining this into the NotIn rule.

foreach ($value as $v) {
if (in_array($v, (array)$this->parameter('disallowed_values'), $this->strict)) {
return false;
}
}

return true;
}

return !in_array($value, (array)$this->parameter('disallowed_values'), $this->strict);
}
}
44 changes: 44 additions & 0 deletions src/Rules/ProhibitedWith.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types=1);

namespace Somnambulist\Components\Validation\Rules;

use Somnambulist\Components\Validation\Rules\Behaviours\CanConvertFieldParametersDotNotationToResolvedStrings;

/**
* Based on Laravel validators required_with but here the field must be missing or empty if
* any of the other specified fields are present and not empty.
*/
class ProhibitedWith extends Prohibited
{
use CanConvertFieldParametersDotNotationToResolvedStrings;

protected bool $implicit = true;
protected string $message = 'rule.prohibited_with';

public function fillParameters(array $params): self
{
$this->params['fields'] = $params;

return $this;
}

public function check(mixed $value): bool
{
$this->assertHasRequiredParameters(['fields']);

$fields = $this->parameter('fields');
$requiredValidator = $this->validation->factory()->rule('required');

if (!$requiredValidator->check($this->attribute()->value())) {
return true;
}

foreach ($fields as $field) {
if ($requiredValidator->check($this->attribute->value($field))) {
return false;
}
}

return $requiredValidator->check($value);
}
}
47 changes: 47 additions & 0 deletions src/Rules/ProhibitedWithAll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types=1);

namespace Somnambulist\Components\Validation\Rules;

use Somnambulist\Components\Validation\Rules\Behaviours\CanConvertFieldParametersDotNotationToResolvedStrings;

/**
* Based on Laravel validators required_with_all but here the fields must be missing or empty if
* all the other specified fields are present and not empty.
*/
class ProhibitedWithAll extends Prohibited
{
use CanConvertFieldParametersDotNotationToResolvedStrings;

protected bool $implicit = true;
protected string $message = 'rule.prohibited_with_all';

public function fillParameters(array $params): self
{
$this->params['fields'] = $params;

return $this;
}

public function check(mixed $value): bool
{
$this->assertHasRequiredParameters(['fields']);

$fields = $this->parameter('fields');
$requiredValidator = $this->validation->factory()->rule('required');

if (!$requiredValidator->check($this->attribute->value())) {
return true;
}

$fieldsHaveValues = true;
foreach ($fields as $field) {
$fieldsHaveValues = $fieldsHaveValues && $requiredValidator->check($this->attribute->value($field));
}

if (!$fieldsHaveValues) {
return true;
}

return false;
}
}
43 changes: 43 additions & 0 deletions src/Rules/ProhibitedWithout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types=1);

namespace Somnambulist\Components\Validation\Rules;

use Somnambulist\Components\Validation\Rules\Behaviours\CanConvertFieldParametersDotNotationToResolvedStrings;

/**
* Based on Laravel validators required_with but here the field must be missing or empty if
* any of the other specified fields are present and not empty.
*/
class ProhibitedWithout extends Prohibited
{
use CanConvertFieldParametersDotNotationToResolvedStrings;

protected string $message = 'rule.prohibited_without';
protected bool $implicit = true;

public function fillParameters(array $params): self
{
$this->params['fields'] = $params;

return $this;
}

public function check(mixed $value): bool
{
$this->assertHasRequiredParameters(['fields']);

$fields = $this->parameter('fields');
$requiredValidator = $this->validation->factory()->rule('required');

$fieldsHaveValues = true;
foreach ($fields as $field) {
$fieldsHaveValues = $fieldsHaveValues && $requiredValidator->check($this->attribute->value($field));
}

if (!$fieldsHaveValues) {
return false;
}

return $requiredValidator->check($value);
}
}
51 changes: 51 additions & 0 deletions src/Rules/ProhibitedWithoutAll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types=1);

namespace Somnambulist\Components\Validation\Rules;

use Somnambulist\Components\Validation\Rules\Behaviours\CanConvertFieldParametersDotNotationToResolvedStrings;

/**
* Based on Laravel validators required_with but here the field must be missing or empty if
* any of the other specified fields are present and not empty.
*/
class ProhibitedWithoutAll extends Prohibited
{
use CanConvertFieldParametersDotNotationToResolvedStrings;

protected string $message = 'rule.prohibited_without_all';
protected bool $implicit = true;

public function fillParameters(array $params): self
{
$this->params['fields'] = $params;

return $this;
}

public function check(mixed $value): bool
{
if (!isset($value)) {
return true;
}

$this->assertHasRequiredParameters(['fields']);

$fields = $this->parameter('fields');
$requiredValidator = $this->validation->factory()->rule('required');

if (!$requiredValidator->check($value)) {
return true;
}

$fieldsHaveValues = false;
foreach ($fields as $field) {
$fieldsHaveValues = $fieldsHaveValues || $requiredValidator->check($this->attribute->value($field));
}

if ($fieldsHaveValues) {
return true;
}

return false;
}
}
5 changes: 4 additions & 1 deletion tests/Rules/InTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,26 @@ public function testValids()
{
$this->assertTrue($this->rule->fillParameters([1,2,3])->check(1));
$this->assertTrue($this->rule->fillParameters(['1', 'bar', '3'])->check('bar'));
$this->assertTrue($this->rule->fillParameters(['1', 'bar', '3'])->check(['bar', '3']));
}

public function testInvalids()
{
$this->assertFalse($this->rule->fillParameters([1,2,3])->check(4));
$this->assertFalse($this->rule->fillParameters([1,2,3])->check([3,4]));
}

public function testStricts()
{
// Not strict
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check(true));
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check([true, 3]));

// Strict
$this->rule->strict();
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check([1,3]));
}

public function testWithCommasInStrings()
Expand Down
5 changes: 4 additions & 1 deletion tests/Rules/NotInTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ public function testValids()
{
$this->assertTrue($this->rule->fillParameters(['2', '3', '4'])->check('1'));
$this->assertTrue($this->rule->fillParameters([1, 2, 3])->check(5));
$this->assertTrue($this->rule->fillParameters([1, 2, 3])->check([5,10]));
}

public function testInvalids()
{
$this->assertFalse($this->rule->fillParameters(['bar', 'baz', 'qux'])->check('bar'));
$this->assertFalse($this->rule->fillParameters(['bar', 'baz', 'qux'])->check(['bar','foo']));
}

public function testStricts()
{
// Not strict
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check(true));
$this->assertFalse($this->rule->fillParameters(['1', '2', '3'])->check([true, 3, 9]));

// Strict
$this->rule->strict();
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check(1));
$this->assertTrue($this->rule->fillParameters(['1', '2', '3'])->check([1,3]));
}
}
Loading