Skip to content

Commit ae50028

Browse files
committed
Add symfony validator support
1 parent 225f5c1 commit ae50028

File tree

3 files changed

+109
-10
lines changed

3 files changed

+109
-10
lines changed

README.md

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,11 @@ final class MyValidationTransformer implements ResultTransformerInterface
234234
}
235235
```
236236

237-
## Validator integration
237+
## Validators
238238

239239
You can combine this library with a validator that is doing the actual validation of your input data.
240240

241-
### Integration with CakePHP Validation
241+
### CakePHP Validator
242242

243243
The [cakephp/validation](https://github.com/cakephp/validation) library provides features to
244244
build validators that can validate arbitrary arrays of data with ease.
@@ -281,28 +281,87 @@ $validator
281281
$validationResult = CakeValidatorFactory::createValidationResult($validator->validate($formData));
282282

283283
// Optional: Do more complex validation and append it to the validation result
284-
if (!$this->existsEmailInDatabase($formData['email'])) {
285-
$validationResult->addError('email', 'E-Mail already exists');
284+
if ($this->existsUsername($formData['username'])) {
285+
$validationResult->addError('username', 'Username is already taken);
286286
}
287287

288288
if ($validationResult->isFailed()) {
289289
throw new ValidationException('Validation failed. Please check your input.', $validationResult);
290290
}
291291
```
292292

293+
### Symfony Validator
294+
295+
**Installation**
296+
297+
```
298+
composer require symfony/validator
299+
```
300+
293301
**Usage**
294302

295303
```php
296304
<?php
297-
$validator = $this->validationFactory->createValidator();
298305

299-
// ...
306+
use Cake\Validation\Validator;
307+
use Selective\Validation\Exception\ValidationException;
308+
use Selective\Validation\Regex\ValidationRegex;
309+
use Selective\Validation\Factory\SymfonyValidatorFactory;
310+
use Symfony\Component\Validator\Constraints as Assert;
311+
use Symfony\Component\Validator\ConstraintViolation;
312+
use Symfony\Component\Validator\Validation;
313+
314+
// Note: This is just an example. Don't use the $request object within the domain layer.
315+
$formData = (array)$request->getParsedBody();
300316

301-
$validationResult = $this->validationFactory->createErrorCollector()
302-
->addErrors($validator->validate($form));
317+
// Create a symfony validator instance
318+
$validator = Validation::createValidator();
319+
320+
// Add rules
321+
$constraint = new Assert\Collection(
322+
[
323+
'first_name' => new Assert\NotBlank(['message' => 'Input required']),
324+
'last_name' => new Assert\NotBlank(['message' => 'Input required']),
325+
'mobile' => new Assert\Optional(
326+
[
327+
new Assert\Regex(
328+
[
329+
'pattern' => ValidationRegex::PHONE_NUMBER,
330+
'message' => 'Invalid',
331+
]
332+
),
333+
]
334+
),
335+
'comment' => new Assert\Optional(
336+
[
337+
new Assert\Length(['max' => 255, 'maxMessage' => 'Too long']),
338+
]
339+
),
340+
'email' => new Assert\Optional(
341+
[
342+
new Assert\Email(
343+
[
344+
'message' => 'Invalid',
345+
]
346+
),
347+
]
348+
)
349+
]
350+
);
351+
352+
$constraint->missingFieldsMessage = 'Input required';
353+
$violations = $validator->validate($formData, $constraint);
354+
355+
// Convert violations to ValidationResult
356+
$validationResult = SymfonyValidatorFactory::createValidationResult($violations);
357+
358+
// Optional: Do more complex validation and append it to the validation result
359+
if ($this->existsUsername($formData['username'])) {
360+
$validationResult->addError('username', 'Username is already taken');
361+
}
303362

304363
if ($validationResult->isFailed()) {
305-
// ...
364+
throw new ValidationException(__('Please check your input'), $validationResult);
306365
}
307366
```
308367

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"phpunit/phpunit": "^7.0|^8.0",
2424
"relay/relay": "^2.0",
2525
"slim/psr7": "^1",
26-
"squizlabs/php_codesniffer": "^3.4"
26+
"squizlabs/php_codesniffer": "^3.4",
27+
"symfony/validator": "^5.1"
2728
},
2829
"scripts": {
2930
"test": "phpunit --configuration phpunit.xml",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Selective\Validation\Factory;
4+
5+
use Selective\Validation\ValidationResult;
6+
use Symfony\Component\Validator\ConstraintViolation;
7+
use Symfony\Component\Validator\ConstraintViolationList;
8+
9+
/**
10+
* Symfony validation error collector.
11+
*/
12+
final class SymfonyValidatorFactory
13+
{
14+
/**
15+
* Create validation result from array with errors.
16+
*
17+
* @param ConstraintViolationList $violations The validation errors
18+
* @param ValidationResult|null $result The result
19+
*
20+
* @return ValidationResult The result
21+
*/
22+
public static function createValidationResult(
23+
ConstraintViolationList $violations,
24+
ValidationResult $result = null
25+
): ValidationResult {
26+
if ($result === null) {
27+
$result = new ValidationResult();
28+
}
29+
30+
/** @var ConstraintViolation $violation */
31+
foreach ($violations as $violation) {
32+
$field = $violation->getPropertyPath();
33+
$field = str_replace(']', '', str_replace('[', '', str_replace('][', '.', $field)));
34+
$result->addError($field, $violation->getMessage());
35+
}
36+
37+
return $result;
38+
}
39+
}

0 commit comments

Comments
 (0)