【问题标题】:Doctrine inserting on POST_WRITE event with Symfony 5 and APIplatform使用 Symfony 5 和 APIplatform 在 POST_WRITE 事件上插入教义
【发布时间】:2021-03-17 14:10:34
【问题描述】:

我想在每次用户创建团队时添加一个新的用户团队(获取团队、用户和角色)。我创建了一个事件订阅者 TeamFirstUserAdminSubscriber.php 但它不起作用并且我没有错误消息。

这是我的数据库模型:

这里是 TeamFirstUserAdminSubscriber.php 文件

<?php


namespace App\Events;


use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Team;
use App\Entity\UserTeam;
use App\Repository\RoleUserTeamRepository;
use App\Repository\TeamRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;

class TeamFirstUserAdminSubscriber implements EventSubscriberInterface

{
private $security;
private $repository;
private $repositoryT;
private $manager;

public function __construct(Security $security, RoleUserTeamRepository $repository, TeamRepository $repositoryT, EntityManagerInterface $manager)
{
    $this->security = $security;
    $this->repository = $repository;
    $this->repositoryT = $repositoryT;
    $this->manager = $manager;
}

public static function getSubscribedEvents()
{
    return[
        KernelEvents::VIEW => ['setInstanceUserTeam', EventPriorities::POST_WRITE],
    ];
}

public function setInstanceUserTeam(ViewEvent $event)
{
    $team = $event->getControllerResult();
    $method = $event->getRequest()->getMethod();

    if($team instanceof Team && $method === 'POST')
    {
        //get the user connected
        $user = $this->security->getUser();

        //get the last team created
        $lastTeam = $this->repositoryT->findLastTeamCreated();

        //get the admin role (NOT the symfony one)
        $admin = $this->repository->findOneByRoleAdmin('Admin');

        //should create a new UserTeam instance with the User, the Team and the RoleUserTeam wanted
        $userTeam = new UserTeam();
        $userTeam->setUser($user);
        $userTeam->setTeam($lastTeam);
        $userTeam->setRoleUserTeam($admin);

        $manager = $this->manager;
        $manager->persist($userTeam);
        $manager->flush();


    }

}

当我用邮递员尝试时,新的 UserTeam 没有在数据库中创建,但团队创建得很好。 我想我错过了一些东西,但我不知道是什么。 谁能帮帮我?

【问题讨论】:

    标签: php symfony doctrine api-platform.com


    【解决方案1】:

    我看不到您的完整代码(控制器、表单等),但您可以在没有事件侦听器的情况下实现这一点。如您所知,为用户分配什么团队,为什么不在创建用户对象时将其分配给实体。例如,如果您在控制器中使用表单

    public function addAdminUser(Request $request, RoleUserTeamRepository $repository, TeamRepository $repositoryT, EntityManagerInterface $manager)

    {

    $user = new User();

    $form = $this->createForm(UserForm::class, $user);
    
    $form->handleRequest($form);
    
    
    if ($form->isSubmitted && $form->isValid()) {
        
      //get the last team created
        
      $lastTeam = $this->repositoryT->findLastTeamCreated();
        
      //get the admin role (NOT the symfony one)

      $admin = $this->repository->findOneByRoleAdmin('Admin');

        
      //should create a new UserTeam instance with the User, the Team and the 
      RoleUserTeam wanted
        
    
      $userTeam = new UserTeam();
        
      $userTeam->setUser($user);
        
      $userTeam->setTeam($lastTeam);
        
      $userTeam->setRoleUserTeam($admin);
        
      $user->setUserTeam($userTeam);

        
      //persist the user
        
      $manager->persist($user);
        
      $manager->flush();
    
     }
    
    }
    

    如果你想使用事件,我建议使用 Doctrine 事件。您可以在用户实体上使用 prePersist 事件来实现相同的结果。 Doctrine Events

    【讨论】:

    • 我忘了说我没有控制器也没有表单,因为我只用 API Platform 构建一个 API,用 ReactJS 构建我的前端。
    • 好的,你尝试过 PRE_WRITE 事件吗?还要检查事件的优先级。您可能需要在 services.yml 文件中手动注册订阅者。
    【解决方案2】:

    我解决了我的问题,我需要在我的实体中保持级联。在这里,如果它可以帮助一些人: 我在 Team 实体中有这个

    public function __construct()
    {
        $this->id = Team::class;
        $this->userTeams = new ArrayCollection();
        $this->categories = new ArrayCollection();
    }
    
    public function userTeam()
    {
        $newUserTeam = new UserTeam();
        $newUserTeam->setTeam($this);
        $this->userTeams->add($newUserTeam);
    }
    

    UserTeam 实体,我必须在关系 ManyToOne 中添加 cascade={"persist"}:

    class UserTeam
    {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;
    
    /**
     * @ORM\ManyToOne(targetEntity=Team::class, inversedBy="userTeams", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"users_read", "userTeam_read"})
     */
    private $team;
    

    还有我修改的 TeamByUserSubscriber :

        <?php
    
    namespace App\Events;
    
    use ApiPlatform\Core\EventListener\EventPriorities;
    use App\Entity\Team;
    use App\Entity\UserTeam;
    use App\Repository\RoleUserTeamRepository;
    use App\Repository\TeamRepository;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpKernel\Event\ViewEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\Security\Core\Security;
    
    class TeamByUserSubscriber implements EventSubscriberInterface
    {
    private $security;
    private $repository;
    private $entityManager;
    
    public function __construct(Security $security, RoleUserTeamRepository $repository, EntityManagerInterface $entityManager)
    {
        $this->security = $security;
        $this->repository = $repository;
        $this->entityManager = $entityManager;
    }
    
    public static function getSubscribedEvents()
    {
        return[
            KernelEvents::VIEW => ['setUserForTeam', EventPriorities::PRE_VALIDATE],
        ];
    }
    
    public function setUserForTeam(ViewEvent $event)
    {
        $team = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();
    
        if($team instanceof Team && $method === 'POST')
        {
            //get the connected User
            $user = $this->security->getUser();
    
            //put the current User to the team we are creating (as the creator of the team)
            $team->setUser($user);
    
            //get the Admin role from the RoleUserTeam entity
            $admin = $this->repository->findOneByRoleAdmin('Admin');
    
            //create a new instance of UserTeam with the connected User, the Team we are creating and the role
            $userTeam = new UserTeam();
            $userTeam->setUser($user);
            $userTeam->setTeam($team);
            $userTeam->setRoleUserTeam($admin);
            $manager = $this->entityManager;
            $manager->persist($userTeam);
            $manager->flush();
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多