<?php
namespace App\Controller\Website;
use App\Controller\Website\Trait\FiltrationTrait;
use App\Entity\Product;
use App\Entity\ProductIcon;
use App\Facade\ProductFacade;
use App\Facade\ProductVariantFacade;
use App\Filtration\FiltrationFactory;
use App\Pagination\PaginationFactory;
use App\Repository\ProductCategoryRepository;
use App\Repository\ProductFamilyRepository;
use App\Repository\ProductRepository;
use App\Repository\ProductVariantRepository;
use App\Utils\SchemaManager;
use App\Utils\SnippetManager;
use Sulu\Bundle\ContactBundle\Api\Account as AccountApi;
use Sulu\Bundle\MediaBundle\Api\Media;
use Sulu\Bundle\MediaBundle\Media\Manager\MediaManagerInterface;
use Sulu\Component\Content\Compat\StructureInterface;
use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes;
use Sulu\Component\Webspace\Webspace;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ProductController extends SuluExtendController
{
use FiltrationTrait;
public function viewAction(
Product $product,
ProductCategoryRepository $productCategoryRepository,
ProductFamilyRepository $productFamilyRepository,
ProductRepository $productRepository,
ProductFacade $productFacade,
ProductVariantRepository $productVariantRepository,
ProductVariantFacade $productVariantFacade,
PaginationFactory $paginationFactory,
FiltrationFactory $filtrationFactory,
SnippetManager $snippetManager,
SchemaManager $schemaManager,
MediaManagerInterface $mediaManager,
Request $request,
$_sulu,
$attributes = [],
$preview = false,
$partial = false,
): Response
{
/** @var Webspace $webspace */
$webspace = $request->attributes->get('_sulu')->getAttribute('webspace');
if (isset($_GET['pdf']) && isset($_GET['variantId'])) {
$productVariant = $productVariantRepository->find($_GET['variantId']);
$product = $productRepository->findOneByTitle($productVariant->getTitle(), $productVariant->getLocale());
$organizationArea = $snippetManager->loadByArea('organization');
if ($organizationArea && $organizationArea['content']['organization']) {
/** @var AccountApi $accountApi */
$accountApi = $organizationArea['content']['organization'];
$account = $accountApi->getEntity();
$postalAddress = $account->getMainAddress();
$attributes['pdf_footer'] = [
'url' => 'https://' . $_SERVER['HTTP_HOST'] . $product->getRoute()->getPath(),
'email' => [
'title' => $account->getMainEmail(),
'url' => 'mailto:' . $account->getMainEmail()
],
'phone' => [
'title' => $account->getMainPhone(),
'url' => 'tel:' . $account->getMainPhone()
],
];
if ($postalAddress) {
$attributes['pdf_header']['columns'][0] = [
'title' => $account->getName(),
'content' => '<p>' . $postalAddress->getStreet() . ' ' . $postalAddress->getNumber() . '</br>' . $postalAddress->getZip() . ' ' . $postalAddress->getCity() . '</p>',
];
}
if ($account->getIdentificationNumber() && $account->getTaxIdentificationNumber()) {
$attributes['pdf_header']['columns'][1] = [
'content' => '<p><strong>IČO:</strong> ' . $account->getIdentificationNumber() . '</br><strong>DIČ:</strong>' . $account->getTaxIdentificationNumber() . '</p>',
];
}
}
if ($productVariant) {
$attributes['item'] = $productVariantFacade->renderProductVariantPdf($productVariant, $webspace->getKey(), $productVariant->getLocale());
return $this->renderAll('pages/product-pdf.html.twig', $attributes, $preview, $partial);
}
}
$limit = 20;
$page = $request->query->get('page', 1);
$queryFilters = $this->getQueryFilters($request);
$attributes = $this->getAttributes($attributes);
$attributes['breadcrumbs'] = $this->getBreadcrumbs('product', $product->getUuid());
$schema = $schemaManager->getDefaultSchemas($attributes['breadcrumbs']);
$attributes['product'] = $product;
if(isset($attributes['content']['blocks'])) {
$blockList = $this->resolveBlocks($attributes['content']['blocks'], $schema);
if($blockList instanceof RedirectResponse) {
return $blockList;
}
$attributes['blocks'] = $blockList->getBlocks();
$schema = $blockList->getSchema();
}
// ---------------------------------------
// Product intro
// ---------------------------------------
$attributes['text_media_section'] = [
'header' => [
'heading' => [
'title' => $product->getTitle(),
],
],
'header_position' => 'in',
'spacing' => 'none',
'variant' => 'product',
];
if ($product->getDescription()) {
$attributes['text_media_section']['content'] = $product->getDescription();
}
if ($product->isImage()) {
$media = $mediaManager->getById($product->getImage()->getId(), $product->getLocale());
$attributes['text_media_section']['media'] = [
'img' => [
'src' => $media->getThumbnails()['656x656'],
'srcset' => [
$media->getThumbnails()['656x656'] . ' 1x',
$media->getThumbnails()['1312x1312'] . ' 2x',
],
],
];
if ($productVariantRepository->isNewProductVariant($product->getTitle())) {
$attributes['text_media_section']['media']['tag'] = [
'title' => 'Novinka',
];
}
}
if ($product->getCode()) {
$attributes['text_media_section']['description']['code'] = $product->getCode();
}
if ($product->getCategory()) {
$productCategory = $productCategoryRepository->findOneByImportId($product->getCategory(), $product->getLocale());
if ($productCategory) {
$attributes['text_media_section']['description']['category'] = $productCategory->getTitle();
}
}
if ($product->getFamily()) {
$productFamily = $productFamilyRepository->findOneByImportId($product->getFamily(), $product->getLocale());
if ($productFamily) {
$attributes['text_media_section']['description']['family'] = $productFamily->getTitle();
}
}
$icons = $product->getIcons()?->map(function(ProductIcon $productIcon) use($product, $mediaManager) {
return $mediaManager->getById($productIcon->getMedia()->getId(), $product->getLocale());
});
if (!$icons->isEmpty()) {
/** @var Media $icon */
foreach ($icons as $icon) {
$attributes['text_media_section']['description']['specs'][$icon->getId()] = [
'tooltip' => [
'icon' => [
'src' => $icon->getThumbnails()['32x32'],
],
],
];
if ($icon->getDescription()) {
$attributes['text_media_section']['description']['specs'][$icon->getId()]['tooltip']['title'] = $icon->getDescription();
}
}
}
// ---------------------------------------
// Product variants
// ---------------------------------------
$filtration = $filtrationFactory->createProductVariantsFiltration(
webspace: $webspace->getKey(),
locale: $request->getLocale(),
products: [$product],
filters: $queryFilters,
);
$qb = $productVariantRepository->getProductVariantsQueryBuilder(
webspace: $webspace->getKey(),
locale: $request->getLocale(),
products: [$product],
types: $queryFilters['types'],
fixations: $queryFilters['fixations'],
minLuminousFlux: $queryFilters['minLuminousFlux'],
maxLuminousFlux: $queryFilters['maxLuminousFlux'],
cris: $queryFilters['cris'],
chromaticities: $queryFilters['chromaticities'],
dispersionVariants: $queryFilters['dispersionVariants'],
ips: $queryFilters['ips'],
radiationDirects: $queryFilters['radiationDirects'],
shapes: $queryFilters['shapes'],
minLength: $queryFilters['minLength'],
maxLength: $queryFilters['maxLength'],
minWidth: $queryFilters['minWidth'],
maxWidth: $queryFilters['maxWidth'],
minHeight: $queryFilters['minHeight'],
maxHeight: $queryFilters['maxHeight'],
colors: $queryFilters['colors'],
usages: $queryFilters['usages'],
maxTemperatures: $queryFilters['maxTemperatures'],
minTemperatures: $queryFilters['minTemperatures'],
minInputPower: $queryFilters['minInputPower'],
maxInputPower: $queryFilters['maxInputPower'],
minEfficiency: $queryFilters['minEfficiency'],
maxEfficiency: $queryFilters['maxEfficiency'],
elProtects: $queryFilters['elProtects'],
powerMethods: $queryFilters['powerMethods'],
resourceTypes: $queryFilters['resourceTypes'],
// lightSources: $queryFilters['lightSources'],
statuses: $queryFilters['statuses'],
mechanicalDurabilities: $queryFilters['mechanicalDurabilities'],
dispersions: $queryFilters['dispersions'],
drivers: $queryFilters['drivers'],
accessories: $queryFilters['accessories'],
);
$pagination = $paginationFactory->create();
$pagination->setMaxPerPage($limit);
$pagination->setPage($page);
$pagination->queryBuilderInit($qb);
$variants = [];
if ($pagination->hasPageResults()) {
foreach ($pagination->getPageResults() as $pageResult) {
foreach ($pageResult as $productVariant) {
$variants[] = $productVariantFacade->renderProductVariant($productVariant);
}
}
}
$filtrationSettings = $snippetManager->loadByArea('filtration_settings');
$attributes['product_variants_section'] = [
'header' => [
'heading' => [
'title' => 'Varianty produktu',
],
'variant' => 'left',
],
'empty_title' => 'Žádné výsledky',
'filter' => [
'id' => 'product-filter-form',
'product_id' => $product->getId(),
'reset_btn' => [
'title' => 'Smazat všechny filtry',
'form' => 'product-filter-form',
],
'form_list' => $filtration->render(
settings: $filtrationSettings['content'] ?? null,
product: $product,
),
],
'table' => [
'items' => $variants,
],
'pagination' => $pagination->renderPagination(),
'limit' => $limit,
];
// ---------------------------------------
// Accessories
// ---------------------------------------
$productDetailSnippet = $snippetManager->loadByArea('product_detail_settings', $webspace->getKey(), $product->getLocale());
$accessories = $productVariantRepository->getAccessories($product->getTItle(), $webspace->getKey(), $product->getLocale());
$renderedAccessories = $productRepository->renderAccessories($accessories, $webspace->getKey(), $product->getLocale());
if ($renderedAccessories) {
$attributes['accessories_products_slider'] = [
'id' => 'products-slider-1',
'bg_color' => true,
];
if ($productDetailSnippet && $productDetailSnippet['content']['accessories_title']) {
$attributes['accessories_products_slider']['header']['heading']['title'] = $productDetailSnippet['content']['accessories_title'];
}
if ($productDetailSnippet && $productDetailSnippet['content']['accessories_description']) {
$attributes['accessories_products_slider']['header']['perex'] = $productDetailSnippet['content']['accessories_description'];
}
$attributes['accessories_products_slider']['group']['items'] = $renderedAccessories;
}
// ---------------------------------------
// Similar products
// ---------------------------------------
$similarProducts = $productFacade->renderProducts(
webspace: $webspace->getKey(),
locale: $product->getLocale(),
productCategoryImportId: $product->getCategory(),
currentProductId: $product->getId()
);
if ($similarProducts) {
$attributes['similar_products_slider'] = [
'id' => 'products-slider-2',
'spacing' => 'bottom-0',
];
if ($productDetailSnippet && $productDetailSnippet['content']['similar_products_title']) {
$attributes['similar_products_slider']['header']['heading']['title'] = $productDetailSnippet['content']['similar_products_title'];
}
if ($productDetailSnippet && $productDetailSnippet['content']['similar_products_description']) {
$attributes['similar_products_slider']['header']['perex'] = $productDetailSnippet['content']['similar_products_description'];
}
$attributes['similar_products_slider']['group']['items'] = $similarProducts;
}
$attributes['_schema'] = implode('', $schema);
$this->setEntitySocialMeta($product);
$this->setEntitySeoMeta($product);
return $this->renderAll('pages/product.html.twig', $attributes, $preview, $partial);
}
public function listAction(
StructureInterface $structure,
ProductCategoryRepository $productRepository,
PaginationFactory $paginationFactory,
SchemaManager $schemaManager,
Request $request,
RequestAttributes $_sulu,
$attributes = [],
$preview = false,
$partial = false,
): Response
{
$categoryId = $request->query->get('c');
$category = null;
$attributes = $this->getAttributes([], $structure);
$attributes['breadcrumbs'] = $this->getBreadcrumbs('product_family', $attributes['uuid']);
$schema = $schemaManager->getDefaultSchemas($attributes['breadcrumbs']);
$attributes['references']['header'] = [
'title' => [
'first' => $attributes['content']['title_first'],
'second' => $attributes['content']['title_second'],
],
'overline' => [
'title' => $attributes['content']['title_small'],
'symbol' => $attributes['content']['symbol'],
],
'perex' => $attributes['content']['description'],
];
if($attributes['content']['image_pill'] instanceof Media) {
/** @var Media $imagePill */
$imagePill = $attributes['content']['image_pill'];
$attributes['references']['header']['title']['pill'] = [
'src' => $imagePill->getThumbnails()['240x240'],
'srcset' => [
$imagePill->getThumbnails()['240x240'] . ' 1x',
$imagePill->getThumbnails()['480x480'] . ' 2x',
],
'alt' => $imagePill->getTitle(),
];
}
$limit = $attributes['content']['limit'] ?? 6;
$qb = $productRepository->prepareQueryBuilder(
$_sulu->getAttribute('webspace')->getKey(),
$_sulu->getAttribute('locale'),
$category?->getId()
);
$pagination = $paginationFactory->create();
$pagination->setMaxPerPage($limit);
$pagination->setPage(1);
$pagination->queryBuilderInit($qb);
$products = [];
if($pagination->hasPageResults()) {
$wideCounter = 0;
foreach($pagination->getPageResults() as $pageResult) {
foreach($pageResult as $product) {
$wide = false;
$wideCounter++;
if($wideCounter === 1) {
$wide = true;
}
elseif($wideCounter === 6) {
$wideCounter = 0;
$wide = true;
}
$products[] = $productRepository->getFamilies();
}
}
}
$attributes['references']['references'] = $products;
$attributes['references']['references_limit'] = $limit;
if($category) {
$attributes['references']['references_category'] = $category->getId();
}
if($pagination->hasNextPage()) {
$attributes['references']['references_load_more'] = true;
}
if(isset($attributes['content']['blocks'])) {
$blockList = $this->resolveBlocks($attributes['content']['blocks'], $schema);
if($blockList instanceof RedirectResponse) {
return $blockList;
}
$attributes['content']['blocks'] = $blockList->getBlocks();
$schema = $blockList->getSchema();
}
$attributes['_schema'] = implode('', $schema);
return $this->renderAll('pages/reference-list.html.twig', $attributes, $preview, $partial);
}
}