Skip to content

Commit

Permalink
feat: add opis validator
Browse files Browse the repository at this point in the history
  • Loading branch information
ErwannLeRoux committed Aug 1, 2023
1 parent d0c8295 commit 2a33e6c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 2 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"symfony/http-kernel": ">=6.0",
"symfony/dependency-injection": ">=6.0",
"symfony/config": ">=6.0",
"swaggest/json-schema": ">=0.12.41"
"swaggest/json-schema": ">=0.12.41",
"opis/json-schema": "^2.3"
},
"require-dev": {
"vimeo/psalm": "5.x-dev"
Expand Down
3 changes: 2 additions & 1 deletion config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use KnpLabs\JsonSchema\Collection;
use KnpLabs\JsonSchema\JsonSchemaInterface;
use KnpLabs\JsonSchemaBundle\RequestHandler;
use KnpLabs\JsonSchemaBundle\Validator\OpisValidator;
use KnpLabs\JsonSchemaBundle\Validator\SwaggestValidator;

return function(ContainerConfigurator $configurator) {
Expand All @@ -19,7 +20,7 @@
;

$services->set(SwaggestValidator::class);
$services->alias('KnpLabs\JsonSchema\Validator', SwaggestValidator::class);
$services->set(OpisValidator::class);

$services->set(Collection::class)
->arg('$schemas', tagged_iterator('knp.json_schema'))
Expand Down
27 changes: 27 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace KnpLabs\JsonSchemaBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('knp_json_schema');

$treeBuilder->getRootNode()
->children()
->enumNode('validator')
->values(['OpisValidator', 'SwaggestValidator'])
->defaultValue('SwaggestValidator')
->end()
->end()
;

return $treeBuilder;
}
}
9 changes: 9 additions & 0 deletions src/DependencyInjection/JsonSchemaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ class JsonSchemaExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container): void
{
$configuration = new Configuration();

$config = $this->processConfiguration($configuration, $configs);

$loader = new PhpFileLoader(
$container,
new FileLocator(__DIR__ . '/../../config')
);

$loader->load('services.php');

$container->setAlias(
'KnpLabs\JsonSchema\Validator',
sprintf('KnpLabs\\JsonSchemaBundle\\Validator\\%s', $config['validator'])
);

$container
->registerForAutoconfiguration(JsonSchemaInterface::class)
->addTag('knp.json_schema')
Expand Down
78 changes: 78 additions & 0 deletions src/Validator/OpisValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace KnpLabs\JsonSchemaBundle\Validator;

use KnpLabs\JsonSchema\JsonSchemaInterface;
use KnpLabs\JsonSchema\Validator;
use KnpLabs\JsonSchema\Validator\Error as KnpJsonSchemaError;
use KnpLabs\JsonSchema\Validator\Errors;
use Opis\JsonSchema\Errors\ErrorFormatter;
use Opis\JsonSchema\Errors\ValidationError;
use Opis\JsonSchema\Validator as JsonSchemaValidator;

class OpisValidator implements Validator
{
private JsonSchemaValidator $validator;

public function __construct()
{
$this->validator = new JsonSchemaValidator();
$this->validator->setMaxErrors(10);
}

public function validate(array $data, JsonSchemaInterface $schema): ?Errors
{
/**
* @var mixed
*/
$data = json_decode(
json_encode(
$data,
flags: JSON_THROW_ON_ERROR,
),
flags: JSON_THROW_ON_ERROR
);

$schema = json_decode(
json_encode(
$schema->getSchema(),
flags: JSON_THROW_ON_ERROR,
),
flags: JSON_THROW_ON_ERROR
);

$result = $this->validator->validate($data, $schema);

if ($result->isValid()) {
return null;
}

return new Errors(
...$this->yieldErrors($result->error())
);
}

/**
* @return iterable<KnpJsonSchemaError>
*/
private function yieldErrors(ValidationError $error): iterable
{
$formatter = new ErrorFormatter();

$errors = $formatter->format($error);

foreach ($errors as $field => $message) {
$formatted = sizeof($message) === 1
? $message[0]
: json_encode($message)
;

yield new KnpJsonSchemaError(
$field,
$formatted,
);
}
}
}

0 comments on commit 2a33e6c

Please sign in to comment.