Home > Blockchain >  Symfony, when i delete a "deliver" it delete "user" too. How to only delete the
Symfony, when i delete a "deliver" it delete "user" too. How to only delete the

Time:08-15

i have a problem with my code and maybe with with my relations into my database. I will expose you my code next. I want to delete only a deliver, but it delete me the user too. If you can help me because I don't uderstand why it does this. Thank you

My database view

Deliverer.php

<?php

namespace App\Entity;

use App\Repository\DelivererRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

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

    #[ORM\Column(type: Types::DECIMAL, precision: 3, scale: 1, nullable: true)]
    private ?string $rate = null;

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $info = null;

    #[ORM\OneToMany(mappedBy: 'deliverer', targetEntity: Order::class)]
    private Collection $orders;

    #[ORM\ManyToOne(inversedBy: 'deliverers')]
    private ?Vehicle $vehicle = null;

    #[ORM\Column]
    private ?int $nbRate = 0;

    #[ORM\OneToOne(inversedBy: 'deliverer', cascade: ['persist', 'remove'])]
    private ?User $user = null;

    public function __construct()
    {
        $this->orders = new ArrayCollection();
    }

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

    public function getRate(): ?string
    {
        return $this->rate;
    }

    public function setRate(?string $rate): self
    {
        $this->rate = $rate;

        return $this;
    }

    public function getInfo(): ?string
    {
        return $this->info;
    }

    public function setInfo(?string $info): self
    {
        $this->info = $info;

        return $this;
    }

    /**
     * @return Collection<int, Order>
     */
    public function getOrders(): Collection
    {
        return $this->orders;
    }

    public function addOrder(Order $order): self
    {
        if (!$this->orders->contains($order)) {
            $this->orders->add($order);
            $order->setDeliverer($this);
        }

        return $this;
    }

    public function removeOrder(Order $order): self
    {
        if ($this->orders->removeElement($order)) {
            // set the owning side to null (unless already changed)
            if ($order->getDeliverer() === $this) {
                $order->setDeliverer(null);
            }
        }

        return $this;
    }

    public function getVehicle(): ?Vehicle
    {
        return $this->vehicle;
    }

    public function setVehicle(?Vehicle $vehicle): self
    {
        $this->vehicle = $vehicle;

        return $this;
    }

    public function getNbRate(): ?int
    {
        return $this->nbRate;
    }

    public function setNbRate(int $nbRate): self
    {
        $this->nbRate  = 1;

        return $this;
    }

    public function getUser(): ?User
    {
        return $this->user;
    }

    public function setUser(?User $user): self
    {
        $this->user = $user;

        return $this;
    }
}

User.php

<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

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

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

    #[ORM\Column(length: 255)]
    private ?string $address = null;

    #[ORM\ManyToMany(targetEntity: Promotion::class, inversedBy: 'users')]
    private Collection $promotion;

    #[ORM\OneToOne(mappedBy: 'user', cascade: ['persist', 'remove'])]
    private ?RestaurantInfo $restaurantInfo = null;

    #[ORM\OneToMany(mappedBy: 'user', targetEntity: Order::class)]
    private Collection $orders;

    #[ORM\Column(length: 255)]
    private ?string $firstName = null;

    #[ORM\Column(length: 255)]
    private ?string $lastName = null;

    #[ORM\Column(length: 255)]
    private ?string $phoneNumber = null;

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

    #[ORM\ManyToMany(targetEntity: Restaurant::class, inversedBy: 'users')]
    private Collection $favorites;

    #[ORM\OneToOne(mappedBy: 'user', cascade: ['persist', 'remove'])]
    private ?Deliverer $deliverer = null;

    public function __construct()
    {
        $this->promotion = new ArrayCollection();
        $this->orders = new ArrayCollection();
        $this->favorites = new ArrayCollection();
    }


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

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

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

        return $this;
    }

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

    /**
     * @deprecated since Symfony 5.3, use getUserIdentifier instead
     */
    public function getUsername(): string
    {
        return (string) $this->email;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        if($roles == null)
            $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;
    }

    /**
     * Returning a salt is only needed, if you are not using a modern
     * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
     *
     * @see UserInterface
     */
    public function getSalt(): ?string
    {
        return null;
    }

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

    public function getAddress(): ?string
    {
        return $this->address;
    }

    public function setAddress(string $address): self
    {
        $this->address = $address;

        return $this;
    }

    /**
     * @return Collection<int, Promotion>
     */
    public function getPromotion(): Collection
    {
        return $this->promotion;
    }

    public function addPromotion(Promotion $promotion): self
    {
        if (!$this->promotion->contains($promotion)) {
            $this->promotion->add($promotion);
        }

        return $this;
    }

    public function removePromotion(Promotion $promotion): self
    {
        $this->promotion->removeElement($promotion);

        return $this;
    }

    public function getRestaurantInfo(): ?RestaurantInfo
    {
        return $this->restaurantInfo;
    }

    public function setRestaurantInfo(?RestaurantInfo $restaurantInfo): self
    {
        // unset the owning side of the relation if necessary
        if ($restaurantInfo === null && $this->restaurantInfo !== null) {
            $this->restaurantInfo->setUser(null);
        }

        // set the owning side of the relation if necessary
        if ($restaurantInfo !== null && $restaurantInfo->getUser() !== $this) {
            $restaurantInfo->setUser($this);
        }

        $this->restaurantInfo = $restaurantInfo;

        return $this;
    }

    /**
     * @return Collection<int, Order>
     */
    public function getOrders(): Collection
    {
        return $this->orders;
    }

    public function addOrder(Order $order): self
    {
        if (!$this->orders->contains($order)) {
            $this->orders->add($order);
            $order->setUser($this);
        }

        return $this;
    }

    public function removeOrder(Order $order): self
    {
        if ($this->orders->removeElement($order)) {
            // set the owning side to null (unless already changed)
            if ($order->getUser() === $this) {
                $order->setUser(null);
            }
        }

        return $this;
    }

    public function getFirstName(): ?string
    {
        return $this->firstName;
    }

    public function setFirstName(string $firstName): self
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getLastName(): ?string
    {
        return $this->lastName;
    }

    public function setLastName(string $lastName): self
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getPhoneNumber(): ?string
    {
        return $this->phoneNumber;
    }

    public function setPhoneNumber(string $phoneNumber): self
    {
        $this->phoneNumber = $phoneNumber;

        return $this;
    }

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

    public function setBirthDate(\DateTimeInterface $birthDate): self
    {
        $this->birthDate = $birthDate;

        return $this;
    }

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

    /**
     * @return Collection<int, Restaurant>
     */
    public function getFavorites(): Collection
    {
        return $this->favorites;
    }

    public function addFavorite(Restaurant $favorite): self
    {
        if (!$this->favorites->contains($favorite)) {
            $this->favorites->add($favorite);
        }

        return $this;
    }

    public function removeFavorite(Restaurant $favorite): self
    {
        $this->favorites->removeElement($favorite);

        return $this;
    }

    public function getDeliverer(): ?Deliverer
    {
        return $this->deliverer;
    }

    public function setDeliverer(?Deliverer $deliverer): self
    {
        // unset the owning side of the relation if necessary
        if ($deliverer === null && $this->deliverer !== null) {
            $this->deliverer->setUser(null);
        }

        // set the owning side of the relation if necessary
        if ($deliverer !== null && $deliverer->getUser() !== $this) {
            $deliverer->setUser($this);
        }

        $this->deliverer = $deliverer;

        return $this;
    }
}

UserController.php

<?php

namespace App\Controller;

use App\Entity\Deliverer;
use App\Entity\User;
use App\Form\UserType;
use App\Repository\UserRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/user")
 */
class UserController extends AbstractController
{
    /**
     * @Route("/", name="app_user_index", methods={"GET"})
     */
    public function index(UserRepository $userRepository): Response
    {
        // $user = $this->getUser();
        // return $this->render('user/index.html.twig', [
        //     'user' => $user,
        // ]);

        return $this->render('user/index.html.twig', [
            'users' => $userRepository->findAll(),
        ]);
    }

    /**
     * @Route("/new", name="app_user_new", methods={"GET", "POST"})
     */
    public function new(Request $request, UserRepository $userRepository): Response
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);


        if ($form->isSubmitted() && $form->isValid()) {
            $userRepository->add($user, true);

            return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->renderForm('user/new.html.twig', [
            'user' => $user,
            'form' => $form,
        ]);
    }

    /**
     * @Route("/{id}", name="app_user_show", methods={"GET"})
     */
    public function show(User $user,  $id): Response
    {
        $vehicle = 1;
        $vehicle = 1;
        $user_session = $this->getUser();
        $deliverer = $user->getDeliverer();
        if ($deliverer) {
            $vehicle = $deliverer->getVehicle();
            $orders = $deliverer->getOrders();
        }
        $favorites = $user->getFavorites();

        // Profil utilisateur seulement accessible à celui qui est connecté. Si url modifier avec un id d'un autre user on en peut pas voir le profil de l'autre
        if ($user_session->getId() == intval($id)) {
            return $this->render('user/show.html.twig', [
                'user' => $user,
                'deliverer' => $deliverer,
                'vehicle' => $vehicle,
                'orders' => $orders,
                'favorites' => $favorites,
            ]);
        }


        $id = 1000;
        return $this->render('user/show.html.twig', [
            'user' => $user_session,
            'deliverer' => $deliverer,
            'vehicle' => $vehicle,
            'orders' => $orders,
            'favorites' => $favorites,
        ]);
    }

    /**
     * @Route("/{id}/edit", name="app_user_edit", methods={"GET", "POST"})
     */
    public function edit(Request $request, User $user, UserRepository $userRepository): Response
    {
        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $userRepository->add($user, true);

            return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->renderForm('user/edit.html.twig', [
            'user' => $user,
            'form' => $form,
        ]);
    }

    /**
     * @Route("/{id}", name="app_user_delete", methods={"POST"})
     */
    public function delete(Request $request, User $user, UserRepository $userRepository): Response
    {
        if ($this->isCsrfTokenValid('delete' . $user->getId(), $request->request->get('_token'))) 
        {
            $userRepository->remove($user, true);
        }

        return $this->redirectToRoute('app_user_index', [], Response::HTTP_SEE_OTHER);
    }
}

DelivererController.php

<?php

namespace App\Controller;

use App\Entity\Deliverer;
use App\Form\DelivererType;
use App\Repository\DelivererRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

/**
 * @Route("/deliverer")
 */
class DelivererController extends AbstractController
{
    /**
     * @Route("/", name="app_deliverer_index", methods={"GET"})
     */
    public function index(DelivererRepository $delivererRepository): Response
    {
        $user = $this->getUser();
        return $this->render('deliverer/index.html.twig', [
            'deliverers' => $delivererRepository->findAll(),
            'user' => $user,
        ]);
    }

    /**
     * @Route("/new", name="app_deliverer_new", methods={"GET", "POST"})
     */
    public function new(Request $request, DelivererRepository $delivererRepository, EntityManagerInterface $entityManager): Response
    {
        $user = $this->getUser();
        $user_id = $user->getId();
        $user_roles = $user->getRoles();

        // Si l'utilisateur est déjà un livreur impossible de le devenir, retourne à sa page profil
        if (in_array('ROLE_LIVREUR', $user_roles)) {
            return $this->redirectToRoute('app_user_show', ['id' => $user_id]);
        }

        $deliverer = new Deliverer();
        $form = $this->createForm(DelivererType::class, $deliverer);
        $form->handleRequest($request);

        $id = 1326580;

        if ($form->isSubmitted() && $form->isValid()) {
            $entityManager->persist($deliverer);

            $id = 1000;
            $user->setRoles(array('ROLE_USER', 'ROLE_LIVREUR'));
            $user->setDeliverer($deliverer);

            $entityManager->persist($user);
            $entityManager->flush();


            // Reload user authentification with new roles. If not error to resdirection because user entity is null
            $token = new UsernamePasswordToken($this->getUser(), null, 'main', $this->getUser()->getRoles());
            $this->get('security.token_storage')->setToken($token);

            $user_id = $this->get('security.token_storage')->getToken()->getUser()->getId();
            $user = $this->getUser();

            return $this->redirectToRoute('app_user_show', ['id' => $user_id]);
        }

        return $this->renderForm('deliverer/new.html.twig', [
            'deliverer' => $deliverer,
            'form' => $form,
            'user' => $user,
            'id' => $id,
        ]);
    }

    /**
     * @Route("/{id}", name="app_deliverer_show", methods={"GET"})
     */
    public function show(Deliverer $deliverer): Response
    {
        $user = $this->getUser();
        return $this->render('deliverer/show.html.twig', [
            'deliverer' => $deliverer,
            'user' => $user,
        ]);
    }

    /**
     * @Route("/{id}/edit", name="app_deliverer_edit", methods={"GET", "POST"})
     */
    public function edit(Request $request, Deliverer $deliverer, DelivererRepository $delivererRepository): Response
    {
        $form = $this->createForm(DelivererType::class, $deliverer);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $delivererRepository->add($deliverer, true);

            $user_id = $this->get('security.token_storage')->getToken()->getUser()->getId();

            return $this->redirectToRoute('app_user_show', ['id' => $user_id]);
            // return $this->redirectToRoute('app_deliverer_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->renderForm('deliverer/edit.html.twig', [
            'deliverer' => $deliverer,
            'form' => $form,
        ]);
    }

    /**
     * @Route("/{id}", name="app_deliverer_delete", methods={"POST"})
     */
    public function delete(Request $request, Deliverer $deliverer, DelivererRepository $delivererRepository): Response
    {
        if ($this->isCsrfTokenValid('delete'.$deliverer->getId(), $request->request->get('_token'))) {
            $delivererRepository->remove($deliverer, true);
        }

        return $this->redirectToRoute('app_deliverer_index', [], Response::HTTP_SEE_OTHER);
    }
}

CodePudding user response:

Deliverer.php

remplace

[ORM\OneToOne(inversedBy: 'deliverer', cascade: ['persist', 'remove'])]

by

[ORM\OneToOne(inversedBy: 'deliverer', cascade: ['persist'])]
<?php

namespace App\Entity;

use App\Repository\DelivererRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

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

    #[ORM\Column(type: Types::DECIMAL, precision: 3, scale: 1, nullable: true)]
    private ?string $rate = null;

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $info = null;

    #[ORM\OneToMany(mappedBy: 'deliverer', targetEntity: Order::class)]
    private Collection $orders;

    #[ORM\ManyToOne(inversedBy: 'deliverers')]
    private ?Vehicle $vehicle = null;

    #[ORM\Column]
    private ?int $nbRate = 0;

    #[ORM\OneToOne(inversedBy: 'deliverer', cascade: ['persist'])]
    private ?User $user = null;
...

CodePudding user response:

to complete @Yusuf answer:

Thanks to cascade: remove, you can easily delete a user and all linked comments without having to loop through them:

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

In your annotation, you just need to remove the option "remove" in the cascade option.

  • Related