From e21772906691f6513f93ab47ad82efb9ee456a6b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 28 Jun 2019 18:16:38 +0200 Subject: [PATCH] deprecate non-string constraint violation codes --- UPGRADE-4.4.md | 3 ++ UPGRADE-5.0.md | 2 ++ src/Symfony/Component/Validator/CHANGELOG.md | 3 ++ .../Validator/ConstraintViolation.php | 4 +++ .../Validator/Constraints/FileValidator.php | 16 ++++----- .../Tests/ConstraintViolationTest.php | 22 +++++++++++- .../Tests/Constraints/FileValidatorTest.php | 20 +++++------ .../ConstraintViolationBuilderTest.php | 36 +++++++++++++++++++ .../Violation/ConstraintViolationBuilder.php | 4 +++ 9 files changed, 91 insertions(+), 19 deletions(-) create mode 100644 src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php diff --git a/UPGRADE-4.4.md b/UPGRADE-4.4.md index 96c170675c..c8fdb04bcc 100644 --- a/UPGRADE-4.4.md +++ b/UPGRADE-4.4.md @@ -90,5 +90,8 @@ TwigBridge Validator --------- + * Deprecated using anything else than a `string` as the code of a `ConstraintViolation`, a `string` type-hint will + be added to the constructor of the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` + method in 5.0. * Deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. Pass it as the first argument instead. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 442572c468..bfa569bb0b 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -454,6 +454,8 @@ TwigBridge Validator -------- + * Removed support for non-string codes of a `ConstraintViolation`. A `string` type-hint was added to the constructor of + the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` method. * An `ExpressionLanguage` instance or null must be passed as the first argument of `ExpressionValidator::__construct()` * The `checkMX` and `checkHost` options of the `Email` constraint were removed * The `Email::__construct()` 'strict' property has been removed. Use 'mode'=>"strict" instead. diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 8a85ee35ef..f12cae5dfb 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -4,6 +4,9 @@ CHANGELOG 4.4.0 ----- + * using anything else than a `string` as the code of a `ConstraintViolation` is deprecated, a `string` type-hint will + be added to the constructor of the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` + method in 5.0 * deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. Pass it as the first argument instead. * added the `compared_value_path` parameter in violations when using any comparison constraint with the `propertyPath` option. diff --git a/src/Symfony/Component/Validator/ConstraintViolation.php b/src/Symfony/Component/Validator/ConstraintViolation.php index 2ec15e4309..e615cd3921 100644 --- a/src/Symfony/Component/Validator/ConstraintViolation.php +++ b/src/Symfony/Component/Validator/ConstraintViolation.php @@ -56,6 +56,10 @@ class ConstraintViolation implements ConstraintViolationInterface $message = ''; } + if (null !== $code && !\is_string($code)) { + @trigger_error(sprintf('Not using a string as the error code in %s() is deprecated since Symfony 4.4. A type-hint will be added in 5.0.', __METHOD__), E_USER_DEPRECATED); + } + $this->message = $message; $this->messageTemplate = $messageTemplate; $this->parameters = $parameters; diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index 7266669213..ac23f6fb8e 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -65,49 +65,49 @@ class FileValidator extends ConstraintValidator $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) ->setParameter('{{ limit }}', $limitAsString) ->setParameter('{{ suffix }}', $suffix) - ->setCode(UPLOAD_ERR_INI_SIZE) + ->setCode((string) UPLOAD_ERR_INI_SIZE) ->addViolation(); return; case UPLOAD_ERR_FORM_SIZE: $this->context->buildViolation($constraint->uploadFormSizeErrorMessage) - ->setCode(UPLOAD_ERR_FORM_SIZE) + ->setCode((string) UPLOAD_ERR_FORM_SIZE) ->addViolation(); return; case UPLOAD_ERR_PARTIAL: $this->context->buildViolation($constraint->uploadPartialErrorMessage) - ->setCode(UPLOAD_ERR_PARTIAL) + ->setCode((string) UPLOAD_ERR_PARTIAL) ->addViolation(); return; case UPLOAD_ERR_NO_FILE: $this->context->buildViolation($constraint->uploadNoFileErrorMessage) - ->setCode(UPLOAD_ERR_NO_FILE) + ->setCode((string) UPLOAD_ERR_NO_FILE) ->addViolation(); return; case UPLOAD_ERR_NO_TMP_DIR: $this->context->buildViolation($constraint->uploadNoTmpDirErrorMessage) - ->setCode(UPLOAD_ERR_NO_TMP_DIR) + ->setCode((string) UPLOAD_ERR_NO_TMP_DIR) ->addViolation(); return; case UPLOAD_ERR_CANT_WRITE: $this->context->buildViolation($constraint->uploadCantWriteErrorMessage) - ->setCode(UPLOAD_ERR_CANT_WRITE) + ->setCode((string) UPLOAD_ERR_CANT_WRITE) ->addViolation(); return; case UPLOAD_ERR_EXTENSION: $this->context->buildViolation($constraint->uploadExtensionErrorMessage) - ->setCode(UPLOAD_ERR_EXTENSION) + ->setCode((string) UPLOAD_ERR_EXTENSION) ->addViolation(); return; default: $this->context->buildViolation($constraint->uploadErrorMessage) - ->setCode($value->getError()) + ->setCode((string) $value->getError()) ->addViolation(); return; diff --git a/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php b/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php index b43e51f273..d38431b640 100644 --- a/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php +++ b/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php @@ -64,7 +64,7 @@ EOF; 'some_value', null, null, - 0 + '0' ); $expected = <<<'EOF' @@ -108,4 +108,24 @@ EOF; $this->assertSame($expected, (string) $violation); } + + /** + * @group legacy + * @expectedDeprecation Not using a string as the error code in Symfony\Component\Validator\ConstraintViolation::__construct() is deprecated since Symfony 4.4. A type-hint will be added in 5.0. + */ + public function testNonStringCode() + { + $violation = new ConstraintViolation( + '42 cannot be used here', + 'this is the message template', + [], + ['some_value' => 42], + 'some_value', + null, + null, + 42 + ); + + self::assertSame(42, $violation->getCode()); + } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php index c5105c20cf..7e75f8151f 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php @@ -435,23 +435,23 @@ abstract class FileValidatorTest extends ConstraintValidatorTestCase public function uploadedFileErrorProvider() { $tests = [ - [UPLOAD_ERR_FORM_SIZE, 'uploadFormSizeErrorMessage'], - [UPLOAD_ERR_PARTIAL, 'uploadPartialErrorMessage'], - [UPLOAD_ERR_NO_FILE, 'uploadNoFileErrorMessage'], - [UPLOAD_ERR_NO_TMP_DIR, 'uploadNoTmpDirErrorMessage'], - [UPLOAD_ERR_CANT_WRITE, 'uploadCantWriteErrorMessage'], - [UPLOAD_ERR_EXTENSION, 'uploadExtensionErrorMessage'], + [(string) UPLOAD_ERR_FORM_SIZE, 'uploadFormSizeErrorMessage'], + [(string) UPLOAD_ERR_PARTIAL, 'uploadPartialErrorMessage'], + [(string) UPLOAD_ERR_NO_FILE, 'uploadNoFileErrorMessage'], + [(string) UPLOAD_ERR_NO_TMP_DIR, 'uploadNoTmpDirErrorMessage'], + [(string) UPLOAD_ERR_CANT_WRITE, 'uploadCantWriteErrorMessage'], + [(string) UPLOAD_ERR_EXTENSION, 'uploadExtensionErrorMessage'], ]; if (class_exists('Symfony\Component\HttpFoundation\File\UploadedFile')) { // when no maxSize is specified on constraint, it should use the ini value - $tests[] = [UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ + $tests[] = [(string) UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ '{{ limit }}' => UploadedFile::getMaxFilesize() / 1048576, '{{ suffix }}' => 'MiB', ]]; // it should use the smaller limitation (maxSize option in this case) - $tests[] = [UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ + $tests[] = [(string) UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ '{{ limit }}' => 1, '{{ suffix }}' => 'bytes', ], '1']; @@ -464,14 +464,14 @@ abstract class FileValidatorTest extends ConstraintValidatorTestCase // it correctly parses the maxSize option and not only uses simple string comparison // 1000M should be bigger than the ini value - $tests[] = [UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ + $tests[] = [(string) UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ '{{ limit }}' => $limit, '{{ suffix }}' => $suffix, ], '1000M']; // it correctly parses the maxSize option and not only uses simple string comparison // 1000M should be bigger than the ini value - $tests[] = [UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ + $tests[] = [(string) UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', [ '{{ limit }}' => '0.1', '{{ suffix }}' => 'MB', ], '100K']; diff --git a/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php new file mode 100644 index 0000000000..622bcbd8c9 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Violation; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; +use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; + +class ConstraintViolationBuilderTest extends TestCase +{ + /** + * @group legacy + * @expectedDeprecation Not using a string as the error code in Symfony\Component\Validator\Violation\ConstraintViolationBuilder::setCode() is deprecated since Symfony 4.4. A type-hint will be added in 5.0. + * @expectedDeprecation Not using a string as the error code in Symfony\Component\Validator\ConstraintViolation::__construct() is deprecated since Symfony 4.4. A type-hint will be added in 5.0. + */ + public function testNonStringCode() + { + $constraintViolationList = new ConstraintViolationList(); + (new ConstraintViolationBuilder($constraintViolationList, new ConstraintA(), 'invalid message', [], null, 'foo', 'baz', new IdentityTranslator())) + ->setCode(42) + ->addViolation(); + + self::assertSame(42, $constraintViolationList->get(0)->getCode()); + } +} diff --git a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php index ed18f6fa8e..9b3cfa68ab 100644 --- a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php +++ b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php @@ -132,6 +132,10 @@ class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface */ public function setCode($code) { + if (null !== $code && !\is_string($code)) { + @trigger_error(sprintf('Not using a string as the error code in %s() is deprecated since Symfony 4.4. A type-hint will be added in 5.0.', __METHOD__), E_USER_DEPRECATED); + } + $this->code = $code; return $this;