<?php declare(strict_types=1);
namespace App\Product\Controller;
use App\Framework\Controller\APIController;
use App\Framework\Entity\PaginationResult;
use App\Framework\Serializer\APISerializerGroup;
use App\Product\Entity\Product;
use App\Product\Entity\GetProductsFiltersInput;
use App\Product\Service\ProductCategoryService;
use App\Product\Service\ProductService;
use Doctrine\ORM\EntityNotFoundException;
use Doctrine\ORM\ORMException;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Routing\Annotation\Route;
#[Route(path: '/api/products')]
class ProductController extends APIController
{
public function __construct(
private ProductService $productService,
private ProductCategoryService $categoryService,
private LoggerInterface $logger,
) { }
/**
* @return PaginationResult<Product>
*/
#[Route(path: '', methods: ['GET'])]
#[APISerializerGroup('common:list', 'product:list', 'productcategory:default')]
public function getProducts(): PaginationResult
{
$paginationInput = $this->getRequestPaginationInput();
$isPublicSale = $this->getRequestFilterBool(key: 'isPublicSale', required: false, default: null);
$categoryId = $this->getRequestFilterInt(key: 'categoryId', required: false, default: null);
$filtersInput = new GetProductsFiltersInput(
isPublicSale: $isPublicSale,
categoryId: $categoryId,
);
return $this->productService->getProducts(filtersInput: $filtersInput, paginationInput: $paginationInput);
}
/**
* @throws EntityNotFoundException
*/
#[Route(path: '/{id}', requirements: ['id' => '\d+'], methods: ['GET'])]
#[APISerializerGroup('product:list', 'productcategory:default')]
public function getProductById(int $id): Product
{
return $this->productService->getProductById($id);
}
/**
*
* @throws EntityNotFoundException
* @throws ORMException
*/
#[Route(path: '', methods: ['POST'])]
#[Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_HUERTA')")]
#[APISerializerGroup('product:list', 'productcategory:default')]
public function createProduct(): Product
{
// Get request body
$data = $this->getRequestBody();
if (array_key_exists('category', $data) && $data['category']) {
$data['category'] = $this->categoryService->getProductCategoryById($data['category']);
}
// Create the product
return $this->productService->createProductFromFields($data);
}
/**
*
* @throws EntityNotFoundException
* @throws ORMException
*/
#[Route(path: '/{id}', requirements: ['id' => '\d+'], methods: ['PATCH'])]
#[Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_HUERTA')")]
#[APISerializerGroup('product:list', 'productcategory:default')]
public function updateProduct(int $id): Product {
// Fetch the order entity
$product = $this->productService->getProductById($id);
if (!$product) {
throw EntityNotFoundException::fromClassNameAndIdentifier(Product::class, [$id]);
}
// Get request body
$data = $this->getRequestBody();
if (array_key_exists('category', $data)) {
$data['category'] = $this->categoryService->getProductCategoryById($data['category']);
}
// And patch the order
$this->productService->patchFields($product, $data);
return $product;
}
/**
*
* @throws EntityNotFoundException
* @throws ORMException
*/
#[Route(path: '/{id}/thumbnail', requirements: ['id' => '\d+'], methods: ['POST'])]
#[Security("is_granted('ROLE_ADMIN')")]
#[APISerializerGroup('product:list', 'productcategory:default')]
public function updateProductThumbnail(Product $product): Product
{
// Upload thumbnail
$thumbnail = $this->getRequestFileData('thumbnail', false);
if ($thumbnail) {
$this->productService->updateThumbnail($product, $thumbnail);
}
return $product;
}
}