0

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?

1
  • What exactly is not working? Commented Feb 5, 2021 at 10:28

2 Answers 2

1

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
// ...
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.