Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fac3060

Browse files
committed
feature #43973 [Serializer] Add context builders (mtarld)
This PR was merged into the 6.1 branch. Discussion ---------- [Serializer] Add context builders | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fixes partially #30818 | License | MIT | Doc PR | TODO This PR introduces ContextBuilders as discussed in #30818. The main idea here is to introduce an abstract context builder that could be extended to create concrete context builders. These context builders will allow serialization context construction using withers (maybe setters are better?) while providing validation, documentation, and IDE autocompletion. Once construction is ready, `toArray` (maybe `build` is better?) can be called to generate the actual serialization context. For example: ```php use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder; use Symfony\Component\Serializer\Context\Normalizer\DateTimeNormalizerContextBuilder; $initialContext = ['custom_key' => 'custom_value']); $contextBuilder = (new DateTimeNormalizerContextBuilder() ->withContext($initialContext) ->withFormat('Y_m_d') ->withTimezone('GMT'); $contextBuilder = (new CsvEncoderContextBuilder()) ->withContext($contextBuilder->toArray()) ->withDelimiter('-') ->withHeaders(['foo', 'bar']); $this->serializer->serialize($data, 'csv', $contextBuilder->toArray()); // Serialization context will be: // [ // 'custom_key' => 'custom_value', // 'datetime_format' => 'Y_m_d', // 'datetime_timezone' => DateTimeZone instance, // 'csv_delimiter' => '-', // 'csv_headers' => ['foo', 'bar'], // ] ``` Commits ------- f1b078c Add context builers
2 parents 1e54965 + f1b078c commit fac3060

39 files changed

+2371
-7
lines changed

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
6.1
55
---
66

7+
* Add the ability to create contexts using context builders
78
* Set `Context` annotation as not final
89
* Deprecate `ContextAwareNormalizerInterface`, use `NormalizerInterface` instead
910
* Deprecate `ContextAwareDenormalizerInterface`, use `DenormalizerInterface` instead
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Context;
13+
14+
/**
15+
* @author Mathias Arlaud <[email protected]>
16+
*/
17+
trait ContextBuilderTrait
18+
{
19+
/**
20+
* @var array<string, mixed>
21+
*/
22+
protected array $context = [];
23+
24+
protected function with(string $key, mixed $value): static
25+
{
26+
$instance = new static();
27+
$instance->context = array_merge($this->context, [$key => $value]);
28+
29+
return $instance;
30+
}
31+
32+
/**
33+
* @param array<string, mixed> $context
34+
*/
35+
public function withContext(array $context): static
36+
{
37+
$instance = new static();
38+
$instance->context = array_merge($this->context, $context);
39+
40+
return $instance;
41+
}
42+
43+
/**
44+
* @return array<string, mixed>
45+
*/
46+
public function toArray(): array
47+
{
48+
return $this->context;
49+
}
50+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Context\Encoder;
13+
14+
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
15+
use Symfony\Component\Serializer\Encoder\CsvEncoder;
16+
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
17+
18+
/**
19+
* A helper providing autocompletion for available CsvEncoder options.
20+
*
21+
* @author Mathias Arlaud <[email protected]>
22+
*/
23+
final class CsvEncoderContextBuilder
24+
{
25+
use ContextBuilderTrait;
26+
27+
/**
28+
* Configures the column delimiter character.
29+
*
30+
* Must be a single character.
31+
*
32+
* @param non-empty-string|null $delimiter
33+
*
34+
* @throws InvalidArgumentException
35+
*/
36+
public function withDelimiter(?string $delimiter): static
37+
{
38+
if (null !== $delimiter && 1 !== \strlen($delimiter)) {
39+
throw new InvalidArgumentException(sprintf('The "%s" delimiter must be a single character.', $delimiter));
40+
}
41+
42+
return $this->with(CsvEncoder::DELIMITER_KEY, $delimiter);
43+
}
44+
45+
/**
46+
* Configures the field enclosure character.
47+
*
48+
* Must be a single character.
49+
*
50+
* @param non-empty-string|null $enclosure
51+
*
52+
* @throws InvalidArgumentException
53+
*/
54+
public function withEnclosure(?string $enclosure): static
55+
{
56+
if (null !== $enclosure && 1 !== \strlen($enclosure)) {
57+
throw new InvalidArgumentException(sprintf('The "%s" enclosure must be a single character.', $enclosure));
58+
}
59+
60+
return $this->with(CsvEncoder::ENCLOSURE_KEY, $enclosure);
61+
}
62+
63+
/**
64+
* Configures the escape character.
65+
*
66+
* Must be empty or a single character.
67+
*
68+
* @throws InvalidArgumentException
69+
*/
70+
public function withEscapeChar(?string $escapeChar): static
71+
{
72+
if (null !== $escapeChar && \strlen($escapeChar) > 1) {
73+
throw new InvalidArgumentException(sprintf('The "%s" escape character must be empty or a single character.', $escapeChar));
74+
}
75+
76+
return $this->with(CsvEncoder::ESCAPE_CHAR_KEY, $escapeChar);
77+
}
78+
79+
/**
80+
* Configures the key separator when (un)flattening arrays.
81+
*/
82+
public function withKeySeparator(?string $keySeparator): static
83+
{
84+
return $this->with(CsvEncoder::KEY_SEPARATOR_KEY, $keySeparator);
85+
}
86+
87+
/**
88+
* Configures the headers.
89+
*
90+
* @param list<mixed>|null $headers
91+
*/
92+
public function withHeaders(?array $headers): static
93+
{
94+
return $this->with(CsvEncoder::HEADERS_KEY, $headers);
95+
}
96+
97+
/**
98+
* Configures whether formulas should be escaped.
99+
*/
100+
public function withEscapedFormulas(?bool $escapedFormulas): static
101+
{
102+
return $this->with(CsvEncoder::ESCAPE_FORMULAS_KEY, $escapedFormulas);
103+
}
104+
105+
/**
106+
* Configures whether the decoded result should be considered as a collection
107+
* or as a single element.
108+
*/
109+
public function withAsCollection(?bool $asCollection): static
110+
{
111+
return $this->with(CsvEncoder::AS_COLLECTION_KEY, $asCollection);
112+
}
113+
114+
/**
115+
* Configures whether the input (or output) is containing (or will contain) headers.
116+
*/
117+
public function withNoHeaders(?bool $noHeaders): static
118+
{
119+
return $this->with(CsvEncoder::NO_HEADERS_KEY, $noHeaders);
120+
}
121+
122+
/**
123+
* Configures the end of line characters.
124+
*/
125+
public function withEndOfLine(?string $endOfLine): static
126+
{
127+
return $this->with(CsvEncoder::END_OF_LINE, $endOfLine);
128+
}
129+
130+
/**
131+
* Configures whether to add the UTF-8 Byte Order Mark (BOM)
132+
* at the beginning of the encoded result or not.
133+
*/
134+
public function withOutputUtf8Bom(?bool $outputUtf8Bom): static
135+
{
136+
return $this->with(CsvEncoder::OUTPUT_UTF8_BOM_KEY, $outputUtf8Bom);
137+
}
138+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Context\Encoder;
13+
14+
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
15+
use Symfony\Component\Serializer\Encoder\JsonDecode;
16+
use Symfony\Component\Serializer\Encoder\JsonEncode;
17+
18+
/**
19+
* A helper providing autocompletion for available JsonEncoder options.
20+
*
21+
* @author Mathias Arlaud <[email protected]>
22+
*/
23+
final class JsonEncoderContextBuilder
24+
{
25+
use ContextBuilderTrait;
26+
27+
/**
28+
* Configures the json_encode flags bitmask.
29+
*
30+
* @see https://www.php.net/manual/en/json.constants.php
31+
*
32+
* @param positive-int|null $options
33+
*/
34+
public function withEncodeOptions(?int $options): static
35+
{
36+
return $this->with(JsonEncode::OPTIONS, $options);
37+
}
38+
39+
/**
40+
* Configures the json_decode flags bitmask.
41+
*
42+
* @see https://www.php.net/manual/en/json.constants.php
43+
*
44+
* @param positive-int|null $options
45+
*/
46+
public function withDecodeOptions(?int $options): static
47+
{
48+
return $this->with(JsonDecode::OPTIONS, $options);
49+
}
50+
51+
/**
52+
* Configures whether decoded objects will be given as
53+
* associative arrays or as nested stdClass.
54+
*/
55+
public function withAssociative(?bool $associative): static
56+
{
57+
return $this->with(JsonDecode::ASSOCIATIVE, $associative);
58+
}
59+
60+
/**
61+
* Configures the maximum recursion depth.
62+
*
63+
* Must be strictly positive.
64+
*
65+
* @param positive-int|null $recursionDepth
66+
*/
67+
public function withRecursionDepth(?int $recursionDepth): static
68+
{
69+
return $this->with(JsonDecode::RECURSION_DEPTH, $recursionDepth);
70+
}
71+
}

0 commit comments

Comments
 (0)