gpt4 book ai didi

php - 使用 Api 平台,自动将用户分配给对象 (OneToMany)

转载 作者:行者123 更新时间:2023-12-04 22:39:39 29 4
gpt4 key购买 nike

这是我的场景:

我有一个 Article实体。每篇文章都有一个所有者(User)。一个用户可以拥有多篇文章。用户可以通过 API 发布文章。

我想要 user_id基于不记名 token 自动设置的文章列(我使用的是 JWT 身份验证)。

我在任何地方都找不到有关如何执行此操作的任何文档。有人可以帮助如何实现这一目标吗?

注意:如果可能,我正在寻找避免在 Symfony 中使用额外扩展(或 Controller )的解决方案。我相信 Api Platform 应该能够使用内置技术实现这一点,但我可能错了。

这是我的实体:

用户:

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @ApiResource()
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity(fields="email", message="Email already taken")
*/
class User implements UserInterface, \Serializable
{

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

/**
* @var string $password
*
* @ORM\Column(type="string", length=64)
* @Assert\NotBlank()
*/
private $password;

/**
* @var string $plainPassword
*
* @Assert\NotBlank()
* @Assert\Length(max=4096)
*/
private $plainPassword;

/**
* @var string $email
*
* @ORM\Column(type="string", length=254, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
*/
private $email;

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

/**
* @ORM\OneToMany(targetEntity="Article", mappedBy="user")
*/
private $articles;

/**
* @ORM\Column(type="array")
*/
private $roles;

public function __construct($email)
{
$this->isActive = true;
$this->email = $email;
$this->articles = new ArrayCollection();
}

public function getId()
{
return $this->id;
}

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

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

/**
* @param string $email
*
* @return $this
*/
public function setEmail($email)
{
$this->email = $email;

return $this;
}

/**
* @return null|string
*/
public function getSalt()
{
return null;
}

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

/**
* @param string $password
*
* @return $this
*/
public function setPassword($password)
{
$this->password = $password;

return $this;
}

/**
* @return array
*/
public function getRoles()
{
return ['ROLE_USER'];
}

public function eraseCredentials()
{
}

/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
));
}

/** @see \Serializable::unserialize()
* @param $serialized
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
) = unserialize($serialized, array('allowed_classes' => false));
}
}

文章
<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* A User's article
*
* @ORM\Table(name="articles")
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* collectionOperations={
* "get",
* "post"={"access_control"="is_granted('ROLE_USER')"}
* },
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"}
* }
* )
* @ORM\Entity
* @ORM\HasLifecycleCallbacks()
*/
class Article
{

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

/**
* @var string $user
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="articles")
*/
private $user;

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

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

/**
* @var \DateTimeInterface $createdAt
*
* @ORM\Column(type="datetime_immutable")
*/
private $createdAt;

/**
* @var \DateTimeInterface $updatedAt
*
* @ORM\Column(type="date_immutable", nullable=true)
*/
private $updatedAt;

/**
* @ORM\PrePersist()
*/
public function setCreatedAt()
{
$this->createdAt = new \DateTime();
}

/**
* @ORM\PreUpdate()
*/
public function setUpdatedAt()
{
$this->updatedAt = new \DateTime();
}

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

/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}

/**
* @return string
*/
public function getUser(): string
{
return $this->user;
}

/**
* @return string
*/
public function getName(): string
{
return $this->name;
}

/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}

/**
* @return string
*/
public function getLocation(): string
{
return $this->location;
}

/**
* @param string $location
*/
public function setLocation(string $location): void
{
$this->location = $location;
}


}

最佳答案

这应该可以使用 EventListener :https://api-platform.com/docs/core/events

有了这些,您就可以在没有新 Controller 的情况下连接到 ApiPlatform 进程的内部进程。非常适合您的用例。

一个实现可能是这样的:

<?php
// api/src/EventSubscriber/AddOwnerToArticleSubscriber.php

namespace App\EventSubscriber;

use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Article;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

final class AddOwnerToArticleSubscriber implements EventSubscriberInterface
{

/**
* @var TokenStorageInterface
*/
private $tokenStorage;

public function __construct(TokenStorageInterface $tokenStorage)
{

$this->tokenStorage = $tokenStorage;
}

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

public function attachOwner(GetResponseForControllerResultEvent $event)
{
$article = $event->getControllerResult();
$method = $event->getRequest()->getMethod();

if (!$article instanceof Article || Request::METHOD_POST !== $method) {

// Only handle Article entities (Event is called on any Api entity)
return;
}

// maybe these extra null checks are not even needed
$token = $this->tokenStorage->getToken();
if (!$token) {
return;
}

$owner = $token->getUser();
if (!$owner instanceof User) {
return;
}


// Attach the user to the not yet persisted Article
$article->setUser($owner);

}
}

关于php - 使用 Api 平台,自动将用户分配给对象 (OneToMany),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52528915/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com