Skip to content

Commit 02167b0

Browse files
authored
Merge pull request #16 from moufmouf/json_annotations
Adding support for JSON serialization annotations
2 parents 6adcebc + 9612a4d commit 02167b0

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,20 @@ $posts = $db->table('posts')->column('title')->string(50)->graphqlField() // The
5858
->failWith(null) // If the user is not logged or has no right, let's serve 'null'
5959
->endGraphql();
6060

61+
// You can pass instructions on how JSON serialization occurs.
62+
// This will generate a set of JSONxxx annotations.
63+
$nodes = $db->table('nodes')
64+
->column('id')->integer()->primaryKey()->autoIncrement()->jsonSerialize()->ignore()
65+
->column('alias_id')->references('nodes')->null()->jsonSerialize()->recursive()
66+
->column('parent_id')->references('nodes')->null()->jsonSerialize()->include()
67+
->column('root_id')->references('nodes')->null()->jsonSerialize()->ignore()
68+
->column('owner_id')->references('authors')->null()->jsonSerialize()->formatUsingProperty('name')->include()
69+
->column('owner_country')->references('authors')->null()->jsonSerialize()->formatUsingMethod('getCountryName')->include()
70+
->column('name')->string()->jsonSerialize()->key('basename')
71+
->column('size')->integer()->notNull()->default(0)->jsonSerialize()->numericFormat(null, null, null, ' o')
72+
->column('weight')->float()->null()->jsonSerialize()->numericFormat(2, ',', '.', 'g')
73+
->column('created_at')->date()->null()->jsonSerialize()->datetimeFormat("Y-m-d")
74+
->column('another_parent')->references('nodes')->comment('@JsonCollection("entries") @JsonFormat(property="entry")');
75+
6176
$db->junctionTable('posts', 'users')->graphqlField(); // Expose the many-to-many relationship as a GraphQL field.
6277
```

src/TdbmFluidColumnJsonOptions.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
4+
namespace TheCodingMachine\FluidSchema;
5+
6+
7+
use function addslashes;
8+
use Doctrine\DBAL\Types\Type;
9+
use function var_export;
10+
11+
class TdbmFluidColumnJsonOptions
12+
{
13+
/**
14+
* @var TdbmFluidColumnOptions
15+
*/
16+
private $tdbmFluidColumnOptions;
17+
18+
public function __construct(TdbmFluidColumnOptions $tdbmFluidColumnOptions)
19+
{
20+
$this->tdbmFluidColumnOptions = $tdbmFluidColumnOptions;
21+
}
22+
23+
public function key(string $name): self
24+
{
25+
$this->addAnnotation('JsonKey', ['key' => $name]);
26+
return $this;
27+
}
28+
29+
public function datetimeFormat(string $format): self
30+
{
31+
$this->addAnnotation('JsonFormat', ['date' => $format]);
32+
return $this;
33+
}
34+
35+
/**
36+
* @param int|null $decimals The number of decimals
37+
* @param string|null $point The decimal point
38+
* @param string|null $separator The thousands separator
39+
* @param string|null $unit The suffix to append after a number
40+
*/
41+
public function numericFormat(?int $decimals = null, ?string $point = null, ?string $separator = null, ?string $unit = null): self
42+
{
43+
$params = [];
44+
if ($decimals !== null) {
45+
$params['decimals'] = $decimals;
46+
}
47+
if ($point !== null) {
48+
$params['point'] = $point;
49+
}
50+
if ($separator !== null) {
51+
$params['separator'] = $separator;
52+
}
53+
if ($unit !== null) {
54+
$params['unit'] = $unit;
55+
}
56+
$this->addAnnotation('JsonFormat', $params);
57+
return $this;
58+
}
59+
60+
/**
61+
* Serialize in JSON by getting the property from an object.
62+
*/
63+
public function formatUsingProperty(string $property): self
64+
{
65+
$this->addAnnotation('JsonFormat', ['property' => $property]);
66+
return $this;
67+
}
68+
69+
/**
70+
* Serialize in JSON by calling a method from an object.
71+
*/
72+
public function formatUsingMethod(string $method): self
73+
{
74+
$this->addAnnotation('JsonFormat', ['method' => $method]);
75+
return $this;
76+
}
77+
78+
public function ignore(): self
79+
{
80+
$this->addAnnotation('JsonIgnore');
81+
return $this;
82+
}
83+
84+
public function include(): self
85+
{
86+
$this->addAnnotation('JsonInclude');
87+
return $this;
88+
}
89+
90+
public function recursive(): self
91+
{
92+
$this->addAnnotation('JsonRecursive');
93+
return $this;
94+
}
95+
96+
public function collection(string $key): self
97+
{
98+
$this->addAnnotation('JsonCollection', ['key' => $key]);
99+
return $this;
100+
}
101+
102+
/**
103+
* @param string $annotation
104+
* @param mixed $content
105+
* @param bool $replaceExisting
106+
* @return TdbmFluidColumnGraphqlOptions
107+
*/
108+
public function addAnnotation(string $annotation, $content = null, bool $replaceExisting = true, bool $explicitNull = false): self
109+
{
110+
$this->tdbmFluidColumnOptions->addAnnotation($annotation, $content, $replaceExisting, $explicitNull);
111+
return $this;
112+
}
113+
114+
public function endJsonSerialize(): TdbmFluidColumnOptions
115+
{
116+
return $this->tdbmFluidColumnOptions;
117+
}
118+
119+
public function then(): TdbmFluidTable
120+
{
121+
return $this->tdbmFluidColumnOptions->then();
122+
}
123+
124+
public function column(string $name): TdbmFluidColumn
125+
{
126+
return $this->tdbmFluidColumnOptions->column($name);
127+
}
128+
}

src/TdbmFluidColumnOptions.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ public function graphqlField(): TdbmFluidColumnGraphqlOptions
108108
return new TdbmFluidColumnGraphqlOptions($this, $this->fluidColumn);
109109
}
110110

111+
public function jsonSerialize(): TdbmFluidColumnJsonOptions
112+
{
113+
return new TdbmFluidColumnJsonOptions($this);
114+
}
115+
111116
public function protectedGetter(): self
112117
{
113118
$this->addAnnotation('TheCodingMachine\\TDBM\\Utils\\Annotation\\ProtectedGetter');
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace TheCodingMachine\FluidSchema;
4+
5+
use Doctrine\DBAL\Schema\Schema;
6+
use Doctrine\DBAL\Types\Type;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class TdbmFluidJunctionTableJsonOptionsTest extends TestCase
10+
{
11+
public function testJson()
12+
{
13+
$schema = new Schema();
14+
$fluid = new TdbmFluidSchema($schema);
15+
16+
$fluid->table('nodes')
17+
->column('id')->integer()->primaryKey()->autoIncrement()->jsonSerialize()->ignore()
18+
->column('alias_id')->references('nodes')->null()->jsonSerialize()->recursive()
19+
->column('parent_id')->references('nodes')->null()->jsonSerialize()->include()
20+
->column('root_id')->references('nodes')->null()->jsonSerialize()->ignore()
21+
->column('owner_id')->references('nodes')->null()->jsonSerialize()->formatUsingProperty('name')->include()
22+
->column('owner_country')->references('nodes')->null()->jsonSerialize()->formatUsingMethod('myMethod')->include()
23+
->column('name')->string()->jsonSerialize()->key('basename')
24+
->column('size')->integer()->notNull()->default(0)->jsonSerialize()->numericFormat(null, null, null, ' o')
25+
->column('weight')->float()->null()->jsonSerialize()->numericFormat(2, ',', '.', 'g')
26+
->column('created_at')->date()->null()->jsonSerialize()->datetimeFormat("Y-m-d")
27+
->column('another_parent')->references('nodes')->comment('@JsonCollection("entries") @JsonFormat(property="entry")');
28+
29+
$nodesTable = $schema->getTable('nodes');
30+
$this->assertContains('@JsonIgnore', $nodesTable->getColumn('id')->getComment());
31+
$this->assertContains('@JsonRecursive', $nodesTable->getColumn('alias_id')->getComment());
32+
$this->assertContains('@JsonInclude', $nodesTable->getColumn('parent_id')->getComment());
33+
$this->assertContains('@JsonIgnore', $nodesTable->getColumn('root_id')->getComment());
34+
$this->assertContains('@JsonFormat(property = "name")', $nodesTable->getColumn('owner_id')->getComment());
35+
$this->assertContains('@JsonFormat(method = "myMethod")', $nodesTable->getColumn('owner_country')->getComment());
36+
$this->assertContains('@JsonKey(key = "basename")', $nodesTable->getColumn('name')->getComment());
37+
$this->assertContains('@JsonFormat(unit = " o")', $nodesTable->getColumn('size')->getComment());
38+
$this->assertContains('@JsonFormat(decimals = 2, point = ",", separator = ".", unit = "g")', $nodesTable->getColumn('weight')->getComment());
39+
$this->assertContains('@JsonFormat(date = "Y-m-d")', $nodesTable->getColumn('created_at')->getComment());
40+
$this->assertContains('@JsonCollection("entries")', $nodesTable->getColumn('another_parent')->getComment());
41+
42+
$fluid->table('node_entries')
43+
->column('id')->integer()->primaryKey()->autoIncrement()
44+
->column('node_id')->references('nodes')->jsonSerialize()->collection("entries")
45+
->column('entry')->string()->null();
46+
47+
$this->assertContains('@JsonCollection(key = "entries")', $schema->getTable('node_entries')->getColumn('node_id')->getComment());
48+
49+
$anotherColumn = $fluid->table('nodes')->column('another_column')->integer();
50+
$this->assertSame($anotherColumn, $anotherColumn->jsonSerialize()->endJsonSerialize());
51+
$this->assertSame($fluid->table('nodes'), $anotherColumn->jsonSerialize()->then());
52+
}
53+
}

0 commit comments

Comments
 (0)