phpstan-doctrine
phpstan-doctrine copied to clipboard
False positive for targetEntity interface
I'm not sure if it's a false positive or not, But I didn't know what to put in the title 😄
But I have this Interface
<?php
namespace App\Entity;
use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;
interface UserInterface extends BaseUserInterface
{
public function getId(): int;
public function getEmail(): string;
}
and my User entity implements this interface
But for entities that join with user I'm getting this error
Property App\Entity\UserSocialNetworking::$user type mapping mismatch: property can contain App\Entity\UserInterface but database expects App\Entity\User.
// UserSocialNetworking
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'userSocialNetworks')]
#[ORM\JoinColumn(name: 'user_id', nullable: false)]
protected UserInterface $user;
I tried to use this: https://symfony.com/doc/current/doctrine/resolve_target_entity.html But it doesn't work too!
any idea?
Why not protected User $user;
?
Why not
protected User $user;
?
Hmmmmm I don't remember to have test like it! I'll test and put here the results
I ran into a similar issue, I used MediaInterface
everywhere but PHPStan still complained about the type mismatch.
This is my original definition:
#[ORM\ManyToOne(targetEntity: MediaInterface::class)]
#[ORM\JoinColumn(name: 'icon_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
private ?MediaInterface $icon = null;
PHPStan was happy after I changed the code to make use of the Media entity:
#[ORM\ManyToOne(targetEntity: Media::class)]
#[ORM\JoinColumn(name: 'icon_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
private ?Media $icon = null;
Interestingly, PHPStan only failed in CI. It worked fine locally. Could not figure why, the set-up locally and in CI looks identical to me.
Hi
I'm facing the same issue. I'm using interfaces for my entites to decouple them from doctrine. Using User
as typehint for the private property doesn't work as the setter method also requires the parameter to implement the UserInterface.
I also configured a target entity resolver as the doctrine documentation suggests.
Why not
protected User $user;
?
#[ORM\ManyToOne(targetEntity: UserInterface::class)]
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
private UserInterface $user;
public function setUser(UserInterface $user): FavoriteInterface
{
$this->user = $user;
return $this;
}
public function getUser(): UserInterface
{
return $this->user;
}
Property Favorite::$user type mapping mismatch: property can contain UserInterface but database expects User
Same issue with Collections
/**
* @var Collection<int, AttributeInterface>
*/
#[ORM\OneToMany(mappedBy: "group", targetEntity: AttributeInterface::class)]
protected Collection $attributes;
Property RZ\Roadiz\CoreBundle\Entity\AttributeGroup::$attributes type mapping mismatch: property can contain Doctrine\Common\Collections\Collection<int, RZ\Roadiz\CoreBundle\Model\AttributeInterface> but database expects Doctrine\Common\Collections\Collection&iterable<RZ\Roadiz\CoreBundle\Entity\Attribute>.
Any solution for this issue?
I ended up ignoring the error in the configuration :
ignoreErrors:
- '/Property .* type mapping mismatch: property can contain .*Interface.* but database expects .*/'
If the mapping is wrong, then bin/console doctrine:schema:validate
should return an error.