Skip to content

Commit 4664c0d

Browse files
authored
Merge pull request #430 from adambalint-srg/validator-chain-interface
Create and implement `ValidatorChainInterface` in final class `ValidatorChain`
2 parents 24238b1 + cfb4126 commit 4664c0d

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

src/Conditional.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ final class Conditional implements ValidatorInterface
2020
{
2121
/** @var Closure(array<string, mixed>): bool */
2222
private readonly Closure $rule;
23-
private readonly ValidatorChain $chain;
23+
private readonly ValidatorChainInterface $chain;
2424

2525
/** @param OptionsArgument $options */
2626
public function __construct(ValidatorChainFactory $chainFactory, array $options)

src/ConfigProvider.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public function getDependencyConfig(): array
3030
{
3131
return [
3232
'aliases' => [
33-
'ValidatorManager' => ValidatorPluginManager::class,
33+
'ValidatorManager' => ValidatorPluginManager::class,
34+
ValidatorChainInterface::class => ValidatorChain::class,
3435
],
3536
'factories' => [
3637
ValidatorChainFactory::class => ValidatorChainFactoryFactory::class,

src/ValidatorChain.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
* @psalm-type QueueElement = array{instance: ValidatorInterface, breakChainOnFailure: bool}
2323
* @implements IteratorAggregate<array-key, QueueElement>
2424
*/
25-
final class ValidatorChain implements Countable, IteratorAggregate, ValidatorInterface
25+
final class ValidatorChain implements Countable, IteratorAggregate, ValidatorChainInterface
2626
{
2727
/**
2828
* Default priority at which validators are added
29+
*
30+
* @deprecated Use ValidatorChainInterface::DEFAULT_PRIORITY instead.
2931
*/
30-
public const DEFAULT_PRIORITY = 1;
32+
public const DEFAULT_PRIORITY = ValidatorChainInterface::DEFAULT_PRIORITY;
3133

3234
/**
3335
* Validator chain
@@ -102,8 +104,8 @@ public function setPluginManager(ValidatorPluginManager $plugins): void
102104
*
103105
* @internal \Laminas
104106
*
105-
* @param string|class-string<T> $name Name of validator to return
106-
* @param array<string, mixed> $options Options to pass to validator constructor
107+
* @param string|class-string<T> $name Name of validator to return
108+
* @param array<string, mixed> $options Options to pass to validator constructor
107109
* (if not already instantiated)
108110
* @template T of ValidatorInterface
109111
* @return ($name is class-string<T> ? T : ValidatorInterface)
@@ -126,7 +128,7 @@ public function plugin(string $name, array $options = []): ValidatorInterface
126128
public function attach(
127129
ValidatorInterface $validator,
128130
bool $breakChainOnFailure = false,
129-
int $priority = self::DEFAULT_PRIORITY
131+
int $priority = ValidatorChainInterface::DEFAULT_PRIORITY
130132
): void {
131133
$this->validators->insert(
132134
[
@@ -145,7 +147,7 @@ public function attach(
145147
*/
146148
public function prependValidator(ValidatorInterface $validator, bool $breakChainOnFailure = false): void
147149
{
148-
$priority = self::DEFAULT_PRIORITY;
150+
$priority = ValidatorChainInterface::DEFAULT_PRIORITY;
149151

150152
if (! $this->validators->isEmpty()) {
151153
$extractedNodes = $this->validators->toArray(PriorityQueue::EXTR_PRIORITY);
@@ -172,7 +174,7 @@ public function attachByName(
172174
string $name,
173175
array $options = [],
174176
bool $breakChainOnFailure = false,
175-
int $priority = self::DEFAULT_PRIORITY,
177+
int $priority = ValidatorChainInterface::DEFAULT_PRIORITY,
176178
): void {
177179
$bc = null;
178180
foreach (['break_chain_on_failure', 'breakchainonfailure'] as $key) {
@@ -192,7 +194,7 @@ public function attachByName(
192194
* Use the plugin manager to prepend a validator by name
193195
*
194196
* @param string|class-string<ValidatorInterface> $name
195-
* @param array<string, mixed> $options
197+
* @param array<string, mixed> $options
196198
*/
197199
public function prependByName(string $name, array $options = [], bool $breakChainOnFailure = false): void
198200
{

src/ValidatorChainFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function fromArray(array $specification): ValidatorChain
2020
{
2121
$chain = new ValidatorChain($this->pluginManager);
2222
foreach ($specification as $spec) {
23-
$priority = $spec['priority'] ?? ValidatorChain::DEFAULT_PRIORITY;
23+
$priority = $spec['priority'] ?? ValidatorChainInterface::DEFAULT_PRIORITY;
2424
$breakChain = $spec['break_chain_on_failure'] ?? false;
2525
$options = $spec['options'] ?? [];
2626
$validator = $this->pluginManager->build($spec['name'], $options);

src/ValidatorChainInterface.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Laminas\Validator;
6+
7+
use Override;
8+
9+
interface ValidatorChainInterface extends ValidatorInterface
10+
{
11+
public const DEFAULT_PRIORITY = 1;
12+
13+
/**
14+
* Attach a validator to the end of the chain
15+
*
16+
* @param ValidatorInterface $validator A Validator implementation
17+
* @param bool $breakChainOnFailure If true, the chain's next validator will not be executed in case of failure
18+
* @param int $priority Priority at which to enqueue validator; defaults to 1 (higher executes earlier)
19+
*/
20+
public function attach(
21+
ValidatorInterface $validator,
22+
bool $breakChainOnFailure = false,
23+
int $priority = self::DEFAULT_PRIORITY
24+
): void;
25+
26+
/**
27+
* Attach a validator to the chain using an alias or FQCN
28+
*
29+
* Retrieves the validator from the composed plugin manager, and then calls attach() with the retrieved instance.
30+
*
31+
* @param string|class-string<ValidatorInterface> $name
32+
* @param array<string, mixed> $options Construction options for the desired validator
33+
* @param bool $breakChainOnFailure If true, the chain's next validator will not be executed in case of failure
34+
* @param int $priority Priority at which to enqueue validator; defaults to 1 (higher executes earlier)
35+
*/
36+
public function attachByName(
37+
string $name,
38+
array $options = [],
39+
bool $breakChainOnFailure = false,
40+
int $priority = self::DEFAULT_PRIORITY
41+
): void;
42+
43+
/**
44+
* Returns true if and only if $value passes all validations in the chain
45+
*
46+
* Validators are run in the order in which they were added to the chain (FIFO).
47+
*
48+
* @param array<string, mixed> $context Extra "context" to provide the validator
49+
*/
50+
#[Override]
51+
public function isValid(mixed $value, ?array $context = null): bool;
52+
}

0 commit comments

Comments
 (0)