使用api-platform持久化相关资源字段



我正在使用api平台的项目等。在这个项目中,我有两个资源(Donateur和Don)由ManyToOne关系发布。一个Don被关联到一个Donateur,一个Donateur可以被关联到更多Don。我有一个数据持久化的数据库资源。

Donateur.php

<?php
namespace AppEntity;
use ApiPlatformCoreAnnotationApiResource;
use AppRepositoryDonateurRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentSerializerAnnotationGroups;
/**
* @ApiResource(
*      normalizationContext={
*          "groups"={
*              "read:Donateur:collection"
*          }
*      },
*      denormalizationContext={
*          "groups"={
*              "write:Donateur"
*          }
*      },
*      collectionOperations={
*          "get", "post"
*      },
*      itemOperations={
*          "get", "patch", "delete"
*      }
* )
* @ORMEntity(repositoryClass=DonateurRepository::class)
*/
class Donateur
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
* @Groups("read:Donateur:collection")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
* @Groups({"read:Donateur:collection", "write:Donateur"})
*/
private $nom;
/**
* @ORMColumn(type="float")
* @Groups({"read:Donateur:collection", "write:Don"})
*/
private $solde;
/**
* @ORMOneToMany(targetEntity=Don::class, mappedBy="donateur")
*/
private $dons;

Don.php

<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use AppRepositoryDonRepository;
use ApiPlatformCoreAnnotationApiResource;
use SymfonyComponentSerializerAnnotationGroups;
/**
* @ApiResource(
*      normalizationContext={
*          "groups"={
*              "read:Don:item",
*              "read:Don:collection"
*          }
*      },
*      denormalizationContext={
*          "groups"={
*              "write:Don"
*          }
*      },
*      collectionOperations={
*          "get", "post"
*      },
*      itemOperations={
*          "get"={
*              "normalization_context"={
*                  "groups"={
*                      "read:Don:item",
*                      "read:Don:collection"
*                  }
*              }
*          }, 
*          "patch", "delete"
*      }
* )
* @ORMEntity(repositoryClass=DonRepository::class)
*/
class Don
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMManyToOne(targetEntity=Donateur::class, inversedBy="dons")
* @ORMJoinColumn(nullable=false)
* @Groups({"read:Don:collection", "write:Don"})
*/
private $donateur;
/**
* @ORMColumn(type="date", nullable=true)
* @Groups({"read:Don:collection", "write:Don"})
*/
private $date;
/**
* @ORMColumn(type="float")
* @Groups({"read:Don:collection", "write:Don"})
*/
private $montant;

当我们保存一个新的Don时,Donateur中出售的属性$必须增加。必须添加的值为Don资源的$montant的值

当我尝试这个代码

<?php
namespace AppEventListener;
use ApiPlatformCoreEventListenerEventPriorities;
use AppEntityDon;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
use SymfonyComponentHttpKernelEventViewEvent;
use SymfonyComponentHttpKernelKernelEvents;
use SymfonyComponentSecurityCoreSecurity;
class UpdateSoldeDonateurSubscriber implements EventSubscriberInterface
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}

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

public function updateSoldeDonateur(ViewEvent $event)
{
$data   = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
$user   = $this->security->getUser();
//On va mettre à jour le solde du donateur. On récupère d'abord l'ancien solde puis on y ajoute le nouveau
if($data instanceof Don){
$ancienSolde  = $data->getDonateur()->getSolde();
$nouveauSolde = $ancienSolde + $data->getMontant();
if($method === 'POST'){
$data->getDonateur()->setSolde($nouveauSolde);
}
elseif($method === 'PATCH'){
}
// dd($data->getDonateur(), $ancienSolde, $nouveauSolde);
}
}
}

solde没有变化。我认为这是由数据持久性引起的,但我不知道如何解决它。

这些是我的数据姐妹

<?php
namespace AppDataPersister;
use ApiPlatformCoreDataPersisterContextAwareDataPersisterInterface;
use AppEntityDonateur;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentSecurityCoreSecurity;
class DonateurDataPersister implements ContextAwareDataPersisterInterface
{
private $manager;
private $security;

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

public function supports($data, array $context = []): bool
{
return $data instanceof Donateur;
}
public function persist($data, array $context = [])
{
$this->manager->persist($data);
$this->manager->flush();
return $data;
}
public function remove($data, array $context = [])
{
$data->setIsDeleted(true);
$data->setDeletedBy($this->security->getUser());
$data->setDeletedAt(new DateTime());
$this->manager->flush();
}
}
<?php
namespace AppDataPersister;
use ApiPlatformCoreDataPersisterContextAwareDataPersisterInterface;
use AppEntityDon;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentSecurityCoreSecurity;
class DonDataPersister implements ContextAwareDataPersisterInterface
{
private $manager;
private $security;

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

public function supports($data, array $context = []): bool
{
return $data instanceof Don;
}
public function persist($data, array $context = [])
{
$this->manager->persist($data);
$this->manager->flush();
return $data;
}
public function remove($data, array $context = [])
{
$data->setIsDeleted(true);
$data->setDeletedBy($this->security->getUser());
$data->setDeletedAt(new DateTime());
$this->manager->flush();
}
}

请给我一些建议。

您的订阅者在写入数据库后被调用,您应该在对其进行更改后刷新,或者使用在写入之前调用的另一个事件(例如PRE_WRITE),正如我在评论中提到的。

最新更新