Symfony 3.4 Дублирование моего объекта User в базе данных - PullRequest
1 голос
/ 16 апреля 2019

У меня очень странная проблема. При аутентификации CAS, когда у меня есть пользователь, вошедший в систему, в базе данных выполняется проверка для возврата соответствующего объекта User (который содержит некоторые атрибуты).

Помимо прочего, сущность User содержит ArrayCollection () пакета (сущности), ManyToMany.

Этот пользователь может затем загружать пакеты. Когда он загружает его, пакет добавляется в его ArrayCollection () (и поэтому у меня есть новая строка в таблице сопоставления между пользователем и пакетом, с идентификатором пользователя и идентификатором пакета).

За исключением того, что, как ни странно, я не могу правильно обработать сущность User, потому что, когда у меня есть тот, который загружает пакет, происходит дублирование всего объекта User в базе данных, и это тот, который выигрывает от добавления пакета в его ArrayCollection ().

Короче говоря, мой пользовательский объект не проходит правильно между страницами.

Мой код:

Когда пользователь аутентифицируется (аутентификация CAS):

/**
     * Traitement personnalisé après récupération du token
     * 
     * Il est possible d'enrichir le token (attributs...) ou d'effectuer des contrôles supplémentaire
     * 
     * @param $token 
     *      Token d'authification généré
     * 
     * @return null
     */
    public function onSuccess($token){

        $mail = $this->ai->getMail();

        $token->setAttribute('mail', $mail);;   
        $token->setAttribute('typeAuth','cas');

        $user = $this->checkBDD($mail);
        $user = $this->serializer->serialize($user, 'json');

        $token->setAttribute('user',$user);



       // $user = $this->checkBDD($mail);
       // $token->setAttribute('user',$user);

    }

Таким образом, мы получаем объект User, связанный с ним (или создаем его, если он подключается впервые).

/**
 * Vérifie si l'utilisateur CAS existe et le crée sinon et renvoi l'objet
 * 
 * @return UserCas
 */
public function checkBDD($mail)
{
    $nb = $this->em->getRepository('PagesBundle:UserCas')->getIfUserCas($mail);

    if($nb == 0)
    {
        //création

        $user = new UserCas;

        $nbPackages = $this->em->getRepository('PagesBundle:Paquet')->getNombrePackages();

        $user->setMail($mail);
        $user->setNbTelechargementsAuto($nbPackages);
        $this->em->persist($user);
        $this->em->flush();
    }

    else
    {
        $user = $this->em->getRepository('PagesBundle:UserCas')->findOneByMail($mail);
    }

    return $user;

    }

Объект User затем сериализуется и передается в качестве атрибута в токене.

Затем он имеет доступ к вкладке «Пакеты», где он может загрузить пакеты и их инструкции. Если он загружает пакет, мы добавляем его в коллекцию ArrayCollection.

/** 
     * Lorsque l'on clique sur un package à télécharger ou sa notice : Téléchargement
     *
     * @Route("/{id}/{type}/file", name="user_paquet_fileDDL")
     */
    public function paquetFileAction(Paquet $paquet, $type)
    {
        $downloadHandler = $this->get('vich_uploader.download_handler'); // On prépare le téléchargement

        if($type == "package") //Si l'utilisateur clique sur le lien du package, on lui donne le fichier package
        {
            $token = $this->get('security.token_storage')->getToken();
            $typeAuth = $token->getAttribute('typeAuth');

            if($typeAuth == 'cas')
            {
                $user = $token->getAttribute('user');
                $user = $this->get('serializer')->deserialize($user, 'Site\PagesBundle\Entity\UserCas', 'json');
            }

            else
            {
                $em = $this->getDoctrine()->getManager(); //Récupération du manager
                //$this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->setDDL("loughin.bastien"); //On décrémente le nombre de DDL pour l'utilisateur en question
                $user = $this->getUser();
            }

            $this->packageDDL($paquet,$user);

            return $downloadHandler->downloadObject($paquet, $fileField = 'paquetFile', Paquet::class, null);
        }

        else //Sinon c'est qu'il a cliqué sur le lien de la notice, alors on lui donne la notice associée au package
        {
            return $downloadHandler->downloadObject($paquet, $fileField = 'noticeFile', Paquet::class, null);
        }

    }

С помощью этой функции:

public function packageDDL($paquet,$user)
    {
        $token = $this->get('security.token_storage')->getToken();
        $typeAuth = $token->getAttribute('typeAuth');

        $em = $this->getDoctrine()->getManager(); //Récupération du manager
        $user->addPackage($paquet);
        $em->persist($user);
        $em->flush();

        if($typeAuth == 'cas')
        {
            $data = $this->get('serializer')->serialize($user, 'json');
            $token->setAttribute('user',$data) ;
        }
    }

Вызывает функцию addPackage ($ paquet), которая находится на Черте.

public function addPackage($package)
{
    $this->packages[] = $package;
    $this->decDDL();

}

Затем, когда это будет сделано и сохранено (сохраняются, сбрасываются), мы повторно сериализуем объект User и помещаем его обратно в токен. Ну, это создает нового пользователя.

Часть моего пользовательского объекта:

/**  
 * @var \Doctrine\Common\Collections\Collection
 * @ORM\ManyToMany(targetEntity="Paquet")  
 * @ORM\JoinTable(name="paquetsDDLUserCas") 
 * @ORM\JoinColumn(nullable=false)
 */  
private $packages;

/**
 * Constructor
 */
public function __construct()
{
    $this->packages = new ArrayCollection();
    $this->setEnabled(true);

}

Что не так? Я не понимаю

EDIT:

Я удалил сериализацию моего Пользователя. Теперь это работает лучше. Но теперь, когда я загружаю пакет, у меня есть это:

Изображение

Мой файл не загружен, но моя база данных отредактирована!

UserCas.php:

<?php

namespace Site\PagesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Site\PagesBundle\Security\Traits\traitUser;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * UserCas
 *
 * @ORM\Table(name="user_cas")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\UserCasRepository")
 * @UniqueEntity("mail")
 */
class UserCas
{

    use traitUser;


    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var int
     *
     * @ORM\Column(name="nbTelechargementsAuto", type="integer", nullable=true)
     */
    private $nbTelechargementsAuto;

    /**
     * @var bool
     *
     * @ORM\Column(name="enabled", type="boolean")
     */
    private $enabled;


    /**
     * @ORM\Column(name="mail", type="string")
     */
    private $mail;

    /**  
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="Paquet")  
     * @ORM\JoinTable(name="paquetsDDLUserCas") 
     * @ORM\JoinColumn(nullable=false)
     */  
    private $packages;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->packages = new ArrayCollection();
        $this->setEnabled(true);

    }




    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }


    /**
     * @return string
     */
    public function getMail()
    {
        return $this->mail;
    }

    public function setMail($mail)
    {
        $this->mail = $mail;
    }


    /**
     * Set enabled
     *
     * @param boolean $enabled
     *
     * @return UserCas
     */
    public function setEnabled($enabled)
    {
        $this->enabled = $enabled;

        return $this;
    }

    public function isEnabled()
    {
        return $this->enabled;
    }

}

Paquet.php:

<?php

namespace Site\PagesBundle\Entity;

use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Site\PagesBundle\Entity\Paquet;
use Site\PagesBundle\Entity\TypeUser;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Paquet
 *
 * @ORM\Table(name="paquet")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\PaquetRepository")
 * @Vich\Uploadable
 */
class Paquet
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;


    /**  
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="TypeUser")  
     * @ORM\JoinTable(name="Packages_des_TypesUser") 
     * @ORM\JoinColumn(nullable=false)
     */  
    private $typeUser;

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

    /** 
     * Get TypeUser 
     * 
     * @return Site\PagesBundle\Entity\TypeUser 
     */ 
    public function getTypeUser() 
    { 
        return $this->typeUser; 
    }

    public function deleteTypeFromTypesUser(TypeUser $type)
    {
        $this->typeUser->removeElement($type);
    }



    /**
     * Set typeUser
     *
     * @param Site\PagesBundle\Entity\TypeUser $typeUser
     *
     * @return Paquet
     */
    public function setTypeUser(Site\PagesBundle\Entity\TypeUser $typeUser)
    {
        $this->typeUser = $typeUser;

        return $this;
    }


    /**
     * @var string
     *
     * @ORM\Column(name="titre", type="string", length=255)
     * @Assert\Length(min=5, max=255, minMessage="Le titre doit comporter au minimum 5 caractères")
     */
    private $titre;

    /**
     * @var string
     *
     * @ORM\Column(name="urlPaquet", type="string", length=255)
     */
    private $urlPaquet;

    /**
     * @Vich\UploadableField(mapping="paquet", fileNameProperty="urlPaquet")
     * @var File
     */
    private $paquetFile;

    /**
     * @ORM\Column(type="datetime")
     *
     * @var \DateTime
    */
    private $updatedAt;

    /**
 * @param File|UploadedFile $unPaquetFile
 *
 * @return Paquet
*/
public function setPaquetFile(File $unPaquetFile = null)
{
    $this->paquetFile = $unPaquetFile;

    if ($unPaquetFile) 
    {
        $this->updatedAt = new \DateTimeImmutable();
    }


    return $this;
}

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     *
     * @return Paquet
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

/**
 * @return File|null
 */
public function getPaquetFile()
{
    return $this->paquetFile;
}


    /**
     * @var string
     *
     * @ORM\Column(name="urlNotice", type="string", length=255,nullable=true)
     */
    private $urlNotice;

    /**
     * @Vich\UploadableField(mapping="notice", fileNameProperty="urlNotice",nullable=true)
     * @var File
     */
    private $noticeFile;

    /**
     * @var string
     *
     * @ORM\Column(name="commentaire", type="text")
     */
    private $commentaire;


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set titre
     *
     * @param string $titre
     *
     * @return Paquet
     */
    public function setTitre($titre)
    {
        $this->titre = $titre;

        return $this;
    }

    /**
     * Get titre
     *
     * @return string
     */
    public function getTitre()
    {
        return $this->titre;
    }

    /**
     * Set urlPaquet
     *
     * @param string $urlPaquet
     *
     * @return Paquet
     */
    public function setUrlPaquet($urlPaquet)
    {
        $this->urlPaquet = $urlPaquet;

        return $this;
    }

    /**
     * Get urlPaquet
     *
     * @return string|null
     */
    public function getUrlPaquet()
    {
        return $this->urlPaquet;
    }

    /**
     * @return File|null
     */
    public function getNoticeFile()
    {
        return $this->noticeFile;
    }

        /**
     * @param File|UploadedFile $uneNoticeFile
     *
     * @return Paquet
    */
    public function setNoticeFile(File $uneNoticeFile = null)
    {
        $this->noticeFile = $uneNoticeFile;

        if ($uneNoticeFile) 
        {
            $this->updatedAt = new \DateTimeImmutable();
        }


        return $this;
}

    /**
     * Set urlNotice
     *
     * @param string $urlNotice
     *
     * @return Paquet
     */
    public function setUrlNotice($urlNotice)
    {
        $this->urlNotice = $urlNotice;

        return $this;
    }

    /**
     * Get urlNotice
     *
     * @return string
     */
    public function getUrlNotice()
    {
        return $this->urlNotice;
    }

    /**
     * Set commentaire
     *
     * @param string $commentaire
     *
     * @return Paquet
     */
    public function setCommentaire($commentaire)
    {
        $this->commentaire = $commentaire;

        return $this;
    }

    /**
     * Get commentaire
     *
     * @return string
     */
    public function getCommentaire()
    {
        return $this->commentaire;
    }
}

И после удаления всего, что есть сериализация, у меня в моем методе:

public function packageDDL($paquet,$user)
    {
        $token = $this->get('security.token_storage')->getToken();
        $typeAuth = $token->getAttribute('typeAuth');

        dump($user);
        $em = $this->getDoctrine()->getManager(); //Récupération du manager
        $user->addPackage($paquet);
        $em->persist($user);
        $em->flush();

        if($typeAuth == 'cas')
        {
            $data = $this->get('serializer')->serialize($user, 'json');
            $token->setAttribute('user',$data) ;
        }
    }

1 Ответ

0 голосов
/ 16 апреля 2019

Ваша проблема с

$em->persist($user);

В вашей функции packageDDL

Вам не нужно сохранять сущность User, поскольку она уже существует.Вы просто хотите сбросить это.Так что просто измените вашу функцию для:

public function packageDDL($paquet,$user)
    {
        $token = $this->get('security.token_storage')->getToken();
        $typeAuth = $token->getAttribute('typeAuth');

        $em = $this->getDoctrine()->getManager(); //Récupération du manager
        $user->addPackage($paquet);
        $em->flush();

        if($typeAuth == 'cas')
        {
            $data = $this->get('serializer')->serialize($user, 'json');
            $token->setAttribute('user',$data) ;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...