0

The following error message is of type 'MappingException'. It gets when I try to use the entityManager's remove() function in the verifBan function : BanRepository:

<?php

namespace App\Repository;

use App\Entity\Bannissement;
use App\Entity\Utilisateur;
use DateTime;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<Bannissement>
 *
 * @method Bannissement|null find($id, $lockMode = null, $lockVersion = null)
 * @method Bannissement|null findOneBy(array $criteria, array $orderBy = null)
 * @method Bannissement[]    findAll()
 * @method Bannissement[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class BannissementRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Bannissement::class);
    }

    public function save(Bannissement $entity, bool $flush = false): void
    {
        $this->getEntityManager()->persist($entity);

        if ($flush) {
            $this->getEntityManager()->flush();
        }
    }

    public function remove(Bannissement $entity, bool $flush = false): void
    {
        $this->getEntityManager()->remove($entity);

        if ($flush) {
            $this->getEntityManager()->flush();
        }
    }

//    /**
//     * @return Bannissement[] Returns an array of Bannissement objects
//     */
//    public function findByExampleField($value): array
//    {
//        return $this->createQueryBuilder('b')
//            ->andWhere('b.exampleField = :val')
//            ->setParameter('val', $value)
//            ->orderBy('b.id', 'ASC')
//            ->setMaxResults(10)
//            ->getQuery()
//            ->getResult()
//        ;
//    }

//    public function findOneBySomeField($value): ?Bannissement
//    {
//        return $this->createQueryBuilder('b')
//            ->andWhere('b.exampleField = :val')
//            ->setParameter('val', $value)
//            ->getQuery()
//            ->getOneOrNullResult()
//        ;
//    }

    public function verifBan(Utilisateur $user){
        $now = new DateTime();
        $endBan = $user->getBanRecu()->getDateTimeFin();
        if($endBan){
            if($now > $endBan){
                $em = $this->getEntityManager();
                $em->remove($endBan);
                $em->flush();
                return true;
            }else{
                return false;
            }
        }else{
            return true;
        }
    }
}

The verifBan function checks if the user has a ban and compares the end date of the ban with the current date. When a user has a ban that is still in progress, everything happens normally. But as soon as the ban is passed and must be deleted, the error occurs. Here is the Ban Entity :

<?php

namespace App\Entity;

use App\Repository\BannissementRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: BannissementRepository::class)]
class Bannissement
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(type: Types::TEXT)]
    private ?string $raison = null;

    #[ORM\ManyToOne(inversedBy: 'banCrees')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Utilisateur $banneur = null;

    #[ORM\OneToOne(inversedBy: 'banRecu', cascade: ['persist', 'remove'])]
    #[ORM\JoinColumn(nullable: false)]
    private ?Utilisateur $banni = null;

    #[ORM\Column(type: Types::DATETIME_MUTABLE)]
    private ?\DateTimeInterface $dateTimeFin = null;

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

    public function getRaison(): ?string
    {
        return $this->raison;
    }

    public function setRaison(string $raison): self
    {
        $this->raison = $raison;

        return $this;
    }

    public function getBanneur(): ?Utilisateur
    {
        return $this->banneur;
    }

    public function setBanneur(?Utilisateur $banneur): self
    {
        $this->banneur = $banneur;

        return $this;
    }

    public function getBanni(): ?Utilisateur
    {
        return $this->banni;
    }

    public function setBanni(Utilisateur $banni): self
    {
        $this->banni = $banni;

        return $this;
    }

    public function getDateTimeFin(): ?\DateTimeInterface
    {
        return $this->dateTimeFin;
    }

    public function setDateTimeFin(\DateTimeInterface $dateTimeFin): self
    {
        $this->dateTimeFin = $dateTimeFin;

        return $this;
    }
}

And the User Entity :

<?php

namespace App\Entity;

use App\Repository\UtilisateurRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use phpDocumentor\Reflection\Types\Boolean;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UtilisateurRepository::class)]
#[UniqueEntity(fields: ['pseudo'], message: 'There is already an account with this pseudo')]
class Utilisateur implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 180, unique: true)]
    private ?string $pseudo = null;

    #[ORM\Column(length: 180)]
    private string $email;

    #[ORM\Column]
    private array $roles = [];

    /**
     * @var string The hashed password
     */
    #[ORM\Column]
    private ?string $password = null;

    #[ORM\OneToMany(mappedBy: 'Utilisateur', targetEntity: QuizzEffectue::class, orphanRemoval: true)]
    private Collection $quizzEffectues;

    #[ORM\Column(type: 'boolean')]
    private $is_verified = false;

    #[ORM\Column(type: 'string', length: 100)]
    private $resetToken;

    #[ORM\ManyToMany(targetEntity: Proposition::class, inversedBy: 'utilisateurs')]
    private Collection $propositions;

    #[ORM\ManyToMany(targetEntity: self::class, inversedBy: 'estAmisDe')]
    private Collection $amis;

    #[ORM\ManyToMany(targetEntity: self::class, mappedBy: 'amis')]
    private Collection $estAmisDe;

    #[ORM\OneToMany(mappedBy: 'utilisateur', targetEntity: Notification::class, orphanRemoval: true)]
    private Collection $notifications;

    #[ORM\OneToMany(mappedBy: 'envoyeur', targetEntity: Message::class, orphanRemoval: true)]
    private Collection $messagesEnvoyes;

    #[ORM\OneToMany(mappedBy: 'destinataire', targetEntity: Message::class)]
    private Collection $messagesRecus;

    #[ORM\OneToMany(mappedBy: 'banneur', targetEntity: Bannissement::class, orphanRemoval: true)]
    private Collection $banCrees;

    #[ORM\OneToOne(mappedBy: 'banni', cascade: ['persist', 'remove'])]
    #[ORM\JoinColumn(nullable: true)]
    private ?Bannissement $banRecu = null;
    

    public function __construct()
    {
        $this->quizzEffectues = new ArrayCollection();
        $this->propositions = new ArrayCollection();
        $this->amis = new ArrayCollection();
        $this->estAmisDe = new ArrayCollection();
        $this->notifications = new ArrayCollection();
        $this->messagesEnvoyes = new ArrayCollection();
        $this->messagesRecus = new ArrayCollection();
        $this->banCrees = new ArrayCollection();
    }

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

    public function getPseudo(): ?string
    {
        return $this->pseudo;
    }

    public function setPseudo(string $pseudo): self
    {
        $this->pseudo = $pseudo;

        return $this;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return (string) $this->pseudo;
    }

    public function getEmail(): ?string{
        return $this->email;
    }

    public function setEmail(?string $email): self
    {
        $this->email = $email;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    /**
     * @see PasswordAuthenticatedUserInterface
     */
    public function getPassword(): string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    /**
     * @return Collection<int, QuizzEffectue>
     */
    public function getQuizzEffectues(): Collection
    {
        return $this->quizzEffectues;
    }

    public function addQuizzEffectue(QuizzEffectue $quizzEffectue): self
    {
        if (!$this->quizzEffectues->contains($quizzEffectue)) {
            $this->quizzEffectues->add($quizzEffectue);
            $quizzEffectue->setUtilisateur($this);
        }

        return $this;
    }

    public function removeQuizzEffectue(QuizzEffectue $quizzEffectue): self
    {
        if ($this->quizzEffectues->removeElement($quizzEffectue)) {
            // set the owning side to null (unless already changed)
            if ($quizzEffectue->getUtilisateur() === $this) {
                $quizzEffectue->setUtilisateur(null);
            }
        }

        return $this;
    }

    public function getIsVerified(): ?bool
    {
        return $this->is_verified;
    }

    public function setIsVerified(bool $is_verified): self
    {
        $this->is_verified = $is_verified;
        return $this;
    }

    public function getResetToken(): ?string
    {
        return $this->resetToken;
    }

    public function setResetToken(?string $resetToken): self
    {
        $this->resetToken = $resetToken;

        return $this;
    }

    /**
     * @return Collection<int, Proposition>
     */
    public function getPropositions(): Collection
    {
        return $this->propositions;
    }

    public function addProposition(Proposition $proposition): self
    {
        if (!$this->propositions->contains($proposition)) {
            $this->propositions->add($proposition);
        }

        return $this;
    }

    public function removeProposition(Proposition $proposition): self
    {
        $this->propositions->removeElement($proposition);

        return $this;
    }

    /**
     * @return Collection<int, self>
     */
    public function getAmis(): Collection
    {
        return $this->amis;
    }

    public function addAmi(self $ami): self
    {
        if (!$this->amis->contains($ami)) {
            $this->amis->add($ami);
        }

        return $this;
    }

    public function removeAmi(self $ami): self
    {
        $this->amis->removeElement($ami);

        return $this;
    }

    /**
     * @return Collection<int, self>
     */
    public function getEstAmisDe(): Collection
    {
        return $this->estAmisDe;
    }

    public function addEstAmisDe(self $estAmisDe): self
    {
        if (!$this->estAmisDe->contains($estAmisDe)) {
            $this->estAmisDe->add($estAmisDe);
            $estAmisDe->addAmi($this);
        }

        return $this;
    }

    public function removeEstAmisDe(self $estAmisDe): self
    {
        if ($this->estAmisDe->removeElement($estAmisDe)) {
            $estAmisDe->removeAmi($this);
        }

        return $this;
    }

    /**
     * @return Collection<int, Notification>
     */
    public function getNotifications(): Collection
    {
        return $this->notifications;
    }

    public function addNotification(Notification $notification): self
    {
        if (!$this->notifications->contains($notification)) {
            $this->notifications->add($notification);
            $notification->setUtilisateur($this);
        }

        return $this;
    }

    public function removeNotification(Notification $notification): self
    {
        if ($this->notifications->removeElement($notification)) {
            // set the owning side to null (unless already changed)
            if ($notification->getUtilisateur() === $this) {
                $notification->setUtilisateur(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Message>
     */
    public function getMessagesEnvoyes(): Collection
    {
        return $this->messagesEnvoyes;
    }

    public function addMessagesEnvoye(Message $messagesEnvoye): self
    {
        if (!$this->messagesEnvoyes->contains($messagesEnvoye)) {
            $this->messagesEnvoyes->add($messagesEnvoye);
            $messagesEnvoye->setEnvoyeur($this);
        }

        return $this;
    }

    public function removeMessagesEnvoye(Message $messagesEnvoye): self
    {
        if ($this->messagesEnvoyes->removeElement($messagesEnvoye)) {
            // set the owning side to null (unless already changed)
            if ($messagesEnvoye->getEnvoyeur() === $this) {
                $messagesEnvoye->setEnvoyeur(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Message>
     */
    public function getMessagesRecus(): Collection
    {
        return $this->messagesRecus;
    }

    public function addMessagesRecu(Message $messagesRecu): self
    {
        if (!$this->messagesRecus->contains($messagesRecu)) {
            $this->messagesRecus->add($messagesRecu);
            $messagesRecu->setDestinataire($this);
        }

        return $this;
    }

    public function removeMessagesRecu(Message $messagesRecu): self
    {
        if ($this->messagesRecus->removeElement($messagesRecu)) {
            // set the owning side to null (unless already changed)
            if ($messagesRecu->getDestinataire() === $this) {
                $messagesRecu->setDestinataire(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Bannissement>
     */
    public function getBanCrees(): Collection
    {
        return $this->banCrees;
    }

    public function addBanCree(Bannissement $banCree): self
    {
        if (!$this->banCrees->contains($banCree)) {
            $this->banCrees->add($banCree);
            $banCree->setBanneur($this);
        }

        return $this;
    }

    public function removeBanCree(Bannissement $banCree): self
    {
        if ($this->banCrees->removeElement($banCree)) {
            // set the owning side to null (unless already changed)
            if ($banCree->getBanneur() === $this) {
                $banCree->setBanneur(null);
            }
        }

        return $this;
    }

    public function getBanRecu(): ?Bannissement
    {
        return $this->banRecu;
    }

    public function setBanRecu(Bannissement $banRecu): self
    {
        // set the owning side of the relation if necessary
        if ($banRecu->getBanni() !== $this) {
            $banRecu->setBanni($this);
        }

        $this->banRecu = $banRecu;

        return $this;
    }
}

Here is my composer.json for the versions of my bundles :

{
    "type": "project",
    "license": "proprietary",
    "minimum-stability": "stable",
    "prefer-stable": true,
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "doctrine/annotations": "^2.0",
        "doctrine/doctrine-bundle": "^2.8",
        "doctrine/doctrine-migrations-bundle": "^3.2",
        "doctrine/orm": "^2.14",
        "phpdocumentor/reflection-docblock": "^5.3",
        "phpstan/phpdoc-parser": "^1.16",
        "sensio/framework-extra-bundle": "^6.1",
        "symfony/asset": "6.2.*",
        "symfony/console": "6.2.*",
        "symfony/doctrine-messenger": "6.2.*",
        "symfony/dotenv": "6.2.*",
        "symfony/expression-language": "6.2.*",
        "symfony/flex": "^2",
        "symfony/form": "6.2.*",
        "symfony/framework-bundle": "6.2.*",
        "symfony/http-client": "6.2.*",
        "symfony/intl": "6.2.*",
        "symfony/mailer": "6.2.*",
        "symfony/mime": "6.2.*",
        "symfony/monolog-bundle": "^3.0",
        "symfony/notifier": "6.2.*",
        "symfony/process": "6.2.*",
        "symfony/property-access": "6.2.*",
        "symfony/property-info": "6.2.*",
        "symfony/runtime": "6.2.*",
        "symfony/security-bundle": "6.2.*",
        "symfony/serializer": "6.2.*",
        "symfony/string": "6.2.*",
        "symfony/translation": "6.2.*",
        "symfony/twig-bundle": "6.2.*",
        "symfony/validator": "6.2.*",
        "symfony/web-link": "6.2.*",
        "symfony/yaml": "6.2.*",
        "twig/extra-bundle": "^2.12|^3.0",
        "twig/twig": "^2.12|^3.0"
    },
    "config": {
        "allow-plugins": {
            "php-http/discovery": true,
            "symfony/flex": true,
            "symfony/runtime": true
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php72": "*",
        "symfony/polyfill-php73": "*",
        "symfony/polyfill-php74": "*",
        "symfony/polyfill-php80": "*",
        "symfony/polyfill-php81": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false,
            "require": "6.2.*"
        }
    },
    "require-dev": {
        "phpunit/phpunit": "^9.5",
        "symfony/browser-kit": "6.2.*",
        "symfony/css-selector": "6.2.*",
        "symfony/debug-bundle": "6.2.*",
        "symfony/maker-bundle": "^1.0",
        "symfony/phpunit-bridge": "^6.2",
        "symfony/stopwatch": "6.2.*",
        "symfony/web-profiler-bundle": "6.2.*"
    }
}

I have already tried to find solutions but without success, especially here https://github.com/doctrine/orm/issues/8366 but without understanding what they do. I thank you in advance

Easrim
  • 11
  • 3
  • The `chain configured namespace` is just Doctrine's way of telling you that it can't find an entity names `App\Entity\DateTime`. DateTime is an internal PHP class though I suppose you could make an entity with that name if you really wanted to. You have DateTime as an association someplace in your entities. I scanned your posted code and did not see anything. Poke around a bit in your entities and see if you have a DateTime someplace in there. – Cerad Mar 11 '23 at 12:54
  • The issue you linked to goes back to Dec 2020 and involves doctrine/orm 2.8. Current version is 2.14. Maybe you just need an update assuming this is some sort of legacy project. – Cerad Mar 11 '23 at 13:01
  • I had a second Entity for a chat whose named 'Message' also with a DateTimeInterface. But it's all.. – Easrim Mar 11 '23 at 13:14
  • And your doctrine/orm version is? Looks like your code is fairly new so I would expect the version to be more or less up to date but maybe not. And as the answer below suggests, `use DateTime;` should not be in there at all. I'm guessing you added it while debugging. But it is probably is not a factor here. – Cerad Mar 11 '23 at 13:24
  • In the version.php the version is '2.7.1-DEV' – Easrim Mar 11 '23 at 15:01
  • Okay. Time to back away slowly. I think you need to talk to whomever gave you this assignment and ask for some basic training in php/composer/versioning. Even if you get past this particular issue you will just get stuck again without some idea of what is going on. – Cerad Mar 11 '23 at 15:12
  • Yes I understand, but for once the project is purely my initiative and personal. I'm going to search but if anyone has another lead I'm a taker – Easrim Mar 11 '23 at 15:40
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Mar 13 '23 at 00:23

1 Answers1

0

DateTime is in global namespace. Add a slash like \DateTime or import it with a use statement.

Matthias
  • 96
  • 2