<?php declare(strict_types=1);
namespace Nd\Stl\Core\Content\Look;
use Nd\Stl\Core\Content\Look\Exception\LookNotFoundException;
use OpenApi\Annotations as OA;
use Shopware\Core\Content\Category\CategoryDefinition;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
use Shopware\Core\Content\Cms\SalesChannel\SalesChannelCmsPageLoaderInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Routing\Annotation\Since;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route(defaults={"_routeScope"={"store-api"}})
*/
class LookRoute extends AbstractLookRoute
{
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $lookRepository;
/**
* @var SalesChannelCmsPageLoaderInterface
*/
private SalesChannelCmsPageLoaderInterface $cmsPageLoader;
/**
* @internal
*/
public function __construct(
EntityRepositoryInterface $lookRepository,
SalesChannelCmsPageLoaderInterface $cmsPageLoader
) {
$this->lookRepository = $lookRepository;
$this->cmsPageLoader = $cmsPageLoader;
}
public function getDecorated(): AbstractLookRoute
{
throw new DecorationPatternException(self::class);
}
/**
* @Since("6.2.0.0")
* @OA\Post(
* path="/look/{look}",
* summary="Fetch a single product manufacturer",
* description="This endpoint returns information about the category, as well as a fully resolved (hydrated with mapping values) CMS page, if one is assigned to the category. You can pass slots which should be resolved exclusively.",
* operationId="readLook",
* tags={"Store API", "Look"},
* @OA\RequestBody(
* @OA\JsonContent(
* description="The product listing criteria only has an effect, if the category contains a product listing.",
* ref="#/components/schemas/ProductListingCriteria"
* )
* ),
* @OA\Parameter(
* name="lookId",
* description="Identifier of the category to be fetched",
* @OA\Schema(type="string", pattern="^[0-9a-f]{32}$"),
* in="path",
* required=true
* ),
* @OA\Parameter(
* name="slots",
* description="Resolves only the given slot identifiers. The identifiers have to be seperated by a '|' character",
* @OA\Schema(type="string"),
* in="query",
* ),
* @OA\Parameter(name="Api-Basic-Parameters"),
* @OA\Response(
* response="200",
* description="The loaded category with cms page",
* @OA\JsonContent(ref="#/components/schemas/Category")
* )
* )
*
* @Route("/store-api/look/{lookId}", name="store-api.look.detail", methods={"GET","POST"})
*/
public function load(string $lookId, Request $request, SalesChannelContext $context): LookRouteResponse
{
$look = $this->loadLook($lookId, $context);
$pageId = $look->getCmsPageId();
$slotConfig = $look->getTranslation('slotConfig');
if (!$pageId) {
return new LookRouteResponse($look);
}
$pages = $this->cmsPageLoader->load(
$request,
$this->createCriteria($pageId, $request),
$context,
$slotConfig
);
if (!$pages->has($pageId)) {
throw new PageNotFoundException($pageId);
}
$look->setCmsPage($pages->get($pageId));
$look->setCmsPageId($pageId);
return new LookRouteResponse($look);
}
private function loadLook(string $lookId, SalesChannelContext $context): LookEntity
{
$criteria = new Criteria([$lookId]);
$look = $this->lookRepository
->search($criteria, $context->getContext())
->get($lookId);
if (!$look) {
throw new LookNotFoundException($lookId);
}
return $look;
}
private function createCriteria(string $pageId, Request $request): Criteria
{
$criteria = new Criteria([$pageId]);
$criteria->setTitle('look::cms-page');
$slots = $request->get('slots');
if (\is_string($slots)) {
$slots = explode('|', $slots);
}
if (!empty($slots) && \is_array($slots)) {
$criteria
->getAssociation('sections.blocks')
->addFilter(new EqualsAnyFilter('slots.id', $slots));
}
return $criteria;
}
}