我正在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行之一。
我希望我很害怕,案件有点复杂。
答案 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;