Skip to content

Commit

Permalink
Introduce InArrayValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 committed Nov 22, 2022
1 parent 6a676c6 commit 738dd8e
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 0 deletions.
137 changes: 137 additions & 0 deletions src/InArrayValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?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 = $this->findInvalid((array) $value);

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;
}

/**
* Return the values that are not present in the haystack
*
* **Example usage:**
*
* ```
* (new InArrayValidator())
* ->setHaystack(['a', 'b', 'c', '295'])
* ->setStrict()
* ->findInvalid(['a', 'o', 295]); // Returns ['o', 295]
* ```
*
* @param array $values
*
* @return array Values that was not found in the haystack
*/
public function findInvalid(array $values = []): array
{
$notInArray = [];
foreach ($values as $val) {
if (! in_array($val, $this->getHaystack(), $this->isStrict())) {
$notInArray[] = $val;
}
}

return $notInArray;
}
}
104 changes: 104 additions & 0 deletions tests/InArrayValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace ipl\Tests\Validator;

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

class InArrayValidatorTest extends TestCase
{
public function testValidValues()
{
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 testInvalidValues()
{
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 testStrictOption()
{
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 testArrayAsValue()
{
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());
}

public function testMethodFindInvalid()
{
StaticTranslator::$instance = new NoopTranslator();
$validator = (new InArrayValidator())
->setHaystack(['a', 'b', 'c']);

$this->assertSame([], $validator->findInvalid(['a', 'b', 'c']));
$this->assertSame([''], $validator->findInvalid(['a', 'b', 'c', '']));
$this->assertSame(['d'], $validator->findInvalid(['a', 'd']));
$this->assertSame([55, 'foo'], $validator->findInvalid([55, 'foo']));
}
}

0 comments on commit 738dd8e

Please sign in to comment.