<?php
declare(strict_types=1);
/**
* @copyright 2020 Crehler Sp. z o. o.
* @link https://crehler.com/
* @support support@crehler.com
*
* @author Mateusz FlasiĆski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Crehler\Catalog\Controller\StoreApi;
use Crehler\Catalog\Content\BookmarksResponse;
use Crehler\Catalog\Content\CatalogBasicDataResponse;
use Crehler\Catalog\Content\CatalogFileResponse;
use Crehler\Catalog\Content\CatalogFlatDataResponse;
use Crehler\Catalog\Content\CatalogPageDetailResponse;
use Crehler\Catalog\Content\StoreApiCatalogResponse;
use Crehler\Catalog\Content\TableOfContentsResponse;
use Crehler\Catalog\Entity\Catalog\CatalogEntity;
use Crehler\Catalog\Service\CatalogCacheManager;
use Crehler\Catalog\Service\CatalogReader\BookmarksTreeService;
use Crehler\Catalog\Service\CatalogReader\Loader\CatalogPageLoader;
use Crehler\Catalog\Service\CatalogReader\Loader\TableOfContentsLoader;
use Crehler\Catalog\Service\FlatDataManager\FlatLoaderInterface;
use Crehler\Catalog\Service\PdfMergeService;
use OpenApi\Annotations as OA;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
/**
* @RouteScope(scopes={"store-api"})
*/
class CatalogController
{
private EntityRepositoryInterface $catalogPageRepository;
private TableOfContentsLoader $contentsLoader;
private EntityRepositoryInterface $catalogRepository;
private BookmarksTreeService $bookmarksTreeService;
private CatalogPageLoader $catalogPageLoader;
private CatalogCacheManager $cacheManager;
private FlatLoaderInterface $catalogFlatLoader;
private PdfMergeService $pdfMergeService;
public function __construct(EntityRepositoryInterface $catalogPageRepository,
TableOfContentsLoader $contentsLoader,
EntityRepositoryInterface $catalogRepository,
BookmarksTreeService $bookmarksTreeService,
CatalogPageLoader $catalogPageLoader,
CatalogCacheManager $cacheManager,
FlatLoaderInterface $catalogFlatLoader,
PdfMergeService $pdfMergeService)
{
$this->catalogPageRepository = $catalogPageRepository;
$this->contentsLoader = $contentsLoader;
$this->catalogRepository = $catalogRepository;
$this->bookmarksTreeService = $bookmarksTreeService;
$this->catalogPageLoader = $catalogPageLoader;
$this->cacheManager = $cacheManager;
$this->catalogFlatLoader = $catalogFlatLoader;
$this->pdfMergeService = $pdfMergeService;
}
/**
* @OA\Post(
* path="/catalog/page",
* description="Load a catalog",
* operationId="readCatalogDetail",
* tags={"Store API", "Catalog"},
* )
*
* @Route("/store-api/catalog/page", name="store-api.catalog.page", methods={"POST"})
*/
public function page(Request $request, SalesChannelContext $context): StoreApiCatalogResponse
{
$pageId = $request->get('pageId', null);
if ($pageId === null) {
throw new NotFoundHttpException();
}
$cached = $this->cacheManager->getPage($pageId, $context);
if ($cached !== null) {
return new StoreApiCatalogResponse($cached);
}
$criteria = new Criteria([$pageId]);
$page = $this->catalogPageRepository->search($criteria, $context->getContext())->first();
if ($page === null) {
throw new NotFoundHttpException();
}
$this->cacheManager->savePage($page, $context);
return new StoreApiCatalogResponse($page);
}
/**
* @Route("/store-api/catalog/print-merge-prepare/{leftPdfId}/{rightPdfId}", name="store-api.catalog.print-merge-prepare", methods={"GET"})
*/
public function printMergePrepare(string $leftPdfId, string $rightPdfId, SalesChannelContext $context): Response
{
$media = $this->pdfMergeService->getMedia($leftPdfId, $rightPdfId, $context);
return new JsonResponse(['success' => true, 'uuid' => $media->getId()]);
}
/**
* @Route("/store-api/catalog/flat", name="store-api.catalog.flat", methods={"POST"})
*/
public function flat(Request $request, SalesChannelContext $context): CatalogFlatDataResponse
{
$catalogId = $request->get('catalogId', null);
if ($catalogId === null) {
throw new NotFoundHttpException();
}
$struct = $this->catalogFlatLoader->load($catalogId, $context);
return new CatalogFlatDataResponse($struct);
}
/**
* @Route("/store-api/catalog/basic", name="store-api.catalog.basic", methods={"POST"})
*/
public function basic(Request $request, SalesChannelContext $context): Response
{
$catalogId = $request->get('catalogId', null);
if ($catalogId === null) {
throw new NotFoundHttpException();
}
// $cache = $this->cacheManager->getBasic($catalogId, $context);
//
// if ($cache !== null) {
// return new CatalogBasicDataResponse($cache);
// }
$criteria = new Criteria([$catalogId]);
$criteria->addAssociation('productBoxImageMedia');
$catalog = $this->catalogRepository->search($criteria, $context->getContext())->first();
if ($catalog === null) {
throw new NotFoundHttpException();
}
$this->cacheManager->saveBasic($catalogId, $catalog, $context);
return new CatalogBasicDataResponse($catalog);
}
/**
* @Route("/store-api/catalog/tableOfContents", name="store-api.catalog.table-of-contents", methods={"POST"})
*/
public function tableOfContents(Request $request, SalesChannelContext $context): TableOfContentsResponse
{
$catalogId = $request->get('catalogId', null);
if ($catalogId === null) {
throw new NotFoundHttpException();
}
$limit = (int) $request->get('limit', 50);
$offset = (int) $request->get('offset', 0);
$cached = $this->cacheManager->getTableOfContents($catalogId, $limit, $offset);
if ($cached !== null) {
return new TableOfContentsResponse($cached);
}
$contests = $this->contentsLoader->load($catalogId, $context, $offset, $limit);
$this->cacheManager->setTableOfContents($catalogId, $limit, $offset, $contests);
return new TableOfContentsResponse($contests);
}
/**
* @Route("/store-api/catalog/bookmark", name="store-api.catalog.bookmark", methods={"POST"})
*/
public function bookmark(Request $request, SalesChannelContext $context)
{
$catalogId = $request->get('catalogId', null);
if ($catalogId === null) {
throw new NotFoundHttpException();
}
$cache = $this->cacheManager->getBookmark($catalogId, $context);
if ($cache !== null) {
return new BookmarksResponse($cache);
}
$tree = $this->bookmarksTreeService->getTree($catalogId, $context->getContext(), $context);
$this->cacheManager->saveBookmark($catalogId, $tree, $context);
return new BookmarksResponse($tree);
}
/**
* @Route("/store-api/catalog/products", name="store-api.catalog.products", methods={"POST"})
*/
public function products(Request $request, SalesChannelContext $context)
{
$pageId = $request->get('pageId', null);
$catalogId = $request->get('catalogId', null);
if ($pageId === null || $catalogId === null) {
throw new NotFoundHttpException();
}
$cache = $this->cacheManager->getProduct($pageId, $context);
if ($cache !== null) {
return new JsonResponse($cache);
}
$products = $this->catalogPageLoader->getProducts($pageId);
$this->cacheManager->saveProduct($products, $pageId, $catalogId, $context);
return new JsonResponse($products);
}
/**
* @Route("/store-api/catalog/page-detail", name="store-api.catalog.page-detail", methods={"POST"})
*/
public function pageDetail(Request $request, SalesChannelContext $context)
{
$pageId = $request->get('pageId', null);
$displayMode = (int) $request->get('displayMode', 1);
if ($pageId === null) {
throw new NotFoundHttpException();
}
// $cache = $this->cacheManager->getPageDetail($pageId, $displayMode, $context);
// if ($cache !== null) {
// return new CatalogPageDetailResponse($cache);
// }
$page = $this->catalogPageLoader->getPageDetail($pageId, $context, $displayMode);
$this->cacheManager->savePageDetail($pageId, $displayMode, $page, $context);
return new CatalogPageDetailResponse($page);
}
/**
* @Route("/store-api/catalog/file", name="store-api.catalog.file", methods={"POST"})
*/
public function file(Request $request, SalesChannelContext $context) //TODO add cache
{
$catalogId = $request->get('catalogId', null);
if ($catalogId === null) {
throw new NotFoundHttpException();
}
$criteria = new Criteria([$catalogId]);
$criteria->addAssociation('pdf');
/** @var CatalogEntity $catalog */
$catalog = $this->catalogRepository->search($criteria, $context->getContext())->first();
return new CatalogFileResponse($catalog->getPdf());
}
}