<?php
namespace Tonur\SeoFilterLandingpages\Storefront\Controller;
use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Framework\Routing\RequestTransformer;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Tonur\SeoFilterLandingpages\Core\Content\Landingpage\SeoFilterLandingpageEntity;
use Tonur\SeoFilterLandingpages\Storefront\Page\Landingpage\LandingpagePageLoader;
/**
* @RouteScope(scopes={"storefront"})
*/
class LandingpageController extends StorefrontController
{
/**
* @var LandingpagePageLoader
*/
private $landingpagePageLoader;
/** @var SalesChannelRepository */
private $seoFilterLandingpageRepo;
/**
* @var SeoUrlPlaceholderHandlerInterface
*/
private $seoUrlPlaceholderHandler;
private SystemConfigService $systemConfigService;
public function __construct(
LandingpagePageLoader $landingpagePageLoader,
SalesChannelRepository $seoFilterLandingpageRepo,
SeoUrlPlaceholderHandlerInterface $seoUrlPlaceholderHandler,
SystemConfigService $systemConfigService
)
{
$this->landingpagePageLoader = $landingpagePageLoader;
$this->seoFilterLandingpageRepo = $seoFilterLandingpageRepo;
$this->seoUrlPlaceholderHandler = $seoUrlPlaceholderHandler;
$this->systemConfigService = $systemConfigService;
}
/**
* @Route("/landingpage/{landingpageId}", name="frontend.repertus.landingpage.page", options={"seo"="true"}, methods={"GET"})
*
* @param Request $request
* @param SalesChannelContext $context
* @return Response
*/
public function loadLandingpage(SalesChannelContext $context, Request $request): Response
{
$page = $this->landingpagePageLoader->load($request, $context);
return $this->renderStorefront('@Storefront/storefront/page/content/index.html.twig', ['page' => $page]);
}
/**
* @RouteScope(scopes={"storefront"})
*
* @Route("/widgets/landingpage/{navigationId}/check", name="frontend.repertus.landingpage.check", methods={"GET"}, defaults={"XmlHttpRequest": true})
* @param string $navigationId
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
*/
public function checkForLandingpage(string $navigationId, Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$properties = array_filter(explode('|', $request->query->get('properties', '')));
$manufacturers = array_filter(explode('|', $request->query->get('manufacturer', '')));
$pagination = array_filter(explode('|', $request->query->get('p', '')));
$criteria = new Criteria();
$criteria
->addAssociation('category')
->addFilter(new EqualsFilter('category.id', $navigationId));
$entitySearchResult = $this->seoFilterLandingpageRepo->search($criteria, $salesChannelContext);
/** @var SeoFilterLandingpageEntity $landingpage */
$landingpage = null;
if (empty($pagination) || (int)$pagination[0] === 1) {
/** @var SeoFilterLandingpageEntity $possibleLandingpage */
foreach ($entitySearchResult->getEntities() as $possibleLandingpage) {
if ($this->isSameArray($properties, $possibleLandingpage->getPropertyIds() ?? []) &&
$this->isSameArray($manufacturers, $possibleLandingpage->getManufacturerIds() ?? [])
) {
$landingpage = $possibleLandingpage;
break;
}
}
}
$response = ['isLandingpage' => false];
if ($landingpage) {
$response['isLandingpage'] = true;
$host = $request->attributes->get(RequestTransformer::SALES_CHANNEL_ABSOLUTE_BASE_URL)
. $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
$url = $this->seoUrlPlaceholderHandler->replace(
$this->seoUrlPlaceholderHandler->generate(
'frontend.repertus.landingpage.page',
['landingpageId' => $landingpage->getId()]
),
$host,
$salesChannelContext
);
$this->addOrderParam($url, $request, $salesChannelContext);
$this->addShippingFreeParam($url, $request, $salesChannelContext);
$this->addMinPriceParam($url, $request, $salesChannelContext);
$this->addMaxPriceParam($url, $request, $salesChannelContext);
$response['url'] = $url;
}
return new JsonResponse($response);
}
private function isSameArray(array $array1, array $array2)
{
return
count($array1) === count($array2) &&
empty(array_diff($array1, $array2));
}
private function addOrderParam(string &$url, Request $request, SalesChannelContext $context): void
{
$order = $request->get('order');
if (!$order) {
return;
}
$defaultProductSorting = $this->systemConfigService->getString(
'core.listing.defaultSorting',
$context->getSalesChannelId()
);
if ($defaultProductSorting && strcmp($order, $defaultProductSorting) === 0) {
return;
}
$data = ['order' => $order];
$url .= (strpos($url,'?') !== false ? '&' : '?') . http_build_query($data);
}
private function addShippingFreeParam(string &$url, Request $request, SalesChannelContext $salesChannelContext)
{
$param = $request->get('shipping-free');
if (!$param) {
return;
}
$data = ['shipping-free' => $param];
$url .= (strpos($url,'?') !== false ? '&' : '?') . http_build_query($data);
}
private function addMinPriceParam(string &$url, Request $request, SalesChannelContext $salesChannelContext)
{
$param = $request->get('min-price');
if (!$param) {
return;
}
$data = ['min-price' => $param];
$url .= (strpos($url,'?') !== false ? '&' : '?') . http_build_query($data);
}
private function addMaxPriceParam(string &$url, Request $request, SalesChannelContext $salesChannelContext)
{
$param = $request->get('max-price');
if (!$param) {
return;
}
$data = ['max-price' => $param];
$url .= (strpos($url,'?') !== false ? '&' : '?') . http_build_query($data);
}
}