From 337f2d56c8105656886d65421fbc521f00948bad Mon Sep 17 00:00:00 2001 From: Moln Date: Thu, 9 Sep 2021 13:08:24 +0800 Subject: [PATCH 1/5] Update docs. --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index c6b83d1..6e6c2e3 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,42 @@ composer require zfegg/content-validation Usage / 使用 -------------- +### `Opis\JsonSchema\Validator` factory config. + +```php +// config.php +return [ + Opis\JsonSchema\Validator::class => [ + 'resolvers' => [ + 'protocolDir' => [ + // foo-schema://host/foo.create.json => schema/dir/foo.create.json + ['foo-schema', 'host', 'schema/dir'], + ], + 'protocol' => [ + ], + 'prefix' => [ + ['prefix1', 'path/to/dir'], + ['prefix2', 'path/to/dir'], + ], + 'file' => [ + ['SchemaFoo', 'path/to/file'], + ['SchemaBar', 'path/to/file2'], + ], + 'raw' => [ + ['{"type":"object", ...}', 'schema id 1'], + ['{"type":"object", ...}', 'schema id 2'], + ] + ], + 'filters' => [ + 'foo-filter' => ['filter' => 'FilterFilterName', 'types' => ['integer']], + ], + 'filtersNS' => [ + 'foo-ns' => 'FilterResolverName', + ], + ] +] +``` + ### Mezzio Add `ConfigProvider` in 'config.php'. / 在 `config.php` 中添加 `ConfigProvider`. From 2efb17d59722f77253f57fbb53a391ad63610f54 Mon Sep 17 00:00:00 2001 From: Moln Date: Sun, 9 Jan 2022 22:23:30 +0800 Subject: [PATCH 2/5] Add DbalRecordExistsFilter. --- src/Factory/ValidatorFactory.php | 6 ++ src/Opis/Filter/DbalRecordExistsFilter.php | 43 +++++++++++ src/Opis/Filter/RecordExistsFilter.php | 1 + .../Filter/DbalRecordExistsFilterTest.php | 71 +++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 src/Opis/Filter/DbalRecordExistsFilter.php create mode 100644 test/Opis/Filter/DbalRecordExistsFilterTest.php diff --git a/src/Factory/ValidatorFactory.php b/src/Factory/ValidatorFactory.php index ea1000c..dadd9bf 100644 --- a/src/Factory/ValidatorFactory.php +++ b/src/Factory/ValidatorFactory.php @@ -6,6 +6,7 @@ use Opis\JsonSchema\Validator; use Psr\Container\ContainerInterface; +use Zfegg\ContentValidation\Opis\Filter\DbalRecordExistsFilter; use Zfegg\ContentValidation\Opis\Filter\DoctrineRecordExistsFilter; use Zfegg\ContentValidation\Opis\Filter\RecordExistsFilter; use Zfegg\ContentValidation\Opis\RemoveAdditionalPropertiesParser; @@ -65,6 +66,11 @@ public function __invoke(ContainerInterface $container): Validator new DoctrineRecordExistsFilter($container), $types ); + $parser->getFilterResolver()->registerMultipleTypes( + 'dbal-exists', + new DbalRecordExistsFilter($container), + $types + ); return $validator; } diff --git a/src/Opis/Filter/DbalRecordExistsFilter.php b/src/Opis/Filter/DbalRecordExistsFilter.php new file mode 100644 index 0000000..7261e93 --- /dev/null +++ b/src/Opis/Filter/DbalRecordExistsFilter.php @@ -0,0 +1,43 @@ +container = $container; + $this->defaultId = $defaultId; + } + + public function validate(ValidationContext $context, Schema $schema, array $args = []): bool + { + /** @var \Doctrine\DBAL\Connection $db */ + $db = $this->container->get($args['db'] ?? $this->defaultId); + + if (isset($args['sql'])) { + $sql = $args['sql']; + } elseif (isset($args['table']) && isset($args['field'])) { + $sql = sprintf('SELECT COUNT(*) FROM %s WHERE %s=?', $args['table'], $args['field']); + } else { + throw new \InvalidArgumentException('Invalid args.'); + } + + $exists = $args['exists'] ?? false; + $sth = $db->prepare($sql); + $row = $sth->executeQuery([$context->currentData()])->fetchNumeric(); + + return $row[0] == $exists; + } +} diff --git a/src/Opis/Filter/RecordExistsFilter.php b/src/Opis/Filter/RecordExistsFilter.php index 87caf74..c8d45e9 100644 --- a/src/Opis/Filter/RecordExistsFilter.php +++ b/src/Opis/Filter/RecordExistsFilter.php @@ -24,6 +24,7 @@ public function __construct(ContainerInterface $container, string $defaultId = ' public function validate(ValidationContext $context, Schema $schema, array $args = []): bool { + /** @var \PDO $db */ $db = $this->container->get($args['db'] ?? $this->defaultId); if (isset($args['sql'])) { diff --git a/test/Opis/Filter/DbalRecordExistsFilterTest.php b/test/Opis/Filter/DbalRecordExistsFilterTest.php new file mode 100644 index 0000000..9f8c4a8 --- /dev/null +++ b/test/Opis/Filter/DbalRecordExistsFilterTest.php @@ -0,0 +1,71 @@ +setUpContainer(); + $db = DriverManager::getConnection(['url' => 'sqlite:///:memory:']); + $db->executeStatement(self::SQL); + $db->executeStatement('INSERT INTO foo VALUES(NULL, "exists","123")'); + $this->container->setService('db', $db->getWrappedConnection()); + $this->container->setService('dbal', $db); + } + + public function testValidate(): void + { + $filter = new DbalRecordExistsFilter($this->container, 'dbal'); + + $context = new ValidationContext('test', new SchemaLoader()); + $schema = $this->createMock(Schema::class); + $rs = $filter->validate($context, $schema, ['sql' => 'SELECT count(*) FROM foo where key=?']); + $this->assertTrue($rs); + + $rs = $filter->validate($context, $schema, ['sql' => 'SELECT count(*) FROM foo where key=?', 'exists' => true]); + $this->assertFalse($rs); + + $rs = $filter->validate($context, $schema, ['table' => 'foo', 'field' => 'key']); + $this->assertTrue($rs); + } + + + public function testInValidator(): void + { + $validator = $this->container->get(Validator::class); + $data = <<<'JSON' +{"key": "exists"} +JSON; + $data = json_decode($data); + $result = $validator->validate($data, 'test:test/test-db-filter.json'); + + $this->assertTrue($result->isValid()); + } +} From 7a94eb2cfc2ff290ebe8170075d49207909cd5e0 Mon Sep 17 00:00:00 2001 From: Moln Date: Sun, 9 Jan 2022 22:27:17 +0800 Subject: [PATCH 3/5] CI add PHP8.1 . --- .github/workflows/qa.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index a60834a..29e007b 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: operating-system: [ubuntu-latest] - php-versions: ['7.4', '8.0'] + php-versions: ['7.4', '8.0', '8.1'] steps: - name: Checkout uses: actions/checkout@v2 @@ -30,8 +30,8 @@ jobs: with: path: ${{ steps.composer-cache.outputs.dir }} # Use composer.json for key, if composer.lock is not committed. - # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} +# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install Composer dependencies From 7c77800acd9a2813de6c40fdd0a50dc1cbd94eff Mon Sep 17 00:00:00 2001 From: Moln Date: Sun, 9 Jan 2022 22:37:16 +0800 Subject: [PATCH 4/5] Fix test --- .../Filter/DbalRecordExistsFilterTest.php | 2 +- test/test-dbal-filter.json | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/test-dbal-filter.json diff --git a/test/Opis/Filter/DbalRecordExistsFilterTest.php b/test/Opis/Filter/DbalRecordExistsFilterTest.php index 9f8c4a8..061b92d 100644 --- a/test/Opis/Filter/DbalRecordExistsFilterTest.php +++ b/test/Opis/Filter/DbalRecordExistsFilterTest.php @@ -64,7 +64,7 @@ public function testInValidator(): void {"key": "exists"} JSON; $data = json_decode($data); - $result = $validator->validate($data, 'test:test/test-db-filter.json'); + $result = $validator->validate($data, 'test:test/test-dbal-filter.json'); $this->assertTrue($result->isValid()); } diff --git a/test/test-dbal-filter.json b/test/test-dbal-filter.json new file mode 100644 index 0000000..6ebb5a4 --- /dev/null +++ b/test/test-dbal-filter.json @@ -0,0 +1,23 @@ +{ + "type": "object", + "properties": { + "key": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "$filters": [ + { + "$func": "dbal-exists", + "$vars": { + "db": "dbal", + "table": "foo", + "field": "key", + "exists": true + } + } + ] + } + }, + "required": ["key"], + "additionalProperties": false +} \ No newline at end of file From 81eb4b74a8c12293ecfa781e2a098305a767a9c7 Mon Sep 17 00:00:00 2001 From: Moln Date: Sun, 9 Jan 2022 22:41:04 +0800 Subject: [PATCH 5/5] Fix test --- .github/workflows/qa.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 29e007b..39e88d9 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -49,6 +49,6 @@ jobs: env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - composer require php-coveralls/php-coveralls --dev -q + composer require php-coveralls/php-coveralls "psr/log:^2" --dev -q ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml ./vendor/bin/php-coveralls -v