Symfony3:原则交易和EventSubscriber

时间:2019-03-20 10:08:49

标签: symfony doctrine event-listener

我正在Symfony 3应用程序中编写一种用于批量用户创建的方法。助焊剂正在上传包含所有必要数据的csv文件。

我创建了一个服务,并在其中编写了此操作的所有逻辑。这是我的服务:

class BulkRegistration
{
    private $em;
    private $validator;
    private $session;

    public function __construct(EntityManagerInterface $em, ValidatorInterface $validator, SessionInterface $session)
    {
        $this->em = $em;
        $this->validator = $validator;
        $this->session = $session;
    }

    public function run(BulkRegistrationData $bulkRegistrationData){
        //todo rimuovere dipendenza nascosta
        $serializer = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]);

        $datas = $serializer->decode(file_get_contents($bulkRegistrationData->csv), 'csv');

        $this->em->getConnection()->beginTransaction();

        try{
            foreach($datas as $data)
            {
                $userData = UserData::create($data);
                $this->validate($userData, 'newUser');

                $userCreate = User::create($userData->user);
                $this->em->persist($userCreate);


                $this->em->flush();
            }

            $this->em->getConnection()->commit();

        } catch (\Exception $e) {
            $this->em->getConnection()->rollback();
            $this->em->close();

            $this->session->getFlashBag()->add('error', $e->getMessage());

            return false;
        }

        return true;
    }

    private function validate ($entity, $validationGroup = null){
        if($validationGroup){
            $errors = $this->validator->validate($entity, null, [$validationGroup]);
        }else{
            $errors = $this->validator->validate($entity);
        }

        if (count($errors) > 0) {
            $errorMessage = '';
            foreach($errors as $error)
            {
                $errorMessage .= $error->getMessage();
            }
            throw new \Exception($errorMessage);
        }

        return;
    }
}

我还编写了此EmailSubscriber,用于每次实体User持续存在时发送激活电子邮件:

class EmailSubscriber implements EventSubscriber
{
    private $activationEmail;

    public function __construct(SendActivationEmail $activationEmail)
    {
        $this->activationEmail = $activationEmail;
    }

    public function getSubscribedEvents()
    {
        return array(
            Events::postPersist,
        );
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        $entityManager = $args->getObjectManager();

        if ($entity instanceof User)
        {
            $this->activationEmail->send($entity);
        }
    }
}

这是问题:

EventSubscriber在事务提交之前捕获持久事件。 我希望或保留数据库中的所有行,或者出现违规响应并要求用户修改其csv文件。

因此,useCase之一可能是发送了一些激活电子邮件,但没有将用户保留在数据库中,例如,因为某些验证违反了csv行之一。

我希望我很害怕,案件有点复杂。

1 个答案:

答案 0 :(得分:0)

我认为您需要将foreach调整为仅在没有错误的情况下才刷新:

foreach($datas as $data) {
    $userData = UserData::create($data);
    try {
        $this->validate($userData, 'newUser');
    } catch (\Exception $e) {
        $this->em->getConnection()->rollback();
        $this->em->close();

        $this->session->getFlashBag()->add('error', $validation);

        return false;
    }
    $userCreate = User::create($userData->user);
    $this->em->persist($userCreate);
}
$this->em->flush();
$this->em->getConnection()->commit();

return true;