Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: override of protected property from parent #34

Closed
wants to merge 1 commit into from
Closed

fix: override of protected property from parent #34

wants to merge 1 commit into from

Conversation

wopoczynski
Copy link

Symfony version(s) affected

6.3 and above

Description

During validation if we are using abstract base class with any Assert on property in it, and on child class we are overriding the property and Asserts current behaviour is enforcing the parent protected property Asserts.

I.e.:


abstract class ParentClass
{
    public function __construct(
        #[Assert\NotNull]
        protected ?string $value    
    ) {
    }
}
class Child extends ParentClass
{
    public function __construct(
        #[Assert\Expression(expression: 'this.isValid() === true', message: 'value is invalid. ')]
        #[Assert\Length(min: 11, max: 11, exactMessage: 'must be 11 digits long')]
        #[Assert\NotBlank(message: 'value is required')]
        #[Assert\Regex(pattern: '/^[0-9]+$/', message: 'Must contain digits only')]
        protected ?string $value = null
    ) {}
}

How to reproduce

To reproduce you will need validator, annotations and property access

composer require symfony/validator

example.php:

<?php
// composer require symfony/validator
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\ValidatorBuilder;

// parent abstract class
abstract class ParentClass
{
    public function __construct(
        #[Assert\NotNull]
        protected ?string $value    
    ) {
    }
}

// example child class
class Child extends ParentClass
{
    public function __construct(
        #[Assert\Expression(expression: 'this.isValid() === true', message: 'value is invalid. ')]
        #[Assert\Length(min: 11, max: 11, exactMessage: 'must be 11 digits long')]
        #[Assert\NotBlank(message: 'value is required')]
        #[Assert\Regex(pattern: '/^[0-9]+$/', message: 'Must contain digits only')]
        protected ?string $value = null
    ) {}
}

// example test case 
class ExampleTest extends TestCase
{
    /**
     * @dataProvider provideValues
     */
    public function testValidation(string $value, int $violationCount): void
    {
        $validatorBuilder = new ValidatorBuilder();
        $validatorBuilder->enableAnnotationMapping()
            ->setDoctrineAnnotationReader(new AnnotationReader());
        $validator = $validatorBuilder->getValidator();

        $child = new Child($value);

        $this->assertEquals($violationCount, $validator->validate($child)->count());
    }

    /**
     * @return array<int, string|int>[]
     */
    public function provideValues(): array
    {
        return [
            ['07127669600', 0],
            ['35424643507', 0],
            ['11144477735', 0],
            ['11144477734', 1],
            ['11144477725', 1],
            ['11111111111', 1],
            ['55555555555', 1],
            ['aaaaaaaaaaa', 1],
            ['           ', 1],
            ['071276696', 2],
        ];
    }
}

Possible Solution

For the path in \Symfony\Component\Validator\Mapping\ClassMetadata::mergeConstraints:349 handle not only private properties but also protected
in example:

                if ($member instanceof MemberMetadata && (!$member->isProtected($this->name) && !$member->isPrivate($this->name))) {

@github-actions
Copy link
Contributor

Thanks for your pull request! We love contributions.

However, you should instead open a pull request on the main repository:

https://github.com/symfony/symfony

This repository is what we call a "subtree split": a read-only subset of that main repository.

We're looking forward to your PR there!

@github-actions github-actions bot closed this Jul 19, 2023
@wopoczynski
Copy link
Author

added on main repo symfony/symfony#51025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant