From 3fcfca409f3e902f9b52ef293a05792dc8d99786 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 27 Jun 2025 22:23:05 +0200 Subject: [PATCH] [Serializer] Remove deprecated `escape_char` functionality from `CsvEncoder` --- UPGRADE-8.0.md | 20 +++++++++++++++++ src/Symfony/Component/Serializer/CHANGELOG.md | 2 ++ .../Encoder/CsvEncoderContextBuilder.php | 19 ---------------- .../Serializer/Encoder/CsvEncoder.php | 22 +++++-------------- .../Encoder/CsvEncoderContextBuilderTest.php | 21 ------------------ .../Tests/Encoder/CsvEncoderTest.php | 21 ------------------ .../Component/Serializer/composer.json | 1 - 7 files changed, 28 insertions(+), 78 deletions(-) diff --git a/UPGRADE-8.0.md b/UPGRADE-8.0.md index 80948b9422e55..f9516775954b5 100644 --- a/UPGRADE-8.0.md +++ b/UPGRADE-8.0.md @@ -333,6 +333,26 @@ Security Serializer ---------- + * Remove escape character functionality from `CsvEncoder` + + ```diff + use Symfony\Component\Serializer\Encoder\CsvEncoder; + + // Using escape character in encoding + $encoder = new CsvEncoder(); + -$csv = $encoder->encode($data, 'csv', [ + - CsvEncoder::ESCAPE_CHAR_KEY => '\\', + -]); + +$csv = $encoder->encode($data, 'csv'); + + // Using escape character with context builder + use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder; + + $context = (new CsvEncoderContextBuilder()) + - ->withEscapeChar('\\') + ->toArray(); + ``` + * Remove `AbstractNormalizerContextBuilder::withDefaultContructorArguments()`, use `withDefaultConstructorArguments()` instead * Change signature of `NameConverterInterface::normalize()` and `NameConverterInterface::denormalize()` methods: diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 39e2b0a127a29..7ed133f0c8206 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 8.0 --- + * Remove `CsvEncoder::ESCAPE_CHAR_KEY` constant and escape character functionality + * Remove `CsvEncoderContextBuilder::withEscapeChar()` method * Remove `AbstractNormalizerContextBuilder::withDefaultContructorArguments()`, use `withDefaultConstructorArguments()` instead * Change signature of `NameConverterInterface::normalize()` and `NameConverterInterface::denormalize()` methods: diff --git a/src/Symfony/Component/Serializer/Context/Encoder/CsvEncoderContextBuilder.php b/src/Symfony/Component/Serializer/Context/Encoder/CsvEncoderContextBuilder.php index 9f0d6da6fa0e2..1b3a94d953b1b 100644 --- a/src/Symfony/Component/Serializer/Context/Encoder/CsvEncoderContextBuilder.php +++ b/src/Symfony/Component/Serializer/Context/Encoder/CsvEncoderContextBuilder.php @@ -57,25 +57,6 @@ public function withEnclosure(?string $enclosure): static return $this->with(CsvEncoder::ENCLOSURE_KEY, $enclosure); } - /** - * Configures the escape character. - * - * Must be empty or a single character. - * - * @deprecated since Symfony 7.2, to be removed in 8.0 - * - * @throws InvalidArgumentException - */ - public function withEscapeChar(?string $escapeChar): static - { - trigger_deprecation('symfony/serializer', '7.2', 'The "%s" method is deprecated. It will be removed in 8.0.', __METHOD__); - - if (null !== $escapeChar && \strlen($escapeChar) > 1) { - throw new InvalidArgumentException(\sprintf('The "%s" escape character must be empty or a single character.', $escapeChar)); - } - - return $this->with(CsvEncoder::ESCAPE_CHAR_KEY, $escapeChar); - } /** * Configures the key separator when (un)flattening arrays. diff --git a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php index e267730819571..2f8044c2a88c1 100644 --- a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php @@ -25,10 +25,6 @@ class CsvEncoder implements EncoderInterface, DecoderInterface public const FORMAT = 'csv'; public const DELIMITER_KEY = 'csv_delimiter'; public const ENCLOSURE_KEY = 'csv_enclosure'; - /** - * @deprecated since Symfony 7.2, to be removed in 8.0 - */ - public const ESCAPE_CHAR_KEY = 'csv_escape_char'; public const KEY_SEPARATOR_KEY = 'csv_key_separator'; public const HEADERS_KEY = 'csv_headers'; public const ESCAPE_FORMULAS_KEY = 'csv_escape_formulas'; @@ -44,7 +40,6 @@ class CsvEncoder implements EncoderInterface, DecoderInterface private array $defaultContext = [ self::DELIMITER_KEY => ',', self::ENCLOSURE_KEY => '"', - self::ESCAPE_CHAR_KEY => '', self::END_OF_LINE => "\n", self::ESCAPE_FORMULAS_KEY => false, self::HEADERS_KEY => [], @@ -56,10 +51,6 @@ class CsvEncoder implements EncoderInterface, DecoderInterface public function __construct(array $defaultContext = []) { - if (\array_key_exists(self::ESCAPE_CHAR_KEY, $defaultContext)) { - trigger_deprecation('symfony/serializer', '7.2', 'Setting the "csv_escape_char" option is deprecated. The option will be removed in 8.0.'); - } - $this->defaultContext = array_merge($this->defaultContext, $defaultContext); } @@ -88,7 +79,7 @@ public function encode(mixed $data, string $format, array $context = []): string } } - [$delimiter, $enclosure, $escapeChar, $keySeparator, $headers, $escapeFormulas, $outputBom] = $this->getCsvOptions($context); + [$delimiter, $enclosure, $keySeparator, $headers, $escapeFormulas, $outputBom] = $this->getCsvOptions($context); foreach ($data as &$value) { $flattened = []; @@ -101,7 +92,7 @@ public function encode(mixed $data, string $format, array $context = []): string $endOfLine = $context[self::END_OF_LINE] ?? $this->defaultContext[self::END_OF_LINE]; if (!($context[self::NO_HEADERS_KEY] ?? $this->defaultContext[self::NO_HEADERS_KEY])) { - fputcsv($handle, $headers, $delimiter, $enclosure, $escapeChar); + fputcsv($handle, $headers, $delimiter, $enclosure, ''); if ("\n" !== $endOfLine && 0 === fseek($handle, -1, \SEEK_CUR)) { fwrite($handle, $endOfLine); } @@ -109,7 +100,7 @@ public function encode(mixed $data, string $format, array $context = []): string $headers = array_fill_keys($headers, ''); foreach ($data as $row) { - fputcsv($handle, array_replace($headers, $row), $delimiter, $enclosure, $escapeChar); + fputcsv($handle, array_replace($headers, $row), $delimiter, $enclosure, ''); if ("\n" !== $endOfLine && 0 === fseek($handle, -1, \SEEK_CUR)) { fwrite($handle, $endOfLine); } @@ -150,9 +141,9 @@ public function decode(string $data, string $format, array $context = []): mixed $headerCount = []; $result = []; - [$delimiter, $enclosure, $escapeChar, $keySeparator, , , , $asCollection] = $this->getCsvOptions($context); + [$delimiter, $enclosure, $keySeparator, , , , $asCollection] = $this->getCsvOptions($context); - while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, $escapeChar))) { + while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, ''))) { $nbCols = \count($cols); if (null === $headers) { @@ -244,7 +235,6 @@ private function getCsvOptions(array $context): array { $delimiter = $context[self::DELIMITER_KEY] ?? $this->defaultContext[self::DELIMITER_KEY]; $enclosure = $context[self::ENCLOSURE_KEY] ?? $this->defaultContext[self::ENCLOSURE_KEY]; - $escapeChar = $context[self::ESCAPE_CHAR_KEY] ?? $this->defaultContext[self::ESCAPE_CHAR_KEY]; $keySeparator = $context[self::KEY_SEPARATOR_KEY] ?? $this->defaultContext[self::KEY_SEPARATOR_KEY]; $headers = $context[self::HEADERS_KEY] ?? $this->defaultContext[self::HEADERS_KEY]; $escapeFormulas = $context[self::ESCAPE_FORMULAS_KEY] ?? $this->defaultContext[self::ESCAPE_FORMULAS_KEY]; @@ -255,7 +245,7 @@ private function getCsvOptions(array $context): array throw new InvalidArgumentException(\sprintf('The "%s" context variable must be an array or null, given "%s".', self::HEADERS_KEY, get_debug_type($headers))); } - return [$delimiter, $enclosure, $escapeChar, $keySeparator, $headers, $escapeFormulas, $outputBom, $asCollection]; + return [$delimiter, $enclosure, $keySeparator, $headers, $escapeFormulas, $outputBom, $asCollection]; } /** diff --git a/src/Symfony/Component/Serializer/Tests/Context/Encoder/CsvEncoderContextBuilderTest.php b/src/Symfony/Component/Serializer/Tests/Context/Encoder/CsvEncoderContextBuilderTest.php index fe39feb8197ce..7d196a9d4c922 100644 --- a/src/Symfony/Component/Serializer/Tests/Context/Encoder/CsvEncoderContextBuilderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Context/Encoder/CsvEncoderContextBuilderTest.php @@ -122,25 +122,4 @@ public function testCannotSetMultipleBytesAsEnclosure() $this->contextBuilder->withEnclosure('ọ'); } - /** - * @group legacy - */ - public function testCannotSetMultipleBytesAsEscapeChar() - { - $this->expectUserDeprecationMessage('Since symfony/serializer 7.2: The "Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder::withEscapeChar" method is deprecated. It will be removed in 8.0.'); - - $this->expectException(InvalidArgumentException::class); - $this->contextBuilder->withEscapeChar('ọ'); - } - - /** - * @group legacy - */ - public function testWithEscapeCharIsDeprecated() - { - $this->expectUserDeprecationMessage('Since symfony/serializer 7.2: The "Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder::withEscapeChar" method is deprecated. It will be removed in 8.0.'); - $context = $this->contextBuilder->withEscapeChar('\\'); - - $this->assertSame(['csv_escape_char' => '\\'], $context->toArray()); - } } diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php index 34cc940a7d0b3..e686a70fda630 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php @@ -732,25 +732,4 @@ public static function provideIterable() yield 'generator' => [(fn (): \Generator => yield from $data)()]; } - /** - * @group legacy - */ - public function testPassingNonEmptyEscapeCharIsDeprecated() - { - $this->expectUserDeprecationMessage('Since symfony/serializer 7.2: Setting the "csv_escape_char" option is deprecated. The option will be removed in 8.0.'); - $encoder = new CsvEncoder(['csv_escape_char' => '@']); - - $this->assertSame( - [[ - 'A, B@"' => 'D', - 'C' => 'E', - ]], - $encoder->decode(<<<'CSV' - "A, B@"", "C" - "D", "E" - CSV, - 'csv' - ) - ); - } } diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index e11a748d36904..4519c68960ca8 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -17,7 +17,6 @@ ], "require": { "php": ">=8.4", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8" }, "require-dev": { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy