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

[PropertyInfo] [Validator] the new auto mapping is not working with non found property #31796

Closed
elhadraoui opened this issue Jun 2, 2019 · 6 comments

Comments

@elhadraoui
Copy link

@elhadraoui elhadraoui commented Jun 2, 2019

Symfony version(s) affected: 4.3.0

Description
When we are using a function like public function addSomething() and no property with name: something not existing the exception "The entity has no field with name ..." is thrown.

How to reproduce
Create an entity with function addSomething() without property something and enable the auto mapping for validation.

Possible Solution

Additional context

@cronk1986

This comment has been minimized.

Copy link

@cronk1986 cronk1986 commented Jun 2, 2019

Today I updated Symfony 4.2 to 4.3 and now I can't save entities that implement Interfaces or use traits, Mapping/PropertyMetadata class try to find a property in a interface and throw an error, my code snippet:

interface GetterIdInterface
{
  public function getId();
}
class MyEntity implements GetterIdInterface
{

    /**
     * @var string
     *
     * @ORM\Column(name="id", type="guid", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
     * @Assert\NotBlank()
     */
    protected $title;

    public function getId()
    {
        return $this->id;
    } 

    /**
     * Set title.
     *
     * @param string $title
     *
     * @return MyEntity
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title.
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    } 
 
}
//When I try to save MyEntity throw an exception:
...
$entity = new MyEntity();
$em->persist($entity);
$em->flush();
...
Property "title" does not exist in class "GetterIdInterface"

Symfony\Component\Validator\Exception\ValidatorException in vendor/symfony/validator/Mapping/PropertyMetadata.php (line 40)
 /* @throws ValidatorException     */    
public function __construct(string $class, string $name)    
{        
    if (!property_exists($class, $name)) {            
        throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $name, $class));        
    }        
    parent::__construct($class, $name, $name);    
}

any idea?

@linaori

This comment has been minimized.

Copy link
Contributor

@linaori linaori commented Jun 3, 2019

Is this issue related to #31715?

@cronk1986

This comment has been minimized.

Copy link

@cronk1986 cronk1986 commented Jun 3, 2019

I don't know if it's exactly the same, because I can save all my entities if they not implement an Interface o use Traits...
At the end maybe is the same issue.

@Aerendir

This comment has been minimized.

Copy link

@Aerendir Aerendir commented Jun 5, 2019

I copy and paste here for clarity and more context, my (closed) issue (#31873):

Symfony version(s) affected: 4.3.0

Description
In one of my forms I receive this error:

Property "domain" does not exist in class "App\Entity\MyEntity"

Obviously it doesn't exist as the property is actually $domains.

So I have a method addDomain and a method removeDomain.

The problem is caused by the validation auto_mapping: if I disable it, the problem disappears

framework:
    validation:
        email_validation_mode: html5

        # Enables validator auto-mapping support.
        # For instance, basic validation constraints will be inferred from Doctrine's metadata.
        #auto_mapping:
        #    App\Entity\: []

The PropertyInfo causes a lot of troubles: it tries to guess properties starting from methods: this causes a lot of strange behaviors. Not strictly related to this, this is another example: php-translation/symfony-bundle#309

@xabbuh xabbuh removed the DoctrineBridge label Jun 5, 2019
@weaverryan

This comment has been minimized.

Copy link
Member

@weaverryan weaverryan commented Jun 7, 2019

I can confirm this, here is a simple reproducer: https://github.com/weaverryan/symfony-automapper-reproducer - you can see the simple steps in the history:

  1. install validator & property-info
  2. Create a public setter method in src/Entity without a corresponding property
  3. Try to validate it (e.g. go to / in the reproducer):

Screen Shot 2019-06-07 at 11 13 06 AM

nicolas-grekas added a commit that referenced this issue Jun 7, 2019
…-existent property (weaverryan)

This PR was merged into the 4.3 branch.

Discussion
----------

PropertyInfoLoader should not try to add validation to non-existent property

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #31796 (see #31796 (comment))
| License       | MIT
| Doc PR        | not needed

With auto-validation, if a class has a setter (e.g. `setFoo()`) but there is no `foo` property, it still tries to add validation to that property, resulting in a:

> Property "foo" does not exist in class "App\Entity\Bar

This fixes that. I believe it's "just this simple", but I don't have any experience with the code in this area yet.

Cheers!

Commits
-------

b702598 Fixing bug where PropertyInfoLoader tried to add validation to non-existent properties
@cronk1986

This comment has been minimized.

Copy link

@cronk1986 cronk1986 commented Jun 8, 2019

Perfect, now works!
Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.