Skip to content

Instantly share code, notes, and snippets.

@clemherreman
Created July 1, 2020 12:03
Show Gist options
  • Save clemherreman/4df5a437f733fafeee2bb4155a15cb9e to your computer and use it in GitHub Desktop.
Save clemherreman/4df5a437f733fafeee2bb4155a15cb9e to your computer and use it in GitHub Desktop.
API Platform itemOperation with multiple identifiers
<?php
namespace App\Doctrine\Entity;
use ApiPlatform\Core\Action\NotFoundAction;
use ApiPlatform\Core\Action\PlaceholderAction;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Coupon\Model\OrderSkuInterface;
use App\Doctrine\Validator\Constraints\CartSkuLoyalty;
use App\Doctrine\Validator\Constraints\CartSkuQty;
use App\Util\Price;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\IpTraceable\Traits\IpTraceableEntity;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ApiResource(
* normalizationContext={"groups"={"cartSku:read"}},
* denormalizationContext={"groups"={"cartSku:write"}},
* collectionOperations={
* "get"={"controller"=NotFoundAction::class}
* },
* itemOperations={
* "get" = {
* "method"="GET",
* "path"="/cart/sku/{cart}/{sku}.{_format}",
* "swagger_context" = {
* "summary"="Get sku qty in current cart"
* }
*
* }
* )
*/
class CartSku
{
/**
* @var Cart
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
* @ORM\ManyToOne(targetEntity="App\Doctrine\Entity\Cart", inversedBy="cartSkus")
*
* @ApiProperty(identifier=true)
*/
private $cart;
/**
* @var Sku
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
* @ORM\ManyToOne(targetEntity="App\Doctrine\Entity\Sku")
*
* @ApiProperty(identifier=true, attributes={"fetchEager": true})
*/
private $sku;
}
<?php
namespace App\Doctrine\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Doctrine\Entity\Cart;
use App\Doctrine\Entity\CartSku;
use App\Doctrine\Entity\Sku;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityNotFoundException;
use Doctrine\ORM\ORMException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
class CartSkuSubscriber implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => ['onPreRead', EventPriorities::PRE_READ],
KernelEvents::VIEW => ['onPreValidate', EventPriorities::PRE_VALIDATE],
];
}
public function onPreRead(RequestEvent $event)
{
$attributes = $event->getRequest()->attributes;
$loyaltySku = null;
if (CartSku::class !== $attributes->get('_api_resource_class')) {
return;
}
$idApiP = [
'sku' => $event->getRequest()->attributes->get('sku', $loyaltySku),
'cart' => $event->getRequest()->attributes->get('cart'),
];
$event->getRequest()->attributes->add($idApiP);
$event->getRequest()->attributes->set('id', http_build_query($idApiP, '', ';'));
}
/**
* @throws ORMException
*/
public function onPreValidate(ViewEvent $event)
{
$cartSku = $event->getControllerResult();
if (!$cartSku instanceof CartSku) {
return;
}
$attributes = $event->getRequest()->attributes;
try {
/** @var Sku $sku */
$sku = $this->entityManager->getReference(Sku::class, $attributes->get('sku'));
/** @var Cart $cart */
$cart = $this->entityManager->getReference(Cart::class, $attributes->get('cart'));
$cartSku->setCart($cart);
$cartSku->setSku($sku);
} catch (EntityNotFoundException $e) {
throw new NotFoundHttpException($e->getMessage(), $e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment