Skip to content

Commit

Permalink
Introduce InArrayValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 committed Nov 18, 2022
1 parent 6a676c6 commit 5a38383
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 0 deletions.
139 changes: 139 additions & 0 deletions src/InArrayValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

namespace ipl\Validator;

use ipl\I18n\Translation;

/**
* Validate if specific single or multiple values exist in an array
*/
class InArrayValidator extends BaseValidator
{
use Translation;

/** @var array The array */
protected $haystack = [];

/** @var bool Whether the types of the needle in the haystack should also match */
protected $strict = false;

/**
* Create a new InArray validator
*
* **Optional options:**
*
* * `haystack`: (`array`) The array
* * `strict`: (`bool`) Whether the types of the needle in the haystack should also match, default `false`
*
* @param array $options
*/
public function __construct(array $options = [])
{
if (isset($options['haystack'])) {
$this->setHaystack($options['haystack']);
}

$this->setStrict($options['strict'] ?? false);
}

/**
* Get the haystack
*
* @return array
*/
public function getHaystack(): array
{
return $this->haystack;
}

/**
* Set the haystack
*
* @param array $haystack
*
* @return $this
*/
public function setHaystack(array $haystack): self
{
$this->haystack = $haystack;

return $this;
}

/**
* Whether the types of the needle in the haystack should also match
*
* @return bool
*/
public function isStrict(): bool
{
return $this->strict;
}

/**
* Set whether the types of the needle in the haystack should also match
*
* @param bool $strict
*
* @return $this
*/
public function setStrict(bool $strict = true): self
{
$this->strict = $strict;

return $this;
}

public function isValid($value)
{
// Multiple isValid() calls must not stack validation messages
$this->clearMessages();

$notInArray = array_udiff(
(array) $value,
$this->getHaystack(),
$this->isStrict() ? [$this, 'strictEqual'] : [$this, 'looseEqual']
);

if (empty($notInArray)) {
return true;
}

$this->addMessage(sprintf(
$this->translatePlural(
"%s was not found in the haystack",
"%s were not found in the haystack",
count($notInArray)
),
implode(', ', $notInArray)
));

return false;
}

/**
* Loosely compare the given values
*
* @param $a mixed Value to compare
* @param $b mixed value to compare with
*
* @return int 0 if given values are equal, 99 otherwise
*/
private function looseEqual($a, $b): int
{
return $a == $b ? 0 : 99;
}

/**
* Strictly compare the given values
*
* @param $a mixed Value to compare
* @param $b mixed value to compare with
*
* @return int 0 if given values are equal, 99 otherwise
*/
private function strictEqual($a, $b): int
{
return $a === $b ? 0 : 99;
}
}
92 changes: 92 additions & 0 deletions tests/InArrayValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace ipl\Tests\Validator;

use ipl\I18n\NoopTranslator;
use ipl\I18n\StaticTranslator;
use ipl\Validator\InArrayValidator;

class InArrayValidatorTest extends TestCase
{
public function testWithValidValue()
{
StaticTranslator::$instance = new NoopTranslator();

$validator = new InArrayValidator([
'haystack' => ['test', 'foo', 'bar', 5, [], 0.008]
]);

$this->assertTrue($validator->isValid('foo'), 'foo was not found in the haystack');
$this->assertTrue($validator->isValid(5), '5 was not found in the haystack');
$this->assertTrue($validator->isValid(0.008), '00.8 was not found in the haystack');
$this->assertTrue($validator->isValid([]), '[] (empty array) was not found in the haystack');
}

public function testWithInvalidValue()
{
StaticTranslator::$instance = new NoopTranslator();

$validator = new InArrayValidator([
'haystack' => ['test', 'foo', 'bar', 5, [], 0.008]
]);

$this->assertFalse($validator->isValid('bear'), 'bear was found in the haystack');
$this->assertFalse($validator->isValid(60), '60 was found in the haystack');
$this->assertFalse($validator->isValid(0.09), '0.09 was found in the haystack');
}

public function testWithStrictOption()
{
StaticTranslator::$instance = new NoopTranslator();

$validator = new InArrayValidator([
'haystack' => ['test', 'foo', 'bar', 5, [], 0.008, '295'],
'strict' => true
]);

$this->assertTrue($validator->isValid('295'), '"295" was not found in the haystack');
$this->assertFalse($validator->isValid(295), '295 (int) was found in the haystack');
$this->assertFalse($validator->isValid('0.008'), '"0.008" was not found in the haystack');
}

public function testWithArrayAsValue()
{
StaticTranslator::$instance = new NoopTranslator();

$validator = new InArrayValidator([
'haystack' => ['test', 'foo', 'bar', 5, 0.008, '295'],
]);

$this->assertFalse(
$validator->isValid(['car', 'cat', 55]),
'"car", "cat", 55 were found in the haystack'
);

$this->assertSame(['car, cat, 55 were not found in the haystack'], $validator->getMessages());

$this->assertTrue(
$validator->isValid(['test', '295', 0.008]),
'"test", "295", 0.008 were not found in the haystack'
);
}

public function testOptions()
{
StaticTranslator::$instance = new NoopTranslator();

$validator = new InArrayValidator([
'haystack' => ['test', 'foo', 'bar', 5, [], 0.008],
'strict' => true
]);

$this->assertTrue($validator->isStrict());

$validator->setStrict(false);
$this->assertFalse($validator->isStrict());

$this->assertSame(['test', 'foo', 'bar', 5, [], 0.008], $validator->getHaystack());

$validator->setHaystack([]);
$this->assertSame([], $validator->getHaystack());
}
}

0 comments on commit 5a38383

Please sign in to comment.