Skip to content

Commit 3303042

Browse files
ISSUE-213: Implemented JsonSchemaSubscriber
1 parent 58f85b9 commit 3303042

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ Learn more about it in its [documentation](https://github.com/darkwebdesign/symf
1515

1616
## Features
1717

18+
### Types
19+
1820
* BirthdayType, handles birthday data.
1921
* BooleanType, transforms an user selected value into a boolean.
2022
* EntityType, transforms an user entered identifier into a Doctrine entity.
2123
* UnstructuredType, handles unstructured data.
2224

25+
### Event Subscribers
26+
27+
* JsonSchemaSubscriber, rewrites the JSON Schema `$schema` keyword property.
28+
2329
## Installing via Composer
2430

2531
```bash

src/JsonSchemaSubscriber.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Copyright (c) 2021 DarkWeb Design
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18+
* SOFTWARE.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace DarkWebDesign\SymfonyAddonFormTypes;
24+
25+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
26+
use Symfony\Component\Form\FormEvent;
27+
use Symfony\Component\Form\FormEvents;
28+
29+
/**
30+
* JSON Schema form event subscriber.
31+
*
32+
* @author Raymond Schouten
33+
*
34+
* @since 5.2.1
35+
*/
36+
class JsonSchemaSubscriber implements EventSubscriberInterface
37+
{
38+
/** @var string */
39+
private $fieldName;
40+
41+
public function __construct(string $fieldName = 'schema')
42+
{
43+
$this->fieldName = $fieldName;
44+
}
45+
46+
/**
47+
* Maps the submitted JSON Schema `$schema` keyword to the desired form field name.
48+
*/
49+
public function onPreSubmit(FormEvent $event): void
50+
{
51+
$data = $event->getData();
52+
53+
if (!is_array($data) || !array_key_exists('$schema', $data)) {
54+
return;
55+
}
56+
57+
$data[$this->fieldName] = $data['$schema'];
58+
unset($data['$schema']);
59+
60+
$event->setData($data);
61+
}
62+
63+
/**
64+
* Returns an array of event names this subscriber wants to listen to.
65+
*/
66+
public static function getSubscribedEvents(): array
67+
{
68+
return [
69+
FormEvents::PRE_SUBMIT => 'onPreSubmit',
70+
];
71+
}
72+
}

tests/JsonSchemaSubscriberTest.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* Copyright (c) 2021 DarkWeb Design
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18+
* SOFTWARE.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace DarkWebDesign\SymfonyAddonFormTypes\Tests;
24+
25+
use DarkWebDesign\SymfonyAddonFormTypes\JsonSchemaSubscriber;
26+
use Symfony\Component\Form\Extension\Core\Type\TextType;
27+
use Symfony\Component\Form\Test\TypeTestCase;
28+
29+
/**
30+
* @covers \DarkWebDesign\SymfonyAddonFormTypes\JsonSchemaSubscriber
31+
*/
32+
class JsonSchemaSubscriberTest extends TypeTestCase
33+
{
34+
public function test(): void
35+
{
36+
$form = $this->factory->createBuilder()
37+
->add('schema', TextType::class)
38+
->addEventSubscriber(new JsonSchemaSubscriber())
39+
->getForm();
40+
41+
$form->submit([
42+
'$schema' => 'https://example.com/product.schema.json',
43+
]);
44+
45+
$expected = [
46+
'schema' => 'https://example.com/product.schema.json',
47+
];
48+
49+
$this->assertTrue($form->isSynchronized());
50+
$this->assertSame($expected, $form->getData());
51+
}
52+
53+
public function testAlternativeFieldName(): void
54+
{
55+
$form = $this->factory->createBuilder()
56+
->add('alternativeFieldName', TextType::class)
57+
->addEventSubscriber(new JsonSchemaSubscriber('alternativeFieldName'))
58+
->getForm();
59+
60+
$form->submit([
61+
'$schema' => 'https://example.com/product.schema.json',
62+
]);
63+
64+
$expected = [
65+
'alternativeFieldName' => 'https://example.com/product.schema.json',
66+
];
67+
68+
$this->assertTrue($form->isSynchronized());
69+
$this->assertSame($expected, $form->getData());
70+
}
71+
72+
public function testDataNoSchema(): void
73+
{
74+
$form = $this->factory->createBuilder()
75+
->add('schema', TextType::class)
76+
->addEventSubscriber(new JsonSchemaSubscriber())
77+
->getForm();
78+
79+
$form->submit([]);
80+
81+
$expected = [
82+
'schema' => null,
83+
];
84+
85+
$this->assertTrue($form->isSynchronized());
86+
$this->assertSame($expected, $form->getData());
87+
}
88+
89+
public function testDataNotArray(): void
90+
{
91+
$form = $this->factory->createBuilder()
92+
->add('alternativeFieldName', TextType::class)
93+
->addEventSubscriber(new JsonSchemaSubscriber('alternativeFieldName'))
94+
->getForm();
95+
96+
$form->submit('not-array');
97+
98+
$this->assertFalse($form->isSynchronized());
99+
$this->assertNull($form->getData());
100+
}
101+
}

0 commit comments

Comments
 (0)