php - API Plateform custom get operation

I am trying to build an ecommerce site using API plateform.
Since I am using JWT authentication with LexikJWTAuthenticationBundle I am having a hard time to get the user with the token.
I would like to access the cart of the user.
I managed to add to the cart through a custom post operation.
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AddToCart extends AbstractController
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function __invoke(Article $data)
{
$user = $this->getUser();
$user->addCart($data);
$this->em->flush();
return $user->getCart();
}
}
I am trying to use the same way but with a get request
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class GetCart extends AbstractController
{
public function getCart()
{
$user = $this->getUser();
return $user->getCart();
}
}
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ApiResource(
* itemOperations={
* "get",
* "put",
* "get_cart"={
* "method"="GET",
* "path"="/cart",
* "controller"=App\Controller\GetCart,
* },
* }
* )
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $username;
/**
* @ORM\Column(type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\ManyToMany(targetEntity=Article::class)
*/
private $cart;
/**
* @return Collection|Article[]
*/
public function getCart(): Collection
{
return $this->cart;
}
public function addCart(Article $cart): self
{
if (!$this->cart->contains($cart)) {
$this->cart[] = $cart;
}
return $this;
}
public function removeCart(Article $cart): self
{
$this->cart->removeElement($cart);
return $this;
}
}
Any idea what I am doing wrong?
Answer
Solution:
Instead using a controller, have you try to use custom DataProvider and inject Security ?
use Symfony\Component\Security\Core\Security;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\DataProvider\SerializerAwareDataProviderInterface;
use ApiPlatform\Core\DataProvider\SerializerAwareDataProviderTrait;
class UserDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface, SerializerAwareDataProviderInterface
{
use SerializerAwareDataProviderTrait;
public const OPERATION_NAME = "get_cart";
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return User::class === $resourceClass && self::OPERATION_NAME === $operationName;
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?TableDuplication
{
dump($this->security->getUser(), $this->security->getToken()); die();
// Do what you need
}
}
$this->security->getUser()
will return your user and$this->security->getToken()
will return all about your token
Here's the documentation: https://api-platform.com/docs/core/data-providers/#custom-item-data-provider
Answer
Solution:
Using a custom controller does not switch off the built in services (DataProvider, (De)Serializer, DataPersister) of api plaftorm. With the built in DataProvider you can not have an item operation without an id. Your GetCart controller does not need the built in DataProvider so you can switch it off:
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ApiResource(
* itemOperations={
* "get",
* "put",
* "get_cart"={
* "method"="GET",
* "path"="/cart",
* "controller"=App\Controller\GetCart,
* "read"=false,
* },
* }
* )
*/
class User implements UserInterface
// ...
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: cannot access offset of type string on string
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.