<?php
namespace App\AtechNet\CoreBundle\Helper\Furbify;
use App\AtechNet\CoreBundle\Entity\Album;
use App\AtechNet\CoreBundle\Entity\Attribute;
use App\AtechNet\CoreBundle\Entity\AttributeOption;
use App\AtechNet\CoreBundle\Entity\CategoryGroup;
use App\AtechNet\CoreBundle\Entity\CategoryGroupMemberImage;
use App\AtechNet\CoreBundle\Entity\CategoryPage;
use App\AtechNet\CoreBundle\Entity\CategoryPagesPriorityProducts;
use App\AtechNet\CoreBundle\Entity\Coupon;
use App\AtechNet\CoreBundle\Entity\Customer;
use App\AtechNet\CoreBundle\Entity\Domain;
use App\AtechNet\CoreBundle\Entity\Language;
use App\AtechNet\CoreBundle\Entity\Product;
use App\AtechNet\CoreBundle\Entity\ProductAttribute;
use App\AtechNet\CoreBundle\Entity\ProductContainer;
use App\AtechNet\CoreBundle\Entity\ProductGroup;
use App\AtechNet\CoreBundle\Entity\ProductGroupMember;
use App\AtechNet\CoreBundle\Entity\ProductMeta;
use App\AtechNet\CoreBundle\Entity\ProductModelMeta;
use App\AtechNet\CoreBundle\Entity\ProductTag;
use App\AtechNet\CoreBundle\Entity\ProductType;
use App\AtechNet\CoreBundle\Entity\Review;
use App\AtechNet\CoreBundle\Entity\ReviewSurveyMedia;
use App\AtechNet\CoreBundle\Entity\Vendor;
use App\AtechNet\CoreBundle\Service\HistoricalEuroRate;
use App\AtechNet\CoreBundle\Sevices\ProductService;
use App\AtechNet\CoreBundle\Translation\DatabaseTranslator;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\NotSupported;
use Doctrine\ORM\Query;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Bridge\Twig\TokenParser\DumpTokenParser;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class ProductHelper
{
public const CUSTOMER_TYPE_RETAIL = 1;
public const CUSTOMER_TYPE_WHOLESALE = 2;
public const AGE_0_to_2_YEARS = 0;
public const AGE_3_to_5_YEARS = 1;
public const AGE_6_PLUS_YEARS = 2;
public const LIST_ALLOWED_ATTRIBUTES_RETAIL = [
ProductType::PRODUCT_TYPE_ID_MONITOR => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_RESPONSE_TIME,
Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
],
ProductType::PRODUCT_TYPE_ID_NOTEBOOK => [
Attribute::ATTRIBUTE_ID_CPU_NB,
Attribute::ATTRIBUTE_ID_RAM_NB,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC_SET => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PRINTER => [
Attribute::ATTRIBUTE_ID_PRINTING_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_PRINTING_COLOR,
Attribute::ATTRIBUTE_ID_DUPLEX,
Attribute::ATTRIBUTE_ID_PORTS,
Attribute::ATTRIBUTE_ID_PRINTING_SPEED,
],
ProductType::PRODUCT_TYPE_ID_ELECTRIC_SCOOTER => [
Attribute::ATTRIBUTE_ID_MAX_SPEED,
Attribute::ATTRIBUTE_ID_MAX_RANGE,
Attribute::ATTRIBUTE_ID_POWER,
],
ProductType::PRODUCT_TYPE_ID_SMARTPHONE => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_MEMORY,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_RAM,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_TABLET => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_MEMORY,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_RAM,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_SERVER => [
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_SSHD35,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_FORM,
],
ProductType::PRODUCT_TYPE_ID_PROJECTOR => [
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
Attribute::ATTRIBUTE_ID_CONTRAST,
Attribute::ATTRIBUTE_ID_PROJECTOR_REMOTE,
Attribute::ATTRIBUTE_ID_LUMEN,
],
ProductType::PRODUCT_TYPE_ID_RAM_PC => [
Attribute::ATTRIBUTE_ID_MEMORY_TYPE,
Attribute::ATTRIBUTE_ID_MEMORY_SIZE,
Attribute::ATTRIBUTE_ID_MEMORY_FREQUENCY,
],
ProductType::PRODUCT_TYPE_ID_CPU => [
Attribute::ATTRIBUTE_ID_CPU_PC_FAMILY,
Attribute::ATTRIBUTE_ID_CPU_GENERATION,
Attribute::ATTRIBUTE_ID_CLOCKSPEED,
],
ProductType::PRODUCT_TYPE_ID_DOCKING_STATION => [
Attribute::ATTRIBUTE_ID_CONNECTORS,
Attribute::ATTRIBUTE_ID_DOCKING_STATION_POWER_INPUT,
],
ProductType::PRODUCT_TYPE_ID_NOTEBOOK_BAG => [
Attribute::ATTRIBUTE_ID_NOTEBOOK_BAG_SIZE,
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_COLOR,
],
];
public const LIST_ALLOWED_ATTRIBUTES_WHOLESALE = [
ProductType::PRODUCT_TYPE_ID_MONITOR => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_RESPONSE_TIME,
Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
],
ProductType::PRODUCT_TYPE_ID_NOTEBOOK => [
Attribute::ATTRIBUTE_ID_CPU_NB,
Attribute::ATTRIBUTE_ID_RAM_NB,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC_SET => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE => [
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PRINTER => [
Attribute::ATTRIBUTE_ID_PRINTING_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_PRINTING_COLOR,
Attribute::ATTRIBUTE_ID_DUPLEX,
Attribute::ATTRIBUTE_ID_PORTS,
Attribute::ATTRIBUTE_ID_PRINTING_SPEED,
],
ProductType::PRODUCT_TYPE_ID_ELECTRIC_SCOOTER => [
Attribute::ATTRIBUTE_ID_MAX_SPEED,
Attribute::ATTRIBUTE_ID_MAX_RANGE,
Attribute::ATTRIBUTE_ID_POWER,
],
ProductType::PRODUCT_TYPE_ID_SMARTPHONE => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_MEMORY,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_RAM,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_TABLET => [
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_MEMORY,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_RAM,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_SERVER => [
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_SSHD35,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_FORM,
],
ProductType::PRODUCT_TYPE_ID_PROJECTOR => [
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
Attribute::ATTRIBUTE_ID_CONTRAST,
Attribute::ATTRIBUTE_ID_PROJECTOR_REMOTE,
Attribute::ATTRIBUTE_ID_LUMEN,
],
ProductType::PRODUCT_TYPE_ID_RAM_PC => [
Attribute::ATTRIBUTE_ID_MEMORY_TYPE,
Attribute::ATTRIBUTE_ID_MEMORY_SIZE,
Attribute::ATTRIBUTE_ID_MEMORY_FREQUENCY,
],
ProductType::PRODUCT_TYPE_ID_CPU => [
Attribute::ATTRIBUTE_ID_CPU_PC_FAMILY,
Attribute::ATTRIBUTE_ID_CPU_GENERATION,
Attribute::ATTRIBUTE_ID_CLOCKSPEED,
],
ProductType::PRODUCT_TYPE_ID_DOCKING_STATION => [
Attribute::ATTRIBUTE_ID_CONNECTORS,
Attribute::ATTRIBUTE_ID_DOCKING_STATION_POWER_INPUT,
],
ProductType::PRODUCT_TYPE_ID_NOTEBOOK_BAG => [
Attribute::ATTRIBUTE_ID_NOTEBOOK_BAG_SIZE,
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_COLOR,
],
];
public const DEFAULT_ACCESSORY_SELECTIONS = [
21 => 247,
105 => 1536, // USB wifi : I dont need
116 => 1535, // Speaker : I dont need
147 => 1522, // DDR 4 PC RAM : I dont need
149 => 1537, // Headphones : I dont need
];
public const CPU_MARK_HELPER_MIN = [
1 => 0,
2 => 3_000,
3 => 6_000,
4 => 9_000,
5 => 11_000,
];
public const CPU_MARK_HELPER_MAX = [
1 => 3_000,
2 => 6_000,
3 => 9_000,
4 => 11_000,
5 => 1_000_000,
];
private $entityManager;
private $cloudFlareApiConfig;
private $translator;
private $multiStore;
private $customerType;
private $priceDomainId;
private $localeDomainId;
private $priceDomain;
private $localeDomain;
private $showWindows;
private $notebookSkinAttribute;
private $notebookSkinAttributeOptions;
private $router;
/**
* ProductHelper constructor.
* @param EntityManager $entityManager
* @param array $cloudFlareApiConfig
* @param $translator
* @param MultiStore $multiStore
* @param $router
* @throws \Exception
*/
public function __construct(
EntityManager $entityManager,
array $cloudFlareApiConfig,
$translator,
MultiStore $multiStore,
$router,
private HistoricalEuroRate $historicalEuroRate,
)
{
$this->entityManager = $entityManager;
$this->cloudFlareApiConfig = $cloudFlareApiConfig;
$this->translator = $translator;
$this->multiStore = $multiStore;
$this->router = $router;
$this->customerType = $this->multiStore->getCustomerTypeId();
$this->priceDomainId = $this->multiStore->getDomainId();
$this->localeDomainId = $this->multiStore->getLocaleDomainId();
$this->priceDomain = $this->multiStore->getDomain();
if ($this->priceDomainId == $this->localeDomainId) {
$this->localeDomain = $this->priceDomain;
} else {
$this->localeDomain = $this->multiStore->getLocaleDomain();
$this->translator = new DatabaseTranslator($this->entityManager, $this->multiStore->getLocaleDomainId());
}
return '';
$this->showWindows = !($this->priceDomain->getType() == 'retail') && !in_array($this->priceDomainId, [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]);
}
/**
* @param Product $product
* @return array
*/
public function getDataForProduct(Product $product): array
{
$priceProductMeta = $product->getDomainMeta($this->priceDomain);
if ($this->priceDomain->getId() == $this->localeDomain->getId()) {
$localeProductMeta = $priceProductMeta;
} else {
$localeProductMeta = $product->getDomainMeta($this->localeDomain);
}
return [
'product' => $product,
'priceMeta' => $priceProductMeta,
'localeMeta' => $localeProductMeta,
];
}
/**
* @param int $productId
* @return array
*/
public function getDataForProductById($productId)
{
$product = $this->entityManager->getRepository(Product::class)->findOneById($productId);
return $product ? $this->getDataForProduct($product) : null;
}
/**
* @param array $products
* @return array
*/
public function getDataForProducts($products)
{
$productsData = [];
foreach ($products as $product) {
$productsData[$product->getId()] = $this->getDataForProduct($product);
}
return $productsData;
}
/**
* @param array $productIds
* @return array
*/
public function getDataForProductsById($productIds)
{
$productsData = [];
foreach ($productIds as $productId) {
$productData = $this->getDataForProductById($productId);
if ($productData) {
$productsData[$productId] = $productData;
}
}
return $productsData;
}
/**
* @param array $products
* @param bool $withMultiplePicture
*
* @return array
*/
public function getStructuredDataForProducts($products, bool $withMultiplePicture = false): array
{
$structuredProducts = [];
if (count($products) < 1) {
return $structuredProducts;
}
foreach ($products as $product) {
$structuredProducts[$product->getId()] = $this->getStructuredDataForProduct($product, 'list', $withMultiplePicture);
}
return $structuredProducts;
}
/**
* @param array $products
* @param string $viewMode
* @return array
*/
public function getStructuredDataForProductsById(array $products, $viewMode = 'details'): array
{
$structuredProducts = [];
$products = $this->entityManager->getRepository(Product::class)->findBy([
'id' => $products,
]);
foreach ($products as $product) {
$structuredProducts[$product->getId()] = $this->getStructuredDataForProduct($product, $viewMode);
}
return $structuredProducts;
}
/**
* @param array $attributeList
* @return string
*/
private function getAttributeInfoForProductDescription(array $attributeList): string
{
$attributeIdToIgnoreForTitle = [
Attribute::ATTRIBUTE_ID_CPU_GENERATION,
Attribute::ATTRIBUTE_ID_CPU_NB,
Attribute::ATTRIBUTE_ID_RAM_NB,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_CPU_PC,
Attribute::ATTRIBUTE_ID_RAM_PC,
#Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_RESPONSE_TIME,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY,
Attribute::ATTRIBUTE_ID_MEMORY,
Attribute::ATTRIBUTE_ID_CONNECTORS,
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_NOTEBOOK_BAG_SIZE,
Attribute::ATTRIBUTE_ID_COLOR,
];
$attributeListText = '';
if (array_key_exists(Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM, $attributeList)) {
$operationSystem = $attributeList[Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM];
unset($attributeList[Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM]);
$attributeList[Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM] = $operationSystem;
}
foreach ($attributeList as $attribute) {
if ($attributeListText != '') {
$attributeListText .= ', ';
}
foreach ($attribute['options'] as $option) {
if (!in_array($attribute['id'], $attributeIdToIgnoreForTitle)) {
$attributeTitle = $attribute['id'] == Attribute::ATTRIBUTE_ID_VGA
? ''
: ' ' . $attribute['title'];
} else {
switch ($attribute['id']) {
case Attribute::ATTRIBUTE_ID_RAM_NB:
case Attribute::ATTRIBUTE_ID_RAM_PC:
$attributeTitle = ' RAM';
break;
case Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM:
$attributeTitle = $attribute['title'] . str_contains(strtolower($attribute['title']), 'windows') ? " OS" : '';
break;
case Attribute::ATTRIBUTE_ID_CPU_PC:
case Attribute::ATTRIBUTE_ID_CPU_NB:
$attributeListText .= " {$attribute['vendor']} {$option['title']}";
$attributeListText = str_replace('AMD AMD', 'AMD', $attributeListText);
break;
case Attribute::ATTRIBUTE_ID_CONNECTORS:
$attributeListText = implode(', ', array_map(
function ($option) {
return in_array($option['title'], ['Videokártya', 'Grafická karta']) ? $option['vendor'] : $option['title'];
},
$attribute['options']
));
break;
default:
$attributeTitle = '';
break;
}
}
if (isset($attributeTitle)) {
$attributeListText .= " {$option['title']}$attributeTitle";
}
}
}
$attributeListText = str_replace('OS OS', 'OS', $attributeListText);
return $attributeListText;
}
/**
* @param Product $product
* @param string $viewMode
* @param bool $withMultipleImage
*
* @return array
* @throws NotSupported
*/
public function getStructuredDataForProduct(Product $product, string $viewMode = 'details', bool $withMultipleImage = false): array
{
/**
* @var Product $product
* @var ProductMeta $priceDomain
* @var ProductMeta $localeDomain
* @var ProductAttribute $spec
* @var AttributeOption $option
* @var AttributeOption $acc
*/
$priceMeta = $product->getDomainMeta($this->priceDomain) ?: null;
$localeMeta = $product->getDomainMeta($this->localeDomain) ?: null;
$isCustomerTypeRetail = $this->priceDomain->getType() == 'retail';
$isWebcamIncluded = false;
$noWebcamBadge = false;
$images = [];
$categoryId = 0;
$accessoryAttributes = [];
$specificationAttributes = [];
$specificationAttributesListText = '';
$freeShipLimit = self::getFreeShipLimitsForDomain($this->priceDomainId)['freeShipLimit'];
$containerPartsSpecifications = [];
$connectedBatteries = [];
$batterAttributeOptionId = null;
$isContainer = $product->isContainer();
$containerWithSkin = false;
$translatedKeyboardReprint = $this->translator->trans('Keyboard reprint');
if ($viewMode == 'details') {
foreach ($product->getSpecificationProductAttributeOptions() as $spec) {
$option = $spec->getOption();
$attributeId = $option->getAttribute()->getId();
if ($attributeId == Attribute::ATTRIBUTE_ID_QUALITY
|| ($attributeId == Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM && (in_array($this->priceDomainId, [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU])))) {
continue;
}
if (!isset($specificationAttributes[$attributeId])) {
$specificationAttributes[$attributeId] = [
'id' => $attributeId,
'title' => $option->getAttribute()->getTitle($this->translator),
'options' => [],
];
if ($attributeId == Attribute::ATTRIBUTE_ID_WEBCAM) {
$isWebcamIncluded = true;
}
}
$title = $option->getLongTitle($this->translator);
if (empty($title)) {
$title = $option->getTitle($this->translator);
}
$specificationAttributes[$attributeId]['options'][$spec->getId()] = [
'id' => $spec->getId(),
'attributeOptionId' => $spec->getOption()->getId(),
'title' => $spec->getId() == 1623398 ? $option->getTitle($this->translator) : $title,
'shortTitle' => $option->getTitle($this->translator),
'multiplier' => $spec->getMultiplier(),
];
}
if ($product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_MONITOR) {
if (isset($specificationAttributes[Attribute::ATTRIBUTE_ID_GRAPHIC_INPUTS])) {
$sortOrder = [733, 628, 595];
$options = $specificationAttributes[Attribute::ATTRIBUTE_ID_GRAPHIC_INPUTS]['options'];
usort($options, function ($a, $b) use ($sortOrder) {
return array_search($a['attributeOptionId'], $sortOrder) - array_search($b['attributeOptionId'], $sortOrder);
});
$formatedOptions = [];
foreach ($options as $option) {
$formatedOptions[$option['id']] = $option;
}
$specificationAttributes[Attribute::ATTRIBUTE_ID_GRAPHIC_INPUTS]['options'] = $formatedOptions;
}
}
if ($isContainer && $product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_PC_SET) {
/**
* @var ProductContainer $container
*/
// get attributes from main product First
$productId = $product->getId();
$productTypeId = $product->getType()->getId();
foreach ($product->getSpecificationProductAttributeOptions() as $spec) {
$option = $spec->getOption();
$attributeId = $option->getAttribute()->getId();
if (($isCustomerTypeRetail && $attributeId == Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM) ||
!in_array($productTypeId, [
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_MONITOR,
ProductType::PRODUCT_TYPE_ID_PC_SET,
])
) {
continue;
}
if (!isset($containerPartsSpecifications[$productId])) {
$containerPartsSpecifications[$productId]['title'] = $product->getVendor()->getName() . ' ' . $product->getName();
}
if (!isset($containerPartsSpecifications[$productId]['attributes'][$attributeId])) {
$containerPartsSpecifications[$productId]['attributes'][$attributeId] = [
'id' => $attributeId,
'title' => $option->getAttribute()->getTitle($this->translator),
'options' => [],
];
if ($attributeId == Attribute::ATTRIBUTE_ID_WEBCAM) {
$isWebcamIncluded = true;
}
}
$title = $option->getLongTitle($this->translator);
if (empty($title)) {
$title = $option->getTitle($this->translator);
}
$containerPartsSpecifications[$productId]['attributes'][$attributeId]['options'][$spec->getId()] = [
'id' => $spec->getId(),
'title' => $title,
'shortTitle' => $option->getTitle($this->translator),
'multiplier' => $spec->getMultiplier(),
];
}
foreach ($product->getProductContainers() as $container) {
$containerProduct = $container->getChild();
$containerProductId = $containerProduct->getId();
$containerProductTypeId = $containerProduct->getType()->getId();
foreach ($containerProduct->getSpecificationProductAttributeOptions() as $spec) {
$option = $spec->getOption();
$attributeId = $option->getAttribute()->getId();
if (($isCustomerTypeRetail && $attributeId == Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM) || !in_array($containerProductTypeId, [ProductType::PRODUCT_TYPE_ID_NOTEBOOK, ProductType::PRODUCT_TYPE_ID_MONITOR, ProductType::PRODUCT_TYPE_ID_PC_SET])) {
continue;
}
if (!isset($containerPartsSpecifications[$containerProductId])) {
$containerPartsSpecifications[$containerProductId]['title'] = $containerProduct->getVendor()->getName() . ' ' . $containerProduct->getName();
}
if (!isset($containerPartsSpecifications[$containerProductId]['attributes'][$attributeId])) {
$containerPartsSpecifications[$containerProductId]['attributes'][$attributeId] = [
'id' => $attributeId,
'title' => $option->getAttribute()->getTitle($this->translator),
'options' => [],
];
if ($attributeId == Attribute::ATTRIBUTE_ID_WEBCAM) {
$isWebcamIncluded = true;
}
}
$title = $option->getLongTitle($this->translator);
if (empty($title)) {
$title = $option->getTitle($this->translator);
}
$containerPartsSpecifications[$containerProductId]['attributes'][$attributeId]['options'][$spec->getId()] = [
'id' => $spec->getId(),
'title' => $title,
'shortTitle' => $option->getTitle($this->translator),
'multiplier' => $spec->getMultiplier(),
];
}
}
}
if ($isContainer && $product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
/** @var ProductContainer $productContainer */
foreach ($product->getProductContainers() as $productContainer) {
$childProduct = $productContainer->getChild();
if ($childProduct) {
if ($childProduct->getType()->getId() == ProductType::PRODUCT_TYPE_ID_SERVICE) {
if (str_contains($childProduct->getName(), 'Notebook skin')) {
$containerWithSkin = true;
break;
}
}
}
}
}
if (!$isWebcamIncluded && $product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$specificationAttributes[Attribute::ATTRIBUTE_ID_WEBCAM] = [
'id' => Attribute::ATTRIBUTE_ID_WEBCAM,
'title' => 'Webcam',
'options' => [],
];
$specificationAttributes[Attribute::ATTRIBUTE_ID_WEBCAM]['options'][1773] = [
'id' => 1773,
'title' => $this->translator->trans('No'),
'shortTitle' => $this->translator->trans('No'),
'multiplier' => 0,
'color' => '',
'bold' => 0,
];
}
foreach ($product->getAccessoryAttributeOptions() as $acc) {
if ($acc->hasChildren() || (!is_null($acc->getProduct()) && ($acc->getProduct()->getAvailable() < 1 && $acc->getAttribute()->getId() != 184))) {
continue;
}
$attributeId = $acc->getAttribute()->getId();
if (!isset($accessoryAttributes[$attributeId])) {
$accessoryAttributes[$attributeId] = [
'id' => $attributeId,
'title' => $acc->getAttribute()->getTitle($this->translator),
'options' => [],
];
}
if (in_array($acc->getTitle(), ["Don't need", "No OS"])) {
continue;
}
//-> Suggested Price of Attribute
$attrOptionProductSuggestedPrice = $attrOptionProductVatSuggestedPrice = 0;
if ($this->customerType == self::CUSTOMER_TYPE_WHOLESALE) {
$attrOptionProduct = $acc->getProduct();
if ($attrOptionProduct) {
$attrOptionProductPriceMeta = $attrOptionProduct->getDomainMeta($this->priceDomain);
if ($attrOptionProductPriceMeta->getDomainSuggestedPrice() > 0 && $attrOptionProductPriceMeta->getDomainVatSuggestedPrice() > 0) {
$attrOptionProductSuggestedPrice = $attrOptionProductPriceMeta->getDomainSuggestedPrice();
$attrOptionProductVatSuggestedPrice = $attrOptionProductPriceMeta->getDomainVatSuggestedPrice();
}
}
if ($attrOptionProductSuggestedPrice === 0 && $attrOptionProductVatSuggestedPrice === 0) {
$attrOptionRetailPriceMeta = $acc->getDomainMeta($this->multiStore->getRetailDomainByWholesaleDomain());
$attrOptionProductSuggestedPrice = $attrOptionRetailPriceMeta->getDomainPrice();
$attrOptionProductVatSuggestedPrice = $attrOptionRetailPriceMeta->getDomainVatPrice();
}
}
//<- Suggested Price of Attribute
$attrOptionPriceMeta = $acc->getDomainMeta($this->priceDomain);
$fixedTitle = $this->translator->trans($acc->getTitle());
if ($attributeId == Attribute::ATTRIBUTE_ID_ACCESSORY_KEYBOARD_REPRINT && str_contains($fixedTitle, 'Keyboard reprint')) {
$fixedTitle = str_replace('Keyboard reprint', $translatedKeyboardReprint, $fixedTitle);
}
$accessoryAttributes[$attributeId]['options'][$acc->getId()] = [
'id' => $acc->getId(),
'title' => $fixedTitle,
'discounted' => $attrOptionPriceMeta->isDiscounted(),
'price' => $attrOptionPriceMeta->getDomainPrice(),
'vatPrice' => $attrOptionPriceMeta->getDomainVatPrice(),
'discount' => $attrOptionPriceMeta->getDomainDiscount(),
'vatDiscounted' => $attrOptionPriceMeta->getDomainVatDiscount(),
'suggestedPrice' => $attrOptionProductSuggestedPrice,
'vatSuggestedPrice' => $attrOptionProductVatSuggestedPrice,
'productId' => $acc->getProduct() != null ? $acc->getProduct()->getId() : 0,
];
}
$sortKeyboardPrintByIds = [5495, 2487];
if ($this->priceDomain->getId() == DOMAIN::DOMAIN_ID_RT_SK || $this->priceDomain->getId() == DOMAIN::DOMAIN_ID_WS_SK || $this->priceDomain->getId() == DOMAIN::DOMAIN_ID_RT_CZ || $this->priceDomain->getId() == DOMAIN::DOMAIN_ID_WS_CZ) {
array_unshift($sortKeyboardPrintByIds, 2444);
}
if ($this->priceDomain->getId() == DOMAIN::DOMAIN_ID_RT_HU || $this->priceDomain->getId() == DOMAIN::DOMAIN_ID_WS_HU) {
array_unshift($sortKeyboardPrintByIds, 2446);
}
if (!is_null($accessoryAttributes) && isset($accessoryAttributes[184]['options']) && count($accessoryAttributes[184]['options']) > 0) {
foreach ($sortKeyboardPrintByIds as $sortKeyboardPrintById) {
if (array_key_exists($sortKeyboardPrintById, $accessoryAttributes[184]['options'])) {
$val = $accessoryAttributes[184]['options'][$sortKeyboardPrintById];
unset($accessoryAttributes[184]['options'][$sortKeyboardPrintById]);
$accessoryAttributes[184]['options'][$sortKeyboardPrintById] = $val;
}
}
foreach ($accessoryAttributes[184]['options'] as $attributeOption) {
$foundId = false;
foreach ($sortKeyboardPrintByIds as $sortKeyboardPrintById) {
if ($attributeOption['id'] == $sortKeyboardPrintById) {
$foundId = true;
}
}
if (!$foundId) {
$val = $accessoryAttributes[184]['options'][$attributeOption['id']];
unset($accessoryAttributes[184]['options'][$attributeOption['id']]);
$accessoryAttributes[184]['options'][$attributeOption['id']] = $val;
}
}
}
// Add skinnable accessory choices if conditions are met
if (!$containerWithSkin && self::hasBadgeByStructuredData('Skinable', $product->getBadges())) {
if (!$this->notebookSkinAttributeOptions) {
$this->notebookSkinAttribute = $this->entityManager->getRepository(Attribute::class)->findOneById(Attribute::ATTRIBUTE_ID_NOTEBOOK_SKIN);
$this->notebookSkinAttributeOptions = $this->entityManager->createQuery("SELECT ao
FROM AtechNetCoreBundle:AttributeOption ao
LEFT JOIN ao.product p
WHERE ao.product IS NOT NULL
AND p.available > 0
AND ao.id != 4062
AND ao.archived = 0
AND ao.attribute = " . $this->notebookSkinAttribute->getId())
->getResult();
}
$notebookSkinAttributeId = $this->notebookSkinAttribute->getId();
$accessoryAttributes[$notebookSkinAttributeId] = [
'id' => $notebookSkinAttributeId,
'title' => $this->notebookSkinAttribute->getTitle($this->translator),
'options' => [],
];
foreach ($this->notebookSkinAttributeOptions as $notebookSkinAttributeOption) {
$attrOptionPriceMeta = $notebookSkinAttributeOption->getDomainMeta($this->priceDomain);
$accessoryAttributes[$notebookSkinAttributeId]['options'][$notebookSkinAttributeOption->getId()] = [
'id' => $notebookSkinAttributeOption->getId(),
'title' => $this->translator->trans($notebookSkinAttributeOption->getTitle()),
'discounted' => $attrOptionPriceMeta->isDiscounted(),
'price' => $attrOptionPriceMeta->getDomainPrice(),
'vatPrice' => $attrOptionPriceMeta->getDomainVatPrice(),
'discount' => $attrOptionPriceMeta->getDomainDiscount(),
'vatDiscounted' => $attrOptionPriceMeta->getDomainVatDiscount(),
'suggestedPrice' => 0,
'vatSuggestedPrice' => 0,
'productId' => $notebookSkinAttributeOption->getProduct() != null ? $notebookSkinAttributeOption->getProduct()->getId() : 0,
];
}
}
$accessoryOrder = [
Attribute::ATTRIBUTE_ID_NOTEBOOK_SKIN,
Attribute::ATTRIBUTE_ID_ACCESSORY_KEYBOARD_REPRINT,
Attribute::ATTRIBUTE_ID_ACCESSORY_SSD,
Attribute::ATTRIBUTE_ID_ACCESSORY_NB_RAM_DDR2,
Attribute::ATTRIBUTE_ID_ACCESSORY_NB_RAM_DDR3,
Attribute::ATTRIBUTE_ID_ACCESSORY_NB_RAM_DDR4,
Attribute::ATTRIBUTE_ID_ACCESSORY_PC_RAM_DDR2,
Attribute::ATTRIBUTE_ID_ACCESSORY_PC_RAM_DDR3,
Attribute::ATTRIBUTE_ID_ACCESSORY_PC_RAM_DDR4,
];
$accessoryAttributesBuffer = $accessoryAttributes;
$accessoryAttributes = [];
foreach ($accessoryOrder as $accId) {
if (isset($accessoryAttributesBuffer[$accId])) {
$accessoryAttributes[] = $accessoryAttributesBuffer[$accId];
}
}
foreach ($accessoryAttributesBuffer as $key => $acc) {
if (!in_array($key, $accessoryOrder)) {
$accessoryAttributes[$key] = $accessoryAttributesBuffer[$key];
}
}
// Sort Cable Accessory
if (isset($accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE])) {
if ($product->getType()->getId() != ProductType::PRODUCT_TYPE_ID_MONITOR) {
$sortOrder = [
AttributeOption::ATTRIBUTE_OPTION_ID_DISPLAY_PORT_CABLE,
AttributeOption::ATTRIBUTE_OPTION_ID_HDMI_CABLE,
AttributeOption::ATTRIBUTE_OPTION_ID_VGA_CABLE,
AttributeOption::ATTRIBUTE_OPTION_ID_DVI_CABLE,
];
$accessoryAttributeOptionsBuffer = $accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'];
$accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'] = [];
foreach ($sortOrder as $index) {
if (isset($accessoryAttributeOptionsBuffer[$index])) {
$accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'][$index] = $accessoryAttributeOptionsBuffer[$index];
}
}
}
else {
$sortOrder = [
AttributeOption::ATTRIBUTE_OPTION_ID_DISPLAY_PORT_CABLE,
AttributeOption::ATTRIBUTE_OPTION_ID_HDMI_CABLE,
AttributeOption::ATTRIBUTE_OPTION_ID_VGA_CABLE,
];
$accessoryAttributeOptionsBuffer = $accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'];
$accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'] = [];
foreach ($sortOrder as $index) {
if (isset($accessoryAttributeOptionsBuffer[$index])) {
$accessoryAttributes[Attribute::ATTRIBUTE_ID_ACCESSORY_CABLE]['options'][$index] = $accessoryAttributeOptionsBuffer[$index];
}
}
}
}
// Remove attributes with no options
foreach ($accessoryAttributes as $key => $value) {
if (count($value['options']) < 1) {
unset($accessoryAttributes[$key]);
}
}
$images = $product?->getAlbum()?->getPhotos() ?? [];
$connectedBatteries = $product?->getConnectedBatteries() ?? [];
if (!empty($connectedBatteries)) {
$batterAttributeOptionId = ProductService::getBatteryAttributeOptionIdByPrice($product, $this->localeDomain, $this->historicalEuroRate);
}
}
else if ($viewMode == 'list') {
$listAllowedAttributes = $isCustomerTypeRetail ? self::LIST_ALLOWED_ATTRIBUTES_RETAIL : self::LIST_ALLOWED_ATTRIBUTES_WHOLESALE;
$specificationAttributes = [];
if (isset($listAllowedAttributes[$product->getType()->getId()])) {
/**
* @var ProductAttribute $spec
*/
foreach ($product->getSpecificationProductAttributeOptions() as $spec) {
$option = $spec->getOption();
$attributeId = $option->getAttribute()->getId();
$product = $spec->getProduct();
if ($option->getId() == AttributeOption::ATTRIBUTE_OPTION_NO_WEBCAM) {
$noWebcamBadge = true;
}
if (in_array($attributeId, $listAllowedAttributes[$product->getType()->getId()])) {
if (!isset($specificationAttributes[$attributeId])) {
$specificationAttributes[$attributeId] = [
'id' => $attributeId,
'title' => $option->getAttribute()->getTitle($this->translator),
'vendor' => strtok($option->getLongTitle(), ' '),
'options' => [],
];
}
$specificationAttributes[$attributeId]['options'][$spec->getId()] = [
'id' => $spec->getId(),
'title' => $option->getTitle($this->translator),
'vendor' => strtok($option->getLongTitle(), ' '),
'multiplier' => $spec->getMultiplier(),
];
}
}
} else {
$specificationCount = 0;
/**
* @var ProductAttribute $spec
*/
foreach ($product->getSpecificationProductAttributeOptions() as $spec) {
$specificationCount++;
$option = $spec->getOption();
$attributeId = $option->getAttribute()->getId();
if (!isset($specificationAttributes[$attributeId])) {
$specificationAttributes[$attributeId] = [
'id' => $attributeId,
'title' => $option->getAttribute()->getTitle($this->translator),
'vendor' => strtok($option->getLongTitle(), ' '),
'options' => [],
];
}
$specificationAttributes[$attributeId]['options'][$spec->getId()] = [
'id' => $spec->getId(),
'title' => $option->getTitle($this->translator),
'vendor' => strtok($option->getLongTitle(), ' '),
'multiplier' => $spec->getMultiplier(),
];
if ($specificationCount >= 4) {
break;
}
}
}
$specificationAttributesListText = $this->getAttributeInfoForProductDescription($specificationAttributes);
}
if ($priceMeta && $priceMeta->isReady() && $priceMeta->isActive() && $product->isReservable() && ($viewMode == 'details' || $viewMode == 'list')) {
$outOfStockStatus = $product->getOutOfStockStatus();
if ($outOfStockStatus == Product::OutOfStockStatus_VisibleOrderable5Days) {
$orderWaitingDays = 5;
} elseif ($outOfStockStatus == Product::OutOfStockStatus_VisibleOrderable10Days) {
$orderWaitingDays = 10;
} elseif ($outOfStockStatus == Product::OutOfStockStatus_VisibleOrderable15Days) {
$orderWaitingDays = 15;
} else {
$orderWaitingDays = 0;
}
} else {
$orderWaitingDays = 0;
}
if ($viewMode == 'list' || $viewMode == 'cart' || $viewMode == 'popular') {
foreach ($product->getAlbum()->getPhotos() as $photo) {
$images = $photo;
break;
}
}
if ($viewMode == 'configurator') {
$images = $product->getAlbum()->getNthPhoto();
}
if ($withMultipleImage)
{
$images = $product->getAlbum()->getPhotos()->toArray();
}
$review_count = 0;
$review_stars_sum = 0;
$review_stars = 0;
$reviews = [];
$languageId = $this->multiStore->getDefaultLanguageId();
$languageIds = [$languageId];
$czReviewFirst = false;
if ($languageId == Language::LANGUAGE_ID_CZ) {
$languageIds[] = Language::LANGUAGE_ID_SK;
$czReviewFirst = true;
} elseif ($languageId == Language::LANGUAGE_ID_SK) {
$languageIds[] = Language::LANGUAGE_ID_CZ;
}
$productFamilyReviews = $this->entityManager->createQuery("SELECT r
FROM AtechNetCoreBundle:Review r
LEFT JOIN r.product p
WHERE r.type = :reviewType AND p.name = :productName AND r.language IN(:languageIds) AND r.approved = 1
ORDER BY" . ($czReviewFirst ? ' r.language DESC, ' : '') . " r.created DESC")
->setParameters([
'reviewType' => Review::TYPE_PRODUCT,
'productName' => $product->getName(),
'languageIds' => $languageIds,
])
->getResult();
$fs = new Filesystem();
/**
* @var Review $review
* @var ReviewSurveyMedia $reviewSurveyMedia
*/
if (count($productFamilyReviews) > 0) {
foreach ($productFamilyReviews as $review) {
$reviewProduct = $review->getProduct();
$review_count = $review_count + 1;
$review_stars_sum = $review_stars_sum + $review->getStars();
$reviewImages = [];
if ($viewMode == 'details') {
foreach ($review->getSurveyMedias() as $reviewSurveyMedia) {
if ($reviewSurveyMedia->isApproved()) {
$surveyMedia = $reviewSurveyMedia->getSurveyMedia();
// CREATE FINAL PATH FOR RESIZED IMAGE
$thumbDirPath = 'storage/image/reviews/' . $review->getId() . '/thumbs';
$popupDirPath = 'storage/image/reviews/' . $review->getId() . '/popup';
$thumbPath = $thumbDirPath . '/' . $surveyMedia->getFilename();
$popupPath = $popupDirPath . '/' . $surveyMedia->getFilename();
if (!$fs->exists($thumbDirPath)) {
$fs->mkdir($thumbDirPath, 0755);
}
if (!$fs->exists($popupDirPath)) {
$fs->mkdir($popupDirPath, 0755);
}
// Cloudflare Image (thumb)
$imageThumbPath = $reviewSurveyMedia->getCdnUrl('ProductViewThumb');
// Internal Image (thumb)
if ($imageThumbPath == '' && !$fs->exists($thumbPath)) {
$resize = new ResizeImage($surveyMedia->getDirectory() . '/' . $surveyMedia->getFilename());
$resize->resizeTo(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT, 'maxWidth');
$resize->saveImage($thumbPath);
$imageThumbPath = '/' . $thumbPath;
} elseif ($imageThumbPath == '') {
$imageThumbPath = '/' . $thumbPath;
}
// Cloudflare Image (popup)
$imagePopupPath = $reviewSurveyMedia->getCdnUrl('ProductViewPop');
// Internal Image (popup)
if ($imagePopupPath == '' && !$fs->exists($popupPath)) {
$resize = new ResizeImage($surveyMedia->getDirectory() . '/' . $surveyMedia->getFilename());
$resize->resizeTo(Image::PRODUCT_VIEW_POPUP_WIDTH, Image::PRODUCT_VIEW_POPUP_HEIGHT);
$resize->saveImage($popupPath);
$imagePopupPath = '/' . $popupPath;
} elseif ($imagePopupPath == '') {
$imagePopupPath = '/' . $popupPath;
}
$reviewImages[] = [
'thumb' => $imageThumbPath,
'popup' => $imagePopupPath,
];
}
}
}
if ($viewMode == 'details') {
$reviews[] = [
'stars' => $review->getStars(),
'message' => $review->getText(),
'name' => $review->getName(),
'product_name' => $reviewProduct->getVendor()->getName() . ' ' . $reviewProduct->getName(),
'product_config' => $reviewProduct->getDescription(),
'reviewDate' => $review->getCreated()->format('Y.m.d'),
'reviewImages' => $reviewImages,
];
}
}
$review_stars = floor(($review_stars_sum / $review_count) * 2) / 2;
}
// Badges
$badgesRaw = [];
if ($noWebcamBadge) {
$badgesRaw[] = 'no_webcam';
}
if ($viewMode == 'details') {
$categoryPages = $product->getCategoryPages();
foreach ($categoryPages as $categoryPage) {
$categoryId = $categoryPage->getId();
break;
}
}
// Add Quality to Badges
$quality = $product->getQualityStatus();
if (in_array($quality, [Product::QualityStatus_New, Product::QualityStatus_Platinum, Product::QualityStatus_Gold, Product::QualityStatus_Silver, Product::QualityStatus_Bronze, Product::QualityStatus_Bazaar])) {
$badgesRaw[] = strtolower(Product::getQualityStatusTitleForKey($quality));
}
// Windows
$windows = false;
$index = count($badgesRaw);
$allowedBadges = [
'bronze',
'silver',
'gold',
'platinum',
'new',
'bazaar',
'Chromebook',
'Windows 11',
];
if ($viewMode != 'list' && $viewMode != 'details') {
foreach ($product->getBadges() as $badge) {
if (!in_array($badge, $allowedBadges)) {
continue;
}
$isItWindows = strpos($badge, 'win');
if (($isItWindows !== false && !$this->showWindows) || $badge == '24h') {
continue;
}
if ($isItWindows !== false) {
if ($windows !== false) {
unset($badgesRaw[$windows]);
}
$windows = $index;
}
$badgesRaw[$index] = $badge;
$index++;
}
} else {
foreach ($product->getBadges() as $badge) {
if (in_array($badge, $allowedBadges)) {
$badgesRaw[$index] = $badge;
}
$index++;
}
}
// Limit Badges
$badges = array_slice($badgesRaw, 0, 4);
// Bestseller
if ( $product->hasBadgeItem(Product::PRODUCT_BADGE_BESTSELLER) ) {
$isBestseller = true;
} else {
$isBestseller = false;
}
// Short description
if ($this->showWindows) {
$shortDescription = $product->getDescription();
} else {
$shortDescription = str_replace([' | Win 7 Pro COA', ' | Win 7 Home COA', ' | Win 10 Pro', ' | Win 10 Home', ' | MAR Win 10 Pro'], '', $product->getDescription());
}
$timedSalesStartDate = false;
if (!is_null($priceMeta?->getSaleStart())) {
$salesStartDate = $priceMeta->getSaleStart();
$timedSalesStartDate = [
'year' => $salesStartDate->format('Y'),
'month' => $salesStartDate->format('M'),
'day' => $salesStartDate->format('d'),
'hour' => $salesStartDate->format('H'),
];
}
$timedSalesEndDate = false;
if (!is_null($priceMeta?->getSaleEnd())) {
$salesEndDate = $priceMeta->getSaleEnd();
$timedSalesEndDate = [
'year' => $salesEndDate->format('Y'),
'month' => $salesEndDate->format('M'),
'day' => $salesEndDate->format('d'),
'hour' => $salesEndDate->format('H'),
];
}
$currentVatPrice = $priceMeta
? $priceMeta->isDiscounted() ? $priceMeta->getDomainVatDiscount() : $priceMeta->getDomainVatPrice()
: null;
$couponWithBatch = $this->entityManager->getRepository(Coupon::class)
->getCouponsWithBadge($this->multiStore->getDomainId(), [$product->getType()]);
if (!$couponWithBatch?->isAvailableForDiscountedProducts() && $priceMeta->isDiscounted()) {
$couponWithBatch = null;
}
/** @var Coupon $activeCoupon */
$activeCoupon = $couponWithBatch ?? $product->getCoupons()->map(function (Coupon $coupon) {
if ($coupon->isActive() && $coupon->getDomain()->getId() == $this->priceDomain->getId()) {
return $coupon;
}
return null;
})->filter(function ($coupon) {
return !is_null($coupon);
})->first() ?: null;
if ($activeCoupon?->getCode() == 'SUMMER10') {
$activeCoupon = null;
}
if ($activeCoupon) {
switch ($activeCoupon->getDiscountType()) {
case Coupon::DISCOUNT_TYPE_PERCENT:
$discountPercentage = (100 - $activeCoupon->getDiscount()) / 100;
$priceWithCoupon = $priceMeta->getDomainVatPrice() * $discountPercentage;
break;
case Coupon::DISCOUNT_TYPE_PRICE:
$priceWithCoupon = $priceMeta->getDomainVatPrice() - $activeCoupon->getDiscount();
break;
default:
$priceWithCoupon = 0;
break;
}
} else {
$priceWithCoupon = 0;
}
if ($priceWithCoupon > 0) {
if (in_array($this->priceDomain->getId(), [Domain::DOMAIN_ID_WS_HU, Domain::DOMAIN_ID_RT_HU])) {
$priceWithCoupon = ceil($priceWithCoupon / 10) * 10;
} elseif (in_array($this->priceDomain->getId(), [Domain::DOMAIN_ID_WS_CZ, Domain::DOMAIN_ID_RT_CZ])) {
$priceWithCoupon = ceil($priceWithCoupon);
}
}
$productModelMeta = $product?->getProductModel()?->getProductModelMetas()->filter(function (ProductModelMeta $productModelMeta) {
return $productModelMeta->getLanguage()->getId() == $this->multiStore->getDefaultLanguageId();
})->first();
$warranties = null;
if ($viewMode == 'details') {
if (
in_array($product->getType()->getId(), [
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE,
ProductType::PRODUCT_TYPE_ID_MONITOR,
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_PC_SET,
])
&& $product->getQualityStatus() != Product::QualityStatus_Bazaar
) {
$warranties = [
AttributeOption::ATTRIBUTE_OPTION_1_YEAR_WARRANTY => [
'image' => 'theme/images/1-year-warranty.svg',
'additionalInfo' => 'total 3 years',
'percentPrice' => 10,
],
AttributeOption::ATTRIBUTE_OPTION_2_YEAR_WARRANTY => [
'image' => 'theme/images/2-year-warranty.svg',
'additionalInfo' => 'total 4 years',
'percentPrice' => 20,
],
AttributeOption::ATTRIBUTE_OPTION_3_YEAR_WARRANTY => [
'image' => 'theme/images/3-year-warranty.svg',
'additionalInfo' => 'total 5 years',
'percentPrice' => 30,
],
];
}
}
return [
'id' => $product->getId(),
'code' => $product->getCode(),
'partNumber' => !is_null($product->getPartNumber()) && $product->getPartNumber() != '' ? $product->getPartNumber() : '',
'active' => $priceMeta?->isActive() ?? false,
'listed' => $priceMeta?->isListed() ?? false,
'orderable' => $priceMeta && $priceMeta->isActive() && ($product->isAvailable() || ($product->isReservable() && $priceMeta->isReady())) && $priceMeta->isOrderable(),
'vendorId' => $product->getVendor()->getId(),
'vendor' => $product->getVendor()->getName(),
'productTypeId' => $product->getType()->getId(),
'productType' => $product->getType()->getTitle($this->translator),
'title' => in_array($this->priceDomainId, [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) ? str_replace([' (Quality: Bazar)', ' (Quality: Bazár)', ' (Quality: Bazár, '], ['', '', ' ('], $product->getName()) : $product->getName(),
'width' => $product->getWidth(),
'height' => $product->getHeight(),
'length' => $product->getlength(),
'weight' => $product->getWeight(),
'shortDescription' => $shortDescription,
'isDiscounted' => $priceMeta?->isDiscounted() ?? false,
'vat' => $priceMeta?->getVat() ?? 0,
'price' => $priceMeta?->getDomainPrice() ?? 0,
'rawPrice' => $priceMeta?->getPrice() ?? 0,
'vatPrice' => $priceMeta?->getDomainVatPrice() ?? 0,
'vatPriceWithCoupon' => $priceWithCoupon,
'discountPrice' => $priceMeta?->getDomainDiscount(),
'couponId' => $activeCoupon?->getId(),
'couponCode' => $activeCoupon?->getCode(),
'couponDiscount' => $activeCoupon?->getDiscount(),
'showCouponBadgeOnWebsite'=> $activeCoupon?->isShowBadgeOnWebsite(),
'rawDiscountPrice' => $priceMeta?->getDiscount(),
'discountVatPrice' => $priceMeta?->getDomainVatDiscount(),
'suggestedPrice' => $priceMeta?->getDomainSuggestedPrice(),
'suggestedVatPrice' => $priceMeta?->getDomainVatSuggestedPrice(),
'isAvailable' => $product->isAvailable(),
'availableQty' => $product->getAvailable(),
'additionalDetail' => $localeMeta?->getDetail(),
'warranty' => $priceMeta?->getWarranty(),
'bestSeller' => $priceMeta?->isBestSeller(),
'reLenovo' => $priceMeta?->isReLenovo(),
'hpRenew' => $priceMeta?->isHpRenew(),
'specialPromotion' => $priceMeta?->isSpecialPromotion(),
'badges' => $badges, // .label-{badge}
'badgesRaw' => $badgesRaw,
'attributes' => $specificationAttributes,
'isContainer' => $isContainer,
'containerParts' => $containerPartsSpecifications,
'attributesListTxt' => $specificationAttributesListText,
'accessories' => $accessoryAttributes,
'defaultOptions' => self::DEFAULT_ACCESSORY_SELECTIONS,
'images' => $images,
'categoryId' => $categoryId,
'qualityTitle' => $product->getQualityStatusTitle($product->getQualityStatus()),
'qualityStatusId' => $product->getQualityStatus(),
'timedSalesActive' => $priceMeta?->isTimedSaleActive(true),
'timedSalesStartDate' => $timedSalesStartDate,
'timedSalesEndDate' => $timedSalesEndDate,
'reviewCount' => $review_count,
'reviewStars' => $review_stars,
'reviews' => $reviews,
'freeShipping' => $freeShipLimit < $currentVatPrice,
'isReservable' => ($priceMeta?->isReady() && $priceMeta?->isActive() && $product->isReservable()),
'orderWaitingDays' => $orderWaitingDays,
'outOfStockStatus' => $product->getOutOfStockStatus(),
'productModelDescription' => $productModelMeta ? $this->getProductMetaText($productModelMeta->getText(), $specificationAttributes) : null,
'warranties' => $warranties,
'connectedBatteries' => $connectedBatteries,
'batterAttributeOptionId' => $batterAttributeOptionId,
'isBestseller' => $isBestseller,
'isBazaar' => $product->isBazaar()
];
}
/**
* @param $productIds
* @return array
*/
public function getStructuredDataByProductIds($productIds)
{
$products = [];
$productRepo = $this->entityManager->getRepository(Product::class);
foreach ($productIds as $productId) {
$product = $productRepo->findOneById($productId);
if ($product) {
$products[] = $product;
}
}
return $this->getStructuredDataForProducts($products);
}
/**
* @param int $productId
* @param string $viewMode
* @return array
*/
public function getStructuredDataByProductId(int $productId, string $viewMode = 'details'): array
{
$productRepo = $this->entityManager->getRepository(Product::class);
$product = $productRepo->findOneById($productId);
return $product ? $this->getStructuredDataForProduct($product, $viewMode) : [];
}
/**
* @param array $filter
* @param array $options
* @return array
*/
public function getStructuredDataByFilters(array $filter = [], array $options = []): array
{
$products = [];
if (isset($filter['filterCategoryId'])) {
$categoryPage = $this->entityManager->find(CategoryPage::class, $filter['filterCategoryId']);
$priorityProducts = $this->getPriorityProductsForCategoryPages($filter, $categoryPage);
/**
* @var Product $product
*/
foreach ($priorityProducts as $product) {
$products[$product->getId()] = $this->getStructuredDataForProduct($product, 'list');
}
if (!$this->isUserApplyingFilters($filter, $categoryPage) && count($priorityProducts) > 0) {
$filter['limit'] -= count($priorityProducts) - 1;
}
}
$query = $this->getProductListingQuery($filter, $options);
$results = new Paginator($query);
/**
* @var Product $product
*/
foreach ($results as $product) {
$products[$product->getId()] = $this->getStructuredDataForProduct($product, 'list');
}
return $products;
}
/**
* @param SeoUrlHelper $seoUrlHelper
* @param array $filter
* @param $translator
* @return array
*/
public function getVariantsForFilter(SeoUrlHelper $seoUrlHelper, $translator, array $filter = []): array
{
$query = $this->getProductVariantsQuery($filter);
$results = new Paginator($query, true);
$products = [];
$i = 0;
foreach ($results as $product) {
$productData = $this->getStructuredDataByProductId($product->getId(), 'list');
$products[$i]['description'] = explode(' | ', $product->getDescription());
$products[$i]['link'] = $seoUrlHelper->link('product', [
'product_id' => $product->getId(),
'isBazaar' => $product->isBazaar()
]);
$products[$i]['price'] = $filter['basePrice'] == MultiStore::BASE_PRICE_GROSS ?
($productData['isDiscounted'] ? $productData['discountVatPrice'] : $productData['vatPrice']) :
($productData['isDiscounted'] ? $productData['discountPrice'] : $productData['price']);
$products[$i]['oldPriceForDiscount'] = $filter['basePrice'] == MultiStore::BASE_PRICE_GROSS ? $productData['vatPrice'] : $productData['price'];
$products[$i]['isDiscounted'] = $productData['isDiscounted'];
$products[$i]['qualityStatusId'] = $productData['qualityStatusId'];
$products[$i]['quality'] = $translator->trans($productData['qualityTitle']);
$products[$i]['title'] = $productData['vendor'] . ' ' . $productData['title'];
$image = '';
if (is_object($productData['images'])) {
$image = $this->getImage($productData['images'], 'product/' . $productData['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$products[$i]['image'] = $image;
$i++;
}
return $products;
}
/**
* @param array $filter
* @return int
*/
public function getTotalByFilters(array $filter = []): int
{
$query = $this->getProductListingQuery($filter, [
'count' => true,
]);
$result = $query->getSingleScalarResult();
return (int)$result;
}
/**
* @param array $filter
* @param array $options
* @return array
*/
public function getStructuredDataForWizard(array $filter = [], array $options = []): array
{
$query = $this->getListForWizard($filter, $options);
$results = new Paginator($query, $fetchJoinCollection = true);
$products = [];
foreach ($results as $result) {
$products[$result->getId()] = $this->getStructuredDataForProduct($result, 'list');
}
return $products;
}
/**
* @param array $filter
* @return int
*/
public function getCountForWizard(array $filter = []): int
{
$query = $this->getListForWizard($filter, [
'count' => true,
]);
$result = $query->getSingleScalarResult();
return (int)$result;
}
/**
* @param array $filter
* @param array $options
* @return array
*/
public function buildFilterOptions(array $filter, array $options = []): array
{
// Attribute Filter by Category Page
$attributeFilters = [];
$vendors = $productTypes = [];
// For Latest list page
$categoryFilters = [];
//Switch for notebook show
$notebookShow = false;
$useSalesFilters = in_array($filter['filterCategoryId'], CategoryPage::SALE_CATEGORY_PAGES) && !is_null($filter['filterProductType']);
if (isset($filter['filterCategoryId']) && $useSalesFilters) {
$isOtherCategory = false;
if ($filter['filterProductType'] == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$notebookShow = true;
} else if ($filter['filterProductType'] == ProductType::PRODUCT_TYPE_ID_OTHER) {
$categoryPage = $filter['filterCategoryId'] > 0
? $this->entityManager->getRepository(CategoryPage::class)->findOneById($filter['filterCategoryId'])
: false;
if ($categoryPage) {
$isOtherCategory = true;
foreach ($categoryPage->getProducts() as $product) {
$productType = $product->getType();
if (in_array($productType->getId(), ProductType::getSaleProductTypeFilterTypes())) {
continue;
}
if (!isset($productTypes[$productType->getId()])) {
$productTypes[$productType->getId()] = [
'id' => $productType->getId(),
'name' => $productType->getTitle($this->translator),
];
}
}
}
}
$filterAttribute = [];
if (isset($filter['filterAttribute'])) {
$filterAttribute = $filter['filterAttribute'];
}
$filters = $isOtherCategory
? []
: CategoryPage::getFiltersForProductType((int)$filter['filterProductType']);
foreach ($filters as $attributeId) {
$attributeFilter = $filterAttribute;
$attribute = $this->entityManager->getRepository(Attribute::class)
->findOneById($attributeId);
if ($attribute) {
$attributeFilters[$attribute->getId()] = [
'id' => $attribute->getId(),
'title' => $attribute->getTitle($this->translator),
'filter' => $attributeFilter,
'options' => [],
];
}
}
}
else if (isset($filter['filterCategoryId'])) {
$categoryPage = $filter['filterCategoryId'] > 0
? $this->entityManager->getRepository(CategoryPage::class)->findOneById($filter['filterCategoryId'])
: false;
$filterAttribute = [];
if (isset($filter['filterAttribute'])) {
$filterAttribute = $filter['filterAttribute'];
}
if ($categoryPage) {
foreach ($categoryPage->getFilterAttributes() as $categoryFilterAttribute) {
$attributeFilter = $filterAttribute;
$attribute = $categoryFilterAttribute->getAttribute();
$attributeFilters[$attribute->getId()] = [
'id' => $attribute->getId(),
'title' => $attribute->getTitle($this->translator),
'filter' => $attributeFilter,
'options' => [],
];
}
}
if ($categoryPage->getProductTypes()->count() == 1) {
$productType = $categoryPage->getProductTypes()->first();
if ($productType->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$notebookShow = true;
}
}
if ($categoryPage->getProductTypes()->count() > 1) {
foreach ($categoryPage->getProductTypes() as $key => $productType) {
if ($productType->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$notebookShow = true;
}
$productTypes[$productType->getId()] = [
'id' => $productType->getId(),
'name' => $productType->getTitle($this->translator),
];
}
}
//show productTypes always
if (count($productTypes) == 0) {
/** @var Product $product */
foreach ($categoryPage->getProducts() as $product) {
$productType = $product->getType();
if ($productType->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$notebookShow = true;
}
$isSetShow = in_array($categoryPage->getId(), [217, 218, 219]) && $productType->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK;
$productTypes[$productType->getId()] = [
'id' => $productType->getId(),
'name' => $isSetShow ? $this->translator->trans('notebook set') : $productType->getTitle($this->translator),
];
if ($product->getTags()->count() > 0) {
$newBattery = $product->getTags()->exists(fn(int $index, ProductTag $tag) => $tag->getTitle() == 'New battery - Notebook');
if ($newBattery) {
$attributeFilters['newBattery'] = [
'id' => 'newBattery',
'title' => $this->translator->trans('New battery'),
'filter' => $filterAttribute,
'options' => [
[
'id' => '1',
'title' => $this->translator->trans('Yes'),
'count' => 0,
'sortOrder' => 1,
],
],
];
}
}
}
}
//EXTRA PAGES FOR NOOTEBOOK SHOW
if (in_array($categoryPage->getId(), [615, 614, 217, 218, 219, 627, 625])) {
$notebookShow = true;
}
if ($notebookShow && !isset($attributeFilters['newBattery'])) {
$categoryProductTypes = $categoryPage->getProductTypes();
if ($categoryProductTypes->count() == 1 && $categoryProductTypes->first()->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
$newBatteryProducts = $this->entityManager->getRepository(Product::class)->createQueryBuilder('p')
->select('COUNT(p.id) as count')
->innerJoin('p.tags', 't')
->where('t.title = :newBattery')
->setParameter('newBattery', 'New battery - Notebook')
->getQuery()->getSingleScalarResult();
if ($newBatteryProducts > 0) {
$attributeFilters['newBattery'] = [
'id' => 'newBattery',
'title' => $this->translator->trans('New battery'),
'filter' => '',
'options' => [
[
'id' => 'newBattery',
'title' => $this->translator->trans('Yes'),
"count" => 0,
'sortOrder' => 1,
],
],
];
}
}
}
}
else if (isset($filter['isNewProductPage'])) {
$categoryFilters = $this->getCategoryFilters($filter['language']);
}
else if (isset($options['search'])) {
// Filter Attribute
$filterAttribute = [];
if (isset($filter['filterAttribute'])) {
$filterAttribute = $filter['filterAttribute'];
}
// Add Filter Quality
$attribute = $this->entityManager->getRepository(Attribute::class)->findOneById(Attribute::ATTRIBUTE_ID_QUALITY);
if ($attribute) {
$attributeFilter = $filterAttribute;
if (isset($attributeFilter[$attribute->getId()])) {
unset($attributeFilter[$attribute->getId()]);
}
$attributeFilters[$attribute->getId()] = [
'id' => $attribute->getId(),
'title' => $attribute->getTitle($this->translator),
'filter' => $attributeFilter,
'options' => [],
];
}
}
$results = $this->getFilterListingResults($filter, $options);
$priceMin = $priceMax = false;
$productTypes ? $productTypesSet = true : $productTypesSet = false;
if ($notebookShow) {
//ADD TN display type
$panelIds = $this->getTnDisplayAttributeOptionIds();
if ($panelIds != '') {
$attributeFilters[Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY]['options'][] = [
'id' => $panelIds,
'title' => 'TN',
'sortOrder' => 1,
];
}
}
/** @var Product $product */
foreach ($results as $product) {
$vendor = $product->getVendor();
if ($vendor) {
if (!isset($vendors[$vendor->getId()])) {
$vendors[$vendor->getId()] = [
'id' => $vendor->getId(),
'name' => $vendor->getName(),
'count' => 0,
'sortOrder' => $vendor->getSortIndex(),
];
}
}
$productType = $product->getType();
if ($productType && isset($options['search'])) {
if (!isset($productTypes[$productType->getId()])) {
$productTypes[$productType->getId()] = [
'id' => $productType->getId(),
'name' => $productType->getTitle($this->translator),
'count' => 0,
];
}
}
$productMeta = $product->getDomainMeta($this->priceDomain);
if ($productMeta) {
$price = (float)$productMeta->getCurrentVatPrice();
if ($priceMin === false || $priceMax === false) {
$priceMin = $priceMax = $price;
}
if ($priceMin > $price) {
$priceMin = $price;
}
if ($priceMax < $price) {
$priceMax = $price;
}
}
if (!empty($attributeFilters)) {
$productAttributes = $product->getProductAttributes();
if ($productAttributes) {
/** @var ProductAttribute $productAttribute */
foreach ($productAttributes as $productAttribute) {
$option = $productAttribute->getOption();
$attribute = $option->getAttribute();
if (isset($attributeFilters[$attribute->getId()]) && isset($attributeFilters[$attribute->getId()]['filter'])) {
if (!isset($attributeFilters[$attribute->getId()]['options'][$option->getId()])) {
$attributeFilter = $attributeFilters[$attribute->getId()]['filter'];
$attributeFilter[$attribute->getId()] = $option->getId();
$attributeFilters[$attribute->getId()]['options'][$option->getId()] = [
'id' => $option->getId(),
'title' => $option->getTitle($this->translator),
'count' => 0,
'sortOrder' => $option->getSortIndex(),
];
}
}
}
}
}
}
if (!$productTypesSet && count($productTypes) < 2) {
$productTypes = [];
}
$sortedVendors = [];
if (!empty($vendors)) {
//HP, DELL, LENOVO AND APPLE
$mainVendors = [];
$otherVendors = [];
$mainNameHelper = [];
$otherNameHelper = [];
foreach ($vendors as $key => $row) {
if (in_array($key, Vendor::MAIN_NOTEBOOK_VENDOR_LIST) || in_array($key, explode(',', $filter['filterVendor']))) {
$mainVendors[$key] = $row;
$mainNameHelper[$key] = $row['name'];
} else {
$otherVendors[$key] = $row;
$otherNameHelper[$key] = $row['name'];
}
}
array_multisort($mainNameHelper, SORT_ASC, $mainVendors);
array_multisort($otherNameHelper, SORT_ASC, $otherVendors);
if ($notebookShow) {
$sortedVendors = [
'main' => $mainVendors,
'other' => $otherVendors,
];
} else {
$sortedVendors = array_merge($mainVendors, $otherVendors);
}
}
if (!empty($productTypes)) {
$name = [];
foreach ($productTypes as $key => $row) {
$name[$key] = $row['name'];
}
array_multisort($name, SORT_ASC, $productTypes);
}
if (!empty($attributeFilters)) {
foreach ($attributeFilters as $attributeId => $attribute) {
$sortOrder = [];
$options = $attribute['options'];
if (in_array($attributeId, [1, 12, 25, 45, 46, 63, 68, 141])) {
foreach ($options as $key => $value) {
$sortOrder[$key] = $value['title'];
}
} else {
foreach ($options as $key => $value) {
$sortOrder[$key] = $value['sortOrder'];
}
}
if ($attributeId == Attribute::ATTRIBUTE_ID_CPU_PC_FAMILY) {
array_multisort($sortOrder, SORT_DESC, $options);
} else {
array_multisort($sortOrder, SORT_ASC, $options);
}
if ($attributeId == Attribute::ATTRIBUTE_ID_CONF_NOTEBOOK_SKIN) {
$this->updateFilterOptionsWithThumbnails($options);
}
$attributeFilters[$attributeId]['options'] = $options;
}
}
return [
'list' => in_array($filter['filterCategoryId'], CategoryPage::SALE_CATEGORY_PAGES) && !$useSalesFilters
? ['main' => []]
: $this->buildFilterSections($productTypes, $categoryFilters, $sortedVendors, $attributeFilters, $filter, $notebookShow),
'priceMin' => floor($priceMin),
'priceMax' => ceil($priceMax),
'cpuMarkMin' => $filter['filterCpuMarkMin'] ?? null,
'cpuMarkMax' => $filter['filterCpuMarkMax'] ?? null,
'notebookShow' => $notebookShow,
'productTypes' => $productTypes,
];
}
/**
* @param array $productTypes
* @param array $categoryFilters
* @param array $vendors
* @param array $attributeFilters
*/
private function buildFilterSections(array $productTypes, array $categoryFilters, array $vendors, array $attributeFilters, array $checkedFilterList, bool $notebookShow): array
{
$filterList = [];
if (count($categoryFilters) > 0) {
$filterList = [
'categoryFilters' => [
'sortOrder' => 0,
'collapseTitle' => 'Categories',
'templateId' => 'category',
'inputName' => 'category',
'checkedList' => $checkedFilterList['filterCategories'],
'isCollapsed' => false,
'filters' => $categoryFilters,
],
];
}
$filterList[] = [
'sortOrder' => 1,
'collapseTitle' => 'Product type',
'templateId' => 'productType',
'inputName' => 'product-type',
'checkedList' => $checkedFilterList['filterProductType'] ?? null,
'isCollapsed' => false,
'filters' => $productTypes,
];
$filterList[] = [
'sortOrder' => 2,
'collapseTitle' => 'Brand',
'templateId' => 'vendorFilter',
'inputName' => 'vendor',
'checkedList' => $checkedFilterList['filterVendor'],
'isCollapsed' => false,
'filters' => $vendors,
];
$filterSorting = [
$this->translator->trans('Categories') => 0,
$this->translator->trans('Product type') => 1,
$this->translator->trans('Brand') => 2,
$this->translator->trans('Year of production') => 3,
$this->translator->trans('Quality') => 4,
$this->translator->trans('Operating system') => 5,
$this->translator->trans('Screen size') => 6,
$this->translator->trans('CPU mark') => 7,
$this->translator->trans('RAM size') => 8,
$this->translator->trans('SSD') => 9,
$this->translator->trans('New battery') => 10,
$this->translator->trans('CPU NB FAMILY') => 11,
$this->translator->trans('Maximum resolution') => 12,
$this->translator->trans('Notebook skin') => 13,
$this->translator->trans('Touchscreen') => 14,
$this->translator->trans('Webcam') => 15,
$this->translator->trans('Connectors external NB') => 16,
$this->translator->trans('NumPad') => 17,
$this->translator->trans('CPU Generation') => 18,
$this->translator->trans('VGA') => 19,
$this->translator->trans('RAM NB type') => 20,
$this->translator->trans('Display Technology') => 21,
$this->translator->trans('ODD NB') => 22,
$this->translator->trans('HDD 2,5"') => 23,
$this->translator->trans('Disk capacity') => 24,
$this->translator->trans('Contrast ratio') => 25,
$this->translator->trans('Keyboard language') => 26,
];
// Attribute Option Groups
$attributeOptionGroups = AttributeOption::getAttributeOptionGroups();
$count = 0;
$sortOrderCount = count($filterSorting);
foreach ($attributeFilters as $attributeFilter) {
$count++;
$extraInfo = null;
$customCountToShow = null;
if (!isset($attributeFilter['id'])){
continue;
}
$filterOptions = in_array($attributeFilter['id'], [141, 142]) //142 == CPU NB FAMILY
? array_reverse($attributeFilter['options'])
: $attributeFilter['options'];
if ($notebookShow) {
//Screen size
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_SCREEN_SIZE) {
//NE TOROLD KI A SPACEKETE AZ IDNEL " "
$screenSizeFilter = [
0 => [
'title' => 'filterTranslation.screenSize.small',
'id' => ' ',
],
1 => [
'title' => 'filterTranslation.screenSize.medium',
'id' => ' ',
],
2 => [
'title' => 'filterTranslation.screenSize.big',
'id' => ' ',
],
];
foreach ($filterOptions as $option) {
preg_match('/\d+,\d+"/', $option['title'], $matches);
if (!empty($matches)) {
$screenSize = (float)str_replace(',', '.', $matches[0]);
if ($screenSize < 13) {
$screenSizeFilter[0]['id'] .= $option['id'] . ',';
} elseif ($screenSize < 15) {
$screenSizeFilter[1]['id'] .= $option['id'] . ',';
} else {
$screenSizeFilter[2]['id'] .= $option['id'] . ',';
}
}
}
// Remove trailing commas from screen size filters
$screenSizeFilter[0]['id'] = rtrim($screenSizeFilter[0]['id'], ',');
$screenSizeFilter[1]['id'] = rtrim($screenSizeFilter[1]['id'], ',');
$screenSizeFilter[2]['id'] = rtrim($screenSizeFilter[2]['id'], ',');
$filterOptions = $screenSizeFilter;
}
//Ram size
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_RAM_SIZE) {
//NE TOROLD KI A SPACEKETE AZ IDNEL " "
$ramSizeFilter = [
0 => [
'title' => 'filterTranslation.ramSize.small',
'id' => ' ',
],
1 => [
'title' => '8GB',
'id' => ' ',
],
2 => [
'title' => '16GB',
'id' => ' ',
],
3 => [
'title' => 'filterTranslation.ramSize.big',
'id' => ' ',
],
];
foreach ($filterOptions as $option) {
preg_match('/\d+GB/', $option['title'], $matches);
if (!empty($matches)) {
$ramSize = (int)$matches[0];
if ($ramSize < 8) {
$ramSizeFilter[0]['id'] .= $option['id'] . ',';
} elseif ($ramSize < 16) {
$ramSizeFilter[1]['id'] .= $option['id'] . ',';
} elseif ($ramSize == 16) {
$ramSizeFilter[2]['id'] .= $option['id'] . ',';
} else {
$ramSizeFilter[3]['id'] .= $option['id'] . ',';
}
}
}
$ramSizeFilter[0]['id'] = rtrim($ramSizeFilter[0]['id'], ',');
$ramSizeFilter[1]['id'] = rtrim($ramSizeFilter[1]['id'], ',');
$ramSizeFilter[2]['id'] = rtrim($ramSizeFilter[2]['id'], ',');
$filterOptions = $ramSizeFilter;
}
//SSD size
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_SSD) {
//NE TOROLD KI A SPACEKETE AZ IDNEL " "
$ssdSizeFilter = [
0 => [
'title' => 'filterTranslation.ssdSize.small',
'id' => ' ',
],
1 => [
'title' => 'filterTranslation.ssdSize.normal',
'id' => ' ',
],
2 => [
'title' => 'filterTranslation.ssdSize.medium',
'id' => ' ',
],
3 => [
'title' => 'filterTranslation.ssdSize.big',
'id' => ' ',
],
];
foreach ($filterOptions as $option) {
preg_match('/\d+GB/', $option['title'], $matches);
if (!empty($matches)) {
$ssdSize = (int)$matches[0];
if ($ssdSize < 240) {
$ssdSizeFilter[0]['id'] .= $option['id'] . ',';
} elseif ($ssdSize <= 256) {
$ssdSizeFilter[1]['id'] .= $option['id'] . ',';
} elseif ($ssdSize <= 512) {
$ssdSizeFilter[2]['id'] .= $option['id'] . ',';
} else {
$ssdSizeFilter[3]['id'] .= $option['id'] . ',';
}
} else {
preg_match('/\d+TB/', $option['title'], $matches);
if (!empty($matches)) {
$ssdSizeFilter[3]['id'] .= $option['id'] . ',';
}
}
}
$ssdSizeFilter[0]['id'] = rtrim($ssdSizeFilter[0]['id'], ',');
$ssdSizeFilter[1]['id'] = rtrim($ssdSizeFilter[1]['id'], ',');
$ssdSizeFilter[2]['id'] = rtrim($ssdSizeFilter[2]['id'], ',');
$ssdSizeFilter[3]['id'] = rtrim($ssdSizeFilter[2]['id'], ',');
$filterOptions = $ssdSizeFilter;
}
//QUALITY sorting + info text
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_QUALITY) {
usort($filterOptions, function ($a, $b) {
return $a['id'] <=> $b['id'];
});
switch ($this->localeDomainId) {
case Domain::DOMAIN_ID_RT_HU:
case Domain::DOMAIN_ID_WS_HU:
$pageId = 27;
break;
case Domain::DOMAIN_ID_RT_SK:
case Domain::DOMAIN_ID_WS_SK:
$pageId = 11;
break;
case Domain::DOMAIN_ID_RT_CZ:
case Domain::DOMAIN_ID_WS_CZ:
$pageId = 60;
break;
case Domain::DOMAIN_ID_RT_EU:
case Domain::DOMAIN_ID_WS_EU:
case Domain::DOMAIN_ID_B2C_EU:
$pageId = 100;
break;
}
$extraInfo = [
'transKey' => 'filterExtraInfos.quality',
'url' => $this->router->generate('page_show', [
'pageId' => $pageId,
], UrlGeneratorInterface::ABSOLUTE_URL),
];
}
//Notebook skin remove and replace with custom hint text
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_CONF_NOTEBOOK_SKIN) {
$filterOptions = [];
$extraInfo = [
'transKey' => 'filterExtraInfos.colors',
];
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_TOUCH_SCREEN) {
$touchScreenFilter = [
[
'id' => AttributeOption::ATTRIBUTE_OPTION_TOUCHSCREEN,
'title' => 'yes',
],
];
$filterOptions = $touchScreenFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_WEBCAM) {
$webcamIds = '';
foreach ($filterOptions as $option) {
if ($option['id'] != AttributeOption::ATTRIBUTE_OPTION_NO_WEBCAM) {
$webcamIds .= $option['id'] . ',';
}
}
$webcamIds = rtrim($webcamIds, ',');
$webcamFilter = [
[
'id' => $webcamIds,
'title' => 'yes',
],
[
'id' => AttributeOption::ATTRIBUTE_OPTION_NO_WEBCAM,
'title' => 'no',
],
];
$filterOptions = $webcamFilter;
}
//Remove the keyboard languages from the filter
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_KEYBOARD_LANGUAGE) {
$filterOptions = [];
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_EXTERNAL_CONNECTORS) {
$connectorsFilter = [];
$textToFinc = [
'HDMI',
'VGA',
'Display port',
'Thunderbolt',
'USB 2',
'USB 3',
'USB Type-C',
'RJ45 (LAN)',
];
foreach ($filterOptions as $option) {
foreach ($textToFinc as $key => $title) {
//option title contains the title
if (str_contains(strtoupper($option['title']), strtoupper($title))) {
if (!isset($connectorsFilter[$key])) {
$connectorsFilter[$key] = [
'id' => $option['id'],
'title' => $title,
];
} else {
$connectorsFilter[$key]['id'] .= ',' . $option['id'];
}
}
}
}
ksort($connectorsFilter);
$filterOptions = $connectorsFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_NUMPAD) {
$numpadFilter = [
[
'id' => AttributeOption::ATTRIBUTE_OPTION_NUMPAD,
'title' => 'yes',
], [
'id' => AttributeOption::ATTRIBUTE_OPTION_NO_NUMPAD,
'title' => 'no',
],
];
$filterOptions = $numpadFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY) {
$order = ['TN', 'IPS', 'OLED'];
usort($filterOptions, function ($a, $b) use ($order) {
return array_search($a['title'], $order) <=> array_search($b['title'], $order);
});
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_OPTICAL_DRIVER) {
$opticalDriverIdString = ' ';
foreach ($filterOptions as $option) {
if ($option['id'] != AttributeOption::ATTRIBUTE_OPTION_NO_OOD) {
$opticalDriverIdString .= $option['id'] . ',';
}
}
$opticalDriverIdString = rtrim($opticalDriverIdString, ',');
$opticalDriverFilter = [
[
'id' => $opticalDriverIdString,
'title' => 'yes',
], [
'id' => AttributeOption::ATTRIBUTE_OPTION_NO_OOD,
'title' => 'no',
],
];
$filterOptions = $opticalDriverFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_VGA) {
//NE TOROLD KI A SPACEKETE AZ IDNEL " "
$vgaFilter = [
[
'id' => ' ',
'title' => 'filterTranslation.vga.integrated',
], [
'id' => ' ',
'title' => 'filterTranslation.vga.gaming',
], [
'id' => ' ',
'title' => 'filterTranslation.vga.graphic',
],
];
foreach ($filterOptions as $option) {
//Gaming
if (str_contains(strtoupper($option['title']), 'RTX')
|| str_contains(strtoupper($option['title']), 'GTX')
|| str_contains(strtoupper($option['title']), 'GT')) {
$vgaFilter[1]['id'] .= ',' . $option['id'];
}
//Graphic
elseif (str_contains(strtoupper($option['title']), 'QUADRO')
|| str_contains(strtoupper($option['title']), 'FIREPRO')) {
$vgaFilter[2]['id'] .= ',' . $option['id'];
//Other
} else {
$vgaFilter[0]['id'] .= ',' . $option['id'];
}
}
$filterOptions = $vgaFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_YEAR_OF_PRODUCTION) {
$yearFilter = [
[
'id' => $this->getAttributeOptionIdsBasedOnTheAge(self::AGE_0_to_2_YEARS),
'title' => '0-2',
], [
'id' => $this->getAttributeOptionIdsBasedOnTheAge(self::AGE_3_to_5_YEARS),
'title' => '3-5',
], [
'id' => $this->getAttributeOptionIdsBasedOnTheAge(self::AGE_6_PLUS_YEARS),
'title' => '6+',
],
];
$filterOptions = $yearFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_ACCESSORY_OS) {
$osFilter = [
1 => [
'title' => 'Windows 11',
'id' => ' ',
],
0 => [
'title' => 'Windows 10',
'id' => ' ',
],
2 => [
'title' => 'Mac OS',
'id' => ' ',
],
];
foreach ($filterOptions as $option) {
if (str_contains(strtoupper($option['title']), 'WINDOWS 10')) {
$osFilter[0]['id'] .= $option['id'] . ',';
} elseif (str_contains(strtoupper($option['title']), 'WINDOWS 11')) {
$osFilter[1]['id'] .= $option['id'] . ',';
} elseif (str_contains(strtoupper($option['title']), 'MAC OS') || str_contains(strtoupper($option['title']), 'MACOS')) {
$osFilter[2]['id'] .= $option['id'] . ',';
}
}
$osFilter[0]['id'] = rtrim($osFilter[0]['id'], ',');
$osFilter[1]['id'] = rtrim($osFilter[1]['id'], ',');
$osFilter[2]['id'] = rtrim($osFilter[2]['id'], ',');
$filterOptions = $osFilter;
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION) {
$resolutionFilter = [
0 => [
'title' => 'filterTranslation.resolution.small',
'id' => ' ',
],
1 => [
'title' => 'filterTranslation.resolution.fullHd',
'id' => ' ',
],
2 => [
'title' => 'filterTranslation.resolution.big',
'id' => ' ',
],
];
foreach ($filterOptions as $option) {
if (preg_match('/(\d+)\s*x/', $option['title'], $matches)) {
$numberBeforeX = $matches[1];
if ($numberBeforeX < 1920) {
$resolutionFilter[0]['id'] .= $option['id'] . ',';
} elseif ($numberBeforeX == 1920) {
if (preg_match('/x\s*(\d+)/', $option['title'], $matches)) {
$numberAfterX = $matches[1];
if (in_array($numberAfterX, [1080, 1200])) {
$resolutionFilter[1]['id'] .= $option['id'] . ',';
} else {
$resolutionFilter[2]['id'] .= $option['id'] . ',';
}
}
} else {
$resolutionFilter[2]['id'] .= $option['id'] . ',';
}
}
}
$resolutionFilter[0]['id'] = rtrim($resolutionFilter[0]['id'], ',');
$resolutionFilter[1]['id'] = rtrim($resolutionFilter[1]['id'], ',');
$resolutionFilter[2]['id'] = rtrim($resolutionFilter[2]['id'], ',');
$customCountToShow = 3;
$filterOptions = array_merge($resolutionFilter, $filterOptions);
}
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_CPU_MARK) {
$pageId = match ($this->localeDomain->getId()) {
Domain::DOMAIN_ID_RT_HU, Domain::DOMAIN_ID_WS_HU => 175,
Domain::DOMAIN_ID_RT_SK, Domain::DOMAIN_ID_WS_SK => 176,
Domain::DOMAIN_ID_RT_CZ, Domain::DOMAIN_ID_WS_CZ => 177,
Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU => 178,
};
$extraInfo = [
'transKey' => 'filterExtraInfos.cpu_mark',
'url' => $this->router->generate('page_show', [
'pageId' => $pageId,
], UrlGeneratorInterface::ABSOLUTE_URL),
];
}
}
else {
// Merge option rows
if (isset($attributeOptionGroups[$attributeFilter['id']])) {
foreach ($attributeOptionGroups[$attributeFilter['id']] as $group) {
$countItems = 0;
$affectedAttributeOptions = [];
foreach ($attributeFilter['options'] as $key => $option) {
if (in_array($option['id'], $group)) {
$affectedAttributeOptions[(int)$option['id']] = $key;
$countItems += (int)$option['count'];
}
}
foreach ($group as $optionId) {
if (isset($affectedAttributeOptions[$optionId])) {
unset($affectedAttributeOptions[$optionId]);
$filterOptions[$key]['count'] = $countItems;
break;
}
}
foreach ($affectedAttributeOptions as $key) {
unset($filterOptions[$key]);
}
}
}
}
// 5 = SSD, 12 = Screen, 384 = Ram, 101 = Quality, 139 = Touchscreen, 19 = Webcam, 45 = Connectors, 118 = DisplayTechnology,
// 11 = OpticalDriver, 25 = VGA, 17 = Numpad, 21 = OperationSystem, 63 = MaxResolution
$skipShortingIds = $notebookShow
? [5, 3, 9, 4, 12, 384, 101, 139, 19, 45, 118, 11, 25, 17, 21, 63]
: [5, 3, 9, 4, 101];
if (!in_array($attributeFilter['id'], $skipShortingIds)) {
$filterOptions = $this->orderArrayBy($filterOptions, 'title');
}
switch ($attributeFilter['id']) {
case Attribute::ATTRIBUTE_ID_CPU_GENERATION:
$filterOptions = $this->orderArrayBy($filterOptions, 'sortOrder');
break;
case Attribute::ATTRIBUTE_ID_RAM_SIZE:
if (!$notebookShow) {
$filterOptions = $this->orderArrayBy($filterOptions, 'title', 'GB');
}
break;
}
$checkedList = $checkedFilterList['filterAttribute'] && array_key_exists($attributeFilter['id'], $checkedFilterList['filterAttribute'])
? $checkedFilterList['filterAttribute'][$attributeFilter['id']]
: '';
if (in_array($attributeFilter['id'], [
Attribute::ATTRIBUTE_ID_RAM_NB_TYPE,
])) {
$collapsed = true;
} elseif (in_array($attributeFilter['id'], [
Attribute::ATTRIBUTE_ID_YEAR_OF_PRODUCTION,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_CPU_MARK,
Attribute::ATTRIBUTE_ID_ACCESSORY_OS,
'newBattery',
])) {
$collapsed = false;
} else {
$collapsed = ($count > 5 && $checkedList == '' && $attributeFilter['id'] != Attribute::ATTRIBUTE_ID_SSD);
}
$filterList[] = [
'sortOrder' => isset($filterSorting[$attributeFilter['title']]) ? $filterSorting[$attributeFilter['title']] : $sortOrderCount++,
'filterId' => $attributeFilter['id'],
'collapseTitle' => $attributeFilter['title'],
'templateId' => 'attributeFilter-' . $attributeFilter['id'],
'inputName' => $attributeFilter['id'] == Attribute::ATTRIBUTE_ID_CPU_MARK ? 'CPU mark' : 'attribute',
'checkedList' => $checkedList,
'isCollapsed' => $collapsed,
'filters' => $filterOptions,
'extraInfo' => $extraInfo,
'customCountToShow' => $customCountToShow,
];
if ($attributeFilter['id'] == Attribute::ATTRIBUTE_ID_HDD_25) {
$filterList[key(array_slice($filterList, -1, 1, true))]['collapseTitle'] = "HDD";
}
}
if ($notebookShow) {
usort($filterList, function ($a, $b) {
return $a['sortOrder'] <=> $b['sortOrder'];
});
}
return [
'main' => $filterList,
];
}
/**
* @param array $items
* @param string $attr
* @param string $textToRemove
* @param string $order
* @return array
*/
private function orderArrayBy(array $items, string $attr, string $textToRemove = '', string $order = 'asc'): array
{
$sortedItems = [];
foreach ($items as $item) {
$key = is_object($item) ? str_replace($textToRemove, '', $item->{$attr}) : str_replace($textToRemove, '', $item[$attr]);
$sortedItems[$key] = $item;
}
if ($order === 'desc') {
krsort($sortedItems);
} else {
ksort($sortedItems);
}
return array_values($sortedItems);
}
/**
* @param array &$filterOptions
*/
private function updateFilterOptionsWithThumbnails(array &$filterOptions): void
{
$filterOptionIds = array_column($filterOptions, 'id');
$attributeOptions = $this->entityManager->getRepository(AttributeOption::class)->findBy([
'id' => $filterOptionIds,
]);
/**
* @var AttributeOption $attributeOption
*/
foreach ($attributeOptions as $key => $attributeOption) {
if ($attributeOption->getProduct() != null) {
$filterOptions[$key]['thumb'] = $this->getImage($attributeOption->getProduct()->getAlbum()->getNthPhoto(), 'product/' . $attributeOption->getProduct()->getCode())->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
}
}
/**
* @param string $language
* @return array
*/
private function getCategoryFilters(string $language): array
{
// Translator
$translator = $this->translator;
// Filter Categories
$categoryFilters = [];
switch ($this->multiStore->getDefaultLocale()) {
case 'sk':
$categoryFilters = [
CategoryPage::SK_CATEGORYPAGE_ID_PC => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_PC,
'name' => $translator->trans('Computers'),
],
CategoryPage::SK_CATEGORYPAGE_ID_NOTEBOOK => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_NOTEBOOK,
'name' => $translator->trans('Notebooks'),
],
CategoryPage::SK_CATEGORYPAGE_ID_MONITOR => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_MONITOR,
'name' => $translator->trans('Monitors'),
],
CategoryPage::SK_CATEGORYPAGE_ID_MOBIL => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_MOBIL,
'name' => $translator->trans('Smartphones'),
],
CategoryPage::SK_CATEGORYPAGE_ID_TABLET => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_TABLET,
'name' => 'Tablet',
],
CategoryPage::SK_CATEGORYPAGE_ID_SMARTWATCH => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_SMARTWATCH,
'name' => 'Smartwatch',
],
CategoryPage::SK_CATEGORYPAGE_ID_ELECTRIC_SCOOTER => [
'id' => CategoryPage::SK_CATEGORYPAGE_ID_ELECTRIC_SCOOTER,
'name' => $translator->trans('Electric scooters'),
],
];
break;
case 'hu':
$categoryFilters = [
CategoryPage::HU_CATEGORYPAGE_ID_PC => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_PC,
'name' => $translator->trans('Computers'),
],
CategoryPage::HU_CATEGORYPAGE_ID_NOTEBOOK => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_NOTEBOOK,
'name' => $translator->trans('Notebooks'),
],
CategoryPage::HU_CATEGORYPAGE_ID_MONITOR => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_MONITOR,
'name' => $translator->trans('Monitors'),
],
CategoryPage::HU_CATEGORYPAGE_ID_MOBIL => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_MOBIL,
'name' => $translator->trans('Smartphones'),
],
CategoryPage::HU_CATEGORYPAGE_ID_TABLET => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_TABLET,
'name' => 'Tablet',
],
CategoryPage::HU_CATEGORYPAGE_ID_SMARTWATCH => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_SMARTWATCH,
'name' => 'Smartwatch',
],
CategoryPage::HU_CATEGORYPAGE_ID_ELECTRIC_SCOOTER => [
'id' => CategoryPage::HU_CATEGORYPAGE_ID_ELECTRIC_SCOOTER,
'name' => $translator->trans('Electric scooters'),
],
];
break;
case 'cz':
$categoryFilters = [
CategoryPage::CZ_CATEGORYPAGE_ID_PC => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_PC,
'name' => $translator->trans('Computers'),
],
CategoryPage::CZ_CATEGORYPAGE_ID_NOTEBOOK => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_NOTEBOOK,
'name' => $translator->trans('Notebooks'),
],
CategoryPage::CZ_CATEGORYPAGE_ID_MONITOR => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_MONITOR,
'name' => $translator->trans('Monitors'),
],
CategoryPage::CZ_CATEGORYPAGE_ID_MOBIL => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_MOBIL,
'name' => $translator->trans('Smartphones'),
],
CategoryPage::CZ_CATEGORYPAGE_ID_TABLET => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_TABLET,
'name' => 'Tablet',
],
CategoryPage::CZ_CATEGORYPAGE_ID_SMARTWATCH => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_SMARTWATCH,
'name' => 'Smartwatch',
],
CategoryPage::CZ_CATEGORYPAGE_ID_ELECTRIC_SCOOTER => [
'id' => CategoryPage::CZ_CATEGORYPAGE_ID_ELECTRIC_SCOOTER,
'name' => $translator->trans('Electric scooters'),
],
];
break;
case 'en':
$categoryFilters = [
CategoryPage::EU_CATEGORYPAGE_ID_PC => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_PC,
'name' => $translator->trans('Computers'),
],
CategoryPage::EU_CATEGORYPAGE_ID_NOTEBOOK => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_NOTEBOOK,
'name' => $translator->trans('Notebooks'),
],
CategoryPage::EU_CATEGORYPAGE_ID_MONITOR => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_MONITOR,
'name' => $translator->trans('Monitors'),
],
CategoryPage::EU_CATEGORYPAGE_ID_MOBIL => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_MOBIL,
'name' => $translator->trans('Smartphones'),
],
CategoryPage::EU_CATEGORYPAGE_ID_TABLET => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_TABLET,
'name' => 'Tablet',
],
CategoryPage::EU_CATEGORYPAGE_ID_SMARTWATCH => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_SMARTWATCH,
'name' => 'Smartwatch',
],
CategoryPage::EU_CATEGORYPAGE_ID_ELECTRIC_SCOOTER => [
'id' => CategoryPage::EU_CATEGORYPAGE_ID_ELECTRIC_SCOOTER,
'name' => $translator->trans('Electric scooters'),
],
];
break;
}
return $categoryFilters;
}
/**
* @param array $filter
* @return array
*/
public function buildPriceFilterForWizard(array $filter): array
{
$results = $this->getListForWizard($filter, [
'filterOptions' => true,
])->getResult();
$priceMin = $priceMax = false;
foreach ($results as $result) {
$productMeta = $result->getDomainMeta($this->priceDomain);
if ($productMeta) {
$price = (float)$productMeta->getCurrentVatPrice();
if ($priceMin === false || $priceMax === false) {
$priceMin = $priceMax = $price;
}
if ($priceMin > $price) {
$priceMin = $price;
}
if ($priceMax < $price) {
$priceMax = $price;
}
}
}
return [
'priceMin' => floor($priceMin),
'priceMax' => ceil($priceMax),
];
}
/**
* @param array $filter
* @param array $options
* @return array
*/
private function getFilterListingResults(array $filter, array $options = [])
{
if (isset($filter['filterCategoryId']) && in_array($filter['filterCategoryId'], CategoryPage::SALE_CATEGORY_PAGES)) {
$filterListing = [
'filterCategoryId' => $filter['filterCategoryId'],
'filterProductType' => $filter['filterProductType'],
];
}
else if (isset($filter['filterCategoryId'])) {
$filterListing = [
'filterCategoryId' => $filter['filterCategoryId'],
];
}
else if (isset($options['search'])) {
$filterListing = $filter;
// Remove Quality Filter
if (isset($filterListing['filterAttribute'][101])) {
unset($filterListing['filterAttribute'][101]);
}
// Remove Price Filter
if (isset($filterListing['filterPriceMin'])) {
unset($filterListing['filterPriceMin']);
}
if (isset($filterListing['filterPriceMax'])) {
unset($filterListing['filterPriceMax']);
}
}
else {
$filterListing = [];
}
$query = $this->getProductListingQuery($filterListing, [
'filterOptions' => true,
]);
return $query->getResult();
}
/**
* @param int $categoryId
* @param int $limit
*/
public function getPopularItemsByCategory($categoryId, $limit = 3)
{
$categoryPage = $this->entityManager->getRepository(CategoryPage::class)->findOneById($categoryId);
$manuallyAddedProducts = $categoryPage->getPopularProducts();
$results = [];
if ($manuallyAddedProducts->count() < 3) {
$query = $this->getProductListingQuery([
'filterCategoryId' => $categoryId,
'filterDiscounted' => 1,
'filterOrderable' => 1,
'start' => 0,
'order' => 'discountedDate',
'sort' => 'DESC',
'limit' => $limit - $manuallyAddedProducts->count(),
]);
foreach ($manuallyAddedProducts as $key => $product) {
array_push($results, $product);
}
$popularProductsByDiscountedDate = new Paginator($query, $fetchJoinCollection = true);
foreach ($popularProductsByDiscountedDate as $key => $product) {
array_push($results, $product);
}
} else {
$results = $manuallyAddedProducts;
}
if (count($results) < 3) {
$query = $this->getProductListingQuery([
'filterCategoryId' => $categoryId,
'filterDiscounted' => 0,
'filterOrderable' => 1,
'start' => 0,
'order' => 'lastSale',
'sort' => 'ASC',
'limit' => $limit - count($results),
]);
$popularProductsByLastSale = new Paginator($query, $fetchJoinCollection = true);
foreach ($popularProductsByLastSale as $key => $product) {
array_push($results, $product);
}
}
$products = [];
$count = 0;
foreach ($results as $result) {
$count++;
if ($count > 3) {
break;
}
$products[$result->getId()] = $this->getStructuredDataForProduct($result, 'popular');
}
return $products;
}
/**
* @param int $categoryId
* @param int $vendorId
* @param int $limit
*/
public function getSimilarItemsByCategoryVendor($categoryId, $vendorId, $limit = 4)
{
$query = $this->getProductListingQuery([
'filterCategoryId' => $categoryId,
'filterVendor' => $vendorId,
'filterOrderable' => 1,
'start' => 0,
'limit' => $limit,
]);
$results = new Paginator($query, $fetchJoinCollection = true);
$products = [];
foreach ($results as $result) {
$products[$result->getId()] = $this->getStructuredDataForProduct($result, 'list');
}
return $products;
}
/**
* @param int $productId
* @param int $limit
* @return array
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getSimilarProducts($productId, $limit = 3)
{
$product = $this->entityManager->getRepository(Product::class)->findOneById($productId);
$domain = $this->priceDomain;
$productsWithSameTypeVendor = $this->entityManager
->createQuery("SELECT COUNT(p.id)
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p AND pm.domain = :domain
WHERE p.type = :type AND p.vendor = :vendor AND p.id != :currentProductId AND p.available > 0 AND pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != :qualityStatus")
->setParameters([
'domain' => $domain,
'type' => $product->getType(),
'vendor' => $product->getVendor(),
'currentProductId' => $product->getId(),
'qualityStatus' => Product::QualityStatus_Bazaar,
])
->setMaxResults($limit)
->getSingleScalarResult();
$where = "p.type = :type";
$parameters = [
'domain' => $domain,
'type' => $product->getType(),
'currentProductId' => $product->getId(),
'qualityStatus' => Product::QualityStatus_Bazaar,
];
if ($productsWithSameTypeVendor >= $limit) {
$where .= " AND p.vendor = :vendor";
$parameters['vendor'] = $product->getVendor();
}
$results = $this->entityManager
->createQuery("SELECT p, (CASE WHEN v.name = '" . $product->getVendor()->getName() . "' THEN 1 ELSE 0 END) AS HIDDEN vndr
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p AND pm.domain = :domain
LEFT JOIN p.vendor v
WHERE " . $where . " AND p.id != :currentProductId AND p.available > 0 AND pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != :qualityStatus
ORDER BY vndr DESC, pm.currentVatPrice ASC")
->setParameters($parameters)
->setMaxResults($limit)
->getResult();
$products = [];
foreach ($results as $result) {
$products[$result->getId()] = $this->getStructuredDataForProduct($result, 'list');
}
return $products;
}
private function productIdsFromCategoryPagesProducts(array $categoryIds)
{
$ret = $this->entityManager->createQueryBuilder()
->from('category_pages_products', 'cpps')
->select('cpps.product_id AS pId')
->where('cpps.category_page_id IN :categoryId')
->setParameter(':categoryId', $categoryIds);
return $ret->getDQL();
}
/**
* @param $filter
* @param array $options
* @return Query
*/
protected function getListForWizard($filter, $options = []): Query
{
$queryBuilder = $this->entityManager->createQueryBuilder();
if (isset($options['count'])) {
$queryBuilder
->select(
$queryBuilder->expr()->countDistinct('p.id')
);
} else {
$queryBuilder->select('p');
}
$queryBuilder
->from(Product::class, 'p')
->leftJoin('p.metas', 'm')
->leftJoin('p.vendor', 'v')
->leftJoin('p.categoryPages', 'cp')
->leftJoin('cp.products', 'cpp', 'WITH', 'cpp.id IN(:categoryIds)')
->setParameter(':categoryIds', $this->productIdsFromCategoryPagesProducts($filter['categoryIds']));
if (isset($filter['filterType']) && !is_null($filter['filterType'])) {
$productTypes = [];
$productTypesRaw = explode(',', $filter['filterType']);
foreach ($productTypesRaw as $productType) {
$productTypes[] = (int)$productType;
}
$queryBuilder
->leftJoin('p.type', 'ppt')
->andWhere(
$queryBuilder->expr()->in('ppt.id', $productTypes)
);
}
if (isset($filter['filterBadge']) && !is_null($filter['filterBadge'])) {
$badges = explode(',', $filter['filterBadge']);
$orX = $queryBuilder->expr()->orX();
foreach ($badges as $index => $badge) {
$orX->add(
$queryBuilder->expr()->like(
'p.badges',
$queryBuilder->expr()->literal('%"' . $badge . '"%')
)
);
}
$queryBuilder->andWhere($orX);
}
if (isset($filter['filterAttribute']) && !is_null($filter['filterAttribute'])) {
// Create OR
if (isset($filter['filterGroupOr']) && !is_null($filter['filterGroupOr'])) {
$orGroup = explode(',', $filter['filterGroupOr']);
$hasOrGroup = false;
$orX = $queryBuilder->expr()->orX();
foreach ($filter['filterAttribute'] as $attributeId => $attribute) {
if (in_array($attributeId, $orGroup)) {
$attributeOptions = [];
$optionsRaw = explode(',', $attribute);
foreach ($optionsRaw as $option) {
$attributeOptions[] = (int)$option;
}
$queryBuilder->leftJoin('p.productAttributes', 'pa' . $attributeId);
$orX->add(
$queryBuilder->expr()->in('pa' . $attributeId . '.option', $attributeOptions)
);
$hasOrGroup = true;
unset($filter['filterAttribute'][$attributeId]);
}
}
if ($hasOrGroup) {
$queryBuilder->andWhere($orX);
}
}
foreach ($filter['filterAttribute'] as $attributeId => $attribute) {
$attributeOptions = [];
$optionsRaw = explode(',', $attribute);
foreach ($optionsRaw as $option) {
$attributeOptions[] = (int)$option;
}
$queryBuilder
->leftJoin('p.productAttributes', 'pa' . $attributeId)
->andWhere(
$queryBuilder->expr()->in('pa' . $attributeId . '.option', $attributeOptions)
);
}
}
if (!empty($filter['filterPriceMin'])) {
$queryBuilder
->andWhere('m.currentVatPrice >= :filterPriceMin')
->setParameter(':filterPriceMin', $filter['filterPriceMin']);
}
if (!empty($filter['filterPriceMax'])) {
$queryBuilder
->andWhere('m.currentVatPrice <= :filterPriceMax')
->setParameter(':filterPriceMax', $filter['filterPriceMax']);
}
$queryBuilder
->andWhere('m.domain = :domainId')
->setParameter(':domainId', $this->priceDomainId)
->andWhere('m.price > 0')
->andWhere('m.active = 1')
->andWhere('m.listed = 1')
->andWhere('p.archived = 0')
->andWhere('p.available > 0');
if (!isset($options['count']) && !isset($options['filterOptions'])) {
if (!empty($filter['sort']) && !empty($filter['order'])) {
if ($filter['sort'] == 'price' && $filter['order'] == 'asc') {
$queryBuilder->orderBy('m.currentVatPrice', 'ASC');
} elseif ($filter['sort'] == 'price' && $filter['order'] == 'desc') {
$queryBuilder->orderBy('m.currentVatPrice', 'DESC');
} elseif ($filter['sort'] == 'created' && $filter['order'] == 'asc') {
$queryBuilder->orderBy('p.created', 'ASC');
} elseif ($filter['sort'] == 'created' && $filter['order'] == 'desc') {
$queryBuilder->orderBy('p.created', 'DESC');
} elseif ($filter['sort'] == 'name' && $filter['order'] == 'asc') {
$queryBuilder->orderBy(
$queryBuilder->expr()->concat(
'v.name',
$queryBuilder->expr()->concat(
$queryBuilder->expr()->literal(' '),
'p.name'
)
),
'ASC'
);
} elseif ($filter['sort'] == 'name' && $filter['order'] == 'desc') {
$queryBuilder->orderBy(
$queryBuilder->expr()->concat(
'v.name',
$queryBuilder->expr()->concat(
$queryBuilder->expr()->literal(' '),
'p.name'
)
),
'DESC'
);
} else {
$queryBuilder->orderBy('p.available', 'DESC');
}
}
if (isset($filter['start']) && isset($filter['limit'])) {
if ($filter['start'] < 0) {
$filter['start'] = 0;
}
if ($filter['limit'] < 1) {
$filter['limit'] = 12;
}
$queryBuilder
->setFirstResult($filter['start'])
->setMaxResults($filter['limit']);
}
}
return $queryBuilder->getQuery();
}
/**
* @param array $filter
* @return \Doctrine\ORM\Query
*/
protected function getProductVariantsQuery(array $filter): Query
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder
->select('p')
->from(Product::class, 'p')
->leftJoin('p.metas', 'm')
->leftJoin('p.vendor', 'v');
if (isset($filter['vendorId']) && !is_null($filter['vendorId'])) {
$queryBuilder
->andWhere('v.id = ' . $filter['vendorId']);
}
if (isset($filter['name']) && !is_null($filter['name'])) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->like(
'p.name',
$queryBuilder->expr()->literal('%' . $filter['name'] . '%')
)
);
}
if (isset($filter['typeId']) && !is_null($filter['typeId'])) {
$queryBuilder
->leftJoin('p.type', 'ppt')
->andWhere('ppt.id = ' . $filter['typeId']);
}
$queryBuilder
->andWhere('m.domain = :domainId')
->setParameter(':domainId', $this->priceDomainId)
->andWhere('m.currentVatPrice > 0')
->andWhere('p.archived = 0')
->andWhere('p.available > 0')
->andWhere('p.id != :productId')
->setParameter(':productId', $filter['productId'])
->andWhere('p.qualityStatus != :qualityStatus')
->setParameter(':qualityStatus', Product::QualityStatus_Bazaar)
->setMaxResults(3)
->andWhere('m.orderable = 1')
->andWhere('m.active = 1')
->orderBy('m.currentVatPrice');
return $queryBuilder->getQuery();
}
/**
* @param array $filter
* @param array $options
* @return Query
* @throws NotSupported
*/
protected function getProductListingQuery(array $filter, array $options = [])
{
$queryBuilder = $this->entityManager->createQueryBuilder();
if (isset($options['count'])) {
$queryBuilder
->select(
$queryBuilder->expr()->countDistinct('p.id')
);
} else {
$queryBuilder->select('p');
}
$queryBuilder
->from(Product::class, 'p')
->leftJoin('p.metas', 'm')
->leftJoin('p.vendor', 'v')
->leftJoin('p.type', 'ppt');
/**
* @var CategoryPage $categoryInfo
*/
if (isset($filter['filterCategoryId'])) {
$categoryInfo = $this->entityManager->getRepository(CategoryPage::class)->findOneById($filter['filterCategoryId']);
if ($categoryInfo) {
$countVendors = $categoryInfo->getVendors()->count();
$countProductTypes = $categoryInfo->getProductTypes()->count();
if ($countVendors > 0) {
$queryBuilder
->leftJoin('v.categoryPages', 'vc', 'WITH', 'vc.id = :categoryId');
}
if ($countProductTypes > 0) {
$queryBuilder
->leftJoin('p.type', 't')
->leftJoin('t.categoryPages', 'tc', 'WITH', 'tc.id = :categoryId');
}
$categoryInfoBadges = json_decode($categoryInfo->getBadges(), true);
$queryBuilder->leftJoin('p.categoryPages', 'c', 'WITH', 'c.id = :categoryId');
if ($countVendors > 0 || $countProductTypes > 0 || (is_array($categoryInfoBadges) && count($categoryInfoBadges) > 0)) {
if ($countProductTypes > 0) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('c.id', ':categoryId'),
$queryBuilder->expr()->andX(
$queryBuilder->expr()->isNotNull('tc.id')
)
)
);
}
if ($countVendors > 0) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('c.id', ':categoryId'),
$queryBuilder->expr()->andX(
$queryBuilder->expr()->isNotNull('vc.id')
)
)
);
}
if (is_array($categoryInfoBadges) && count($categoryInfoBadges) > 0) {
$orX = $queryBuilder->expr()->orX();
foreach ($categoryInfoBadges as $badge) {
$orX->add(
$queryBuilder->expr()->like(
'p.badges',
$queryBuilder->expr()->literal('%"' . $badge . '"%')
)
);
}
$queryBuilder->andWhere($orX);
}
} else {
$queryBuilder->andWhere(
$queryBuilder->expr()->isNotNull('c.id')
);
}
$queryBuilder->setParameter('categoryId', $filter['filterCategoryId']);
}
} elseif (isset($filter['filterCategories']) && $filter['filterCategories'] != null) {
$categoryInfos = $this->entityManager->getRepository(CategoryPage::class)->findBy([
'id' => explode(',', $filter['filterCategories']),
]);
$countVendors = $countProductTypes = 0;
$categoryInfoBadges = [];
foreach ($categoryInfos as $categoryPageItem) {
$countVendors += $categoryPageItem->getVendors()->count();
$countProductTypes += $categoryPageItem->getProductTypes()->count();
$categoryInfoBadges = array_merge($categoryInfoBadges, $categoryPageItem->getBadges() != "" ? json_decode($categoryPageItem->getBadges(), true) : []);
}
if ($countVendors > 0) {
$queryBuilder
->leftJoin('v.categoryPages', 'vc', 'WITH', 'vc.id IN(:categoryIds)');
}
if ($countProductTypes > 0) {
$queryBuilder
->leftJoin('p.type', 't')
->leftJoin('t.categoryPages', 'tc', 'WITH', 'tc.id IN(:categoryIds)');
}
$queryBuilder->leftJoin('p.categoryPages', 'c', 'WITH', 'c.id IN(:categoryIds)');
if ($countVendors > 0 || $countProductTypes > 0 || (is_array($categoryInfoBadges) && count($categoryInfoBadges) > 0)) {
if ($countProductTypes > 0) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->in('c.id', ':categoryIds'),
$queryBuilder->expr()->andX(
$queryBuilder->expr()->isNotNull('tc.id')
)
)
);
}
if ($countVendors > 0) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->in('c.id', ':categoryIds'),
$queryBuilder->expr()->andX(
$queryBuilder->expr()->isNotNull('vc.id')
)
)
);
}
if (is_array($categoryInfoBadges) && count($categoryInfoBadges) > 0) {
$orX = $queryBuilder->expr()->orX();
foreach ($categoryInfoBadges as $badge) {
$orX->add(
$queryBuilder->expr()->like(
'p.badges',
$queryBuilder->expr()->literal('%"' . $badge . '"%')
)
);
}
$queryBuilder->andWhere($orX);
}
} else {
$queryBuilder->andWhere(
$queryBuilder->expr()->isNotNull('c.id')
);
}
$queryBuilder->setParameter('categoryIds', explode(',', $filter['filterCategories']));
}
if (isset($filter['filterProductType']) && !is_null($filter['filterProductType']) && $filter['filterProductType'] != '') {
$productTypes = [];
$productTypesRaw = explode(',', $filter['filterProductType']);
foreach ($productTypesRaw as $productType) {
$productTypes[] = (int)$productType;
}
$queryBuilder
->andWhere(
$queryBuilder->expr()->in('p.type', $productTypes)
);
}
if (isset($filter['filterVendor']) && !is_null($filter['filterVendor']) && $filter['filterVendor'] != '') {
$vendors = [];
$vendorsRaw = explode(',', $filter['filterVendor']);
foreach ($vendorsRaw as $vendor) {
$vendors[] = (int)$vendor;
}
$queryBuilder
->andWhere(
$queryBuilder->expr()->in('v.id', $vendors)
);
}
if (isset($filter['filterType']) && !is_null($filter['filterType'])) {
$productTypes = [];
$productTypesRaw = explode(',', $filter['filterType']);
foreach ($productTypesRaw as $productType) {
$productTypes[] = (int)$productType;
}
$queryBuilder
->andWhere(
$queryBuilder->expr()->in('ppt.id', $productTypes)
);
}
if (isset($filter['filterBadge']) && !is_null($filter['filterBadge'])) {
$badges = explode(',', $filter['filterBadge']);
$orX = $queryBuilder->expr()->orX();
foreach ($badges as $index => $badge) {
$orX->add(
$queryBuilder->expr()->like(
'p.badges',
$queryBuilder->expr()->literal('%"' . $badge . '"%')
)
);
}
$queryBuilder->andWhere($orX);
}
if (isset($filter['filterAttribute']) && $filter['filterAttribute'] != '') {
// Attribute Option Groups
$attributeOptionGroups = AttributeOption::getAttributeOptionGroups();
// Create OR
if (isset($filter['filterGroupOr']) && !is_null($filter['filterGroupOr'])) {
$orGroup = explode(',', $filter['filterGroupOr']);
$hasOrGroup = false;
$orX = $queryBuilder->expr()->orX();
foreach ($filter['filterAttribute'] as $attributeId => $attribute) {
if (in_array($attributeId, $orGroup)) {
$attributeOptions = [];
$optionsRaw = explode(',', $attribute);
foreach ($optionsRaw as $option) {
$attributeOptions[] = (int)$option;
}
if (isset($attributeOptionGroups[$attributeId])) {
foreach ($attributeOptionGroups[$attributeId] as $group) {
$merge = false;
foreach ($group as $optionId) {
if (in_array((int)$optionId, $attributeOptions)) {
$merge = true;
}
}
if ($merge) {
$attributeOptions = array_merge($attributeOptions, $group);
}
}
array_unique($attributeOptions, SORT_NUMERIC);
}
$queryBuilder->leftJoin('p.productAttributes', 'pa' . $attributeId);
$orX->add(
$queryBuilder->expr()->in('pa' . $attributeId . '.option', $attributeOptions)
);
$hasOrGroup = true;
unset($filter['filterAttribute'][$attributeId]);
}
}
if ($hasOrGroup) {
$queryBuilder->andWhere($orX);
}
}
foreach ($filter['filterAttribute'] as $attributeId => $attribute) {
//TN panel is not set so we need to use id is not query... (â–º__â—„)
if ($attributeId == Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY
&& $attribute == $this->getTnDisplayAttributeOptionIds()) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->not(
$queryBuilder->expr()->exists(
$this->entityManager->createQueryBuilder()
->select('1')
->from('AtechNetCoreBundle:ProductAttribute', 'paDT')
->innerJoin('AtechNetCoreBundle:AttributeOption', 'ao', 'WITH', 'paDT.option = ao.id')
->where('paDT.product = p.id')
->andWhere('ao.attribute = :attributeId')
->getDQL()
)
)
)
->setParameter(':attributeId', Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY);
continue;
}
//SAME WITH THE NUMPAD THE NO NUMPAD ATTRIBUTE OPTION IS NOT USED (ï¿£ i ï¿£)
else if ($attributeId == Attribute::ATTRIBUTE_ID_NUMPAD
&& $attribute == AttributeOption::ATTRIBUTE_OPTION_NO_NUMPAD) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->not(
$queryBuilder->expr()->exists(
$this->entityManager->createQueryBuilder()
->select('1')
->from('AtechNetCoreBundle:ProductAttribute', 'paNum')
->innerJoin('AtechNetCoreBundle:AttributeOption', 'ao', 'WITH', 'paNum.option = ao.id')
->where('paNum.product = p.id')
->andWhere('ao.attribute = :attributeId')
->getDQL()
)
)
)
->setParameter(':attributeId', Attribute::ATTRIBUTE_ID_NUMPAD);
continue;
}
else if ($attributeId == 'newBattery') {
$queryBuilder->innerJoin('p.tags', 'tag')
->andWhere('tag.title = :newBattery')
->setParameter(':newBattery', 'New battery - Notebook');
continue;
}
$attributeOptions = [];
$optionsRaw = explode(',', $attribute);
foreach ($optionsRaw as $option) {
$attributeOptions[] = (int)$option;
}
if (isset($attributeOptionGroups[$attributeId])) {
foreach ($attributeOptionGroups[$attributeId] as $group) {
$merge = false;
foreach ($group as $optionId) {
if (in_array((int)$optionId, $attributeOptions)) {
$merge = true;
}
}
if ($merge) {
$attributeOptions = array_merge($attributeOptions, $group);
}
}
array_unique($attributeOptions, SORT_NUMERIC);
}
$queryBuilder
->leftJoin('p.productAttributes', 'pa' . $attributeId)
->andWhere(
$queryBuilder->expr()->in('pa' . $attributeId . '.option', $attributeOptions)
);
}
}
if (!empty($filter['filterPriceMin'])) {
$queryBuilder
->andWhere('m.currentVatPrice >= :filterPriceMin')
->setParameter(':filterPriceMin', $filter['filterPriceMin']);
}
if (!empty($filter['filterPriceMax'])) {
$queryBuilder
->andWhere('m.currentVatPrice <= :filterPriceMax')
->setParameter(':filterPriceMax', $filter['filterPriceMax']);
}
if (!empty($filter['filterCpuMarkMin'])) {
$queryBuilder
->andWhere('p.cpuMark != 0')
->andWhere('p.cpuMark >= :filterCpuMarkMin')
->setParameter(':filterCpuMarkMin', self::CPU_MARK_HELPER_MIN[$filter['filterCpuMarkMin']]);
}
if (!empty($filter['filterCpuMarkMax'])) {
$queryBuilder
->andWhere('p.cpuMark != 0')
->andWhere('p.cpuMark <= :filterCpuMarkMax')
->setParameter(':filterCpuMarkMax', self::CPU_MARK_HELPER_MAX[$filter['filterCpuMarkMax']]);
}
//page without discount
if (isset($categoryInfo) && in_array($categoryInfo->getId(), [659, CategoryPage::UJVARI_FURDO_BANNER_SK, CategoryPage::UJVARI_FURDO_BANNER_HU, CategoryPage::UJVARI_FURDO_BANNER_CZ, 689, 690])) {
$queryBuilder->andWhere('m.discounted = 0');
}
if (!empty($filter['filterDiscounted']) || (isset($categoryInfo) && $categoryInfo->isShowOnlyDiscounted())) {
$filterValue = isset($categoryInfo) && $categoryInfo->isShowOnlyDiscounted() ? 1 : (int)$filter['filterDiscounted'];
$queryBuilder
->andWhere('m.discounted = :filterDiscounted')
->setParameter(':filterDiscounted', $filterValue);
}
if (isset($categoryInfo) && $categoryInfo->isShowOnlyFlashSales()) {
$queryBuilder
->andWhere('m.discounted = 1 AND (m.saleStart IS NOT NULL OR m.saleEnd IS NOT NULL) AND (
(m.saleStart IS NOT NULL AND m.saleEnd IS NULL AND m.saleStart < :currentDate) OR (m.saleStart IS NULL AND m.saleEnd IS NOT NULL AND m.saleEnd > :currentDate) OR (m.saleStart IS NOT NULL AND m.saleEnd IS NOT NULL AND m.saleStart < :currentDate AND m.saleEnd > :currentDate)
)')
->setParameter(':currentDate', (new \DateTime()));
}
if (isset($categoryInfo) && $categoryInfo->isShowOnlyBazaar()) {
$queryBuilder
->andWhere('p.qualityStatus = :bazaar')
->setParameter(':bazaar', Product::QualityStatus_Bazaar);
}
else if (in_array($this->multiStore->getDomainId(), MultiStore::getWholesaleDomainIDs())) {
//note WSen minden kategoriaban ott lehet a bazar, Katival megbeszelve
}
else if ((!isset($categoryInfo) || (isset($categoryInfo) && $categoryInfo->isIncludeBazaar() === false)) && empty($filter['filterSearch'])) {
$queryBuilder
->andWhere('p.qualityStatus != :bazaar')
->setParameter(':bazaar', Product::QualityStatus_Bazaar);
}
if (!empty($filter['filterLastPieces'])) {
$queryBuilder
->andWhere('p.available = :filterLastPieces')
->setParameter(':filterLastPieces', (int)$filter['filterLastPieces']);
}
$queryBuilder
->andWhere('m.domain = :domainId')
->setParameter(':domainId', $this->priceDomainId)
->andWhere('m.price > 0')
->andWhere('p.archived = 0');
if (!isset($options['show_not_available'])) {
$queryBuilder
->andWhere('m.active = :active')
->setParameter(':active', 1)
->andWhere('m.listed = :listed')
->setParameter(':listed', 1);
$orX = $queryBuilder->expr()->orX(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->gt(
'p.available',
0
),
$queryBuilder->expr()->not(
$queryBuilder->expr()->eq(
'p.outOfStockStatus',
Product::OutOfStockStatus_VisibleShadow
)
)
)
);
$queryBuilder->andWhere($orX);
}
if (isset($filter['filterBestseller'])) {
$queryBuilder
->andWhere('m.bestSeller = :bestSeller')
->setParameter(':bestSeller', (int)$filter['filterBestseller']);
}
if (isset($filter['filterOrderable'])) {
$queryBuilder
->andWhere('m.orderable = :orderable')
->setParameter(':orderable', (int)$filter['filterOrderable']);
}
if (!empty($filter['filterSearch'])) {
$andX = $queryBuilder->expr()->andX();
$words = explode(' ', trim(preg_replace('/\s+/', ' ', $filter['filterSearch'])));
foreach ($words as $index => $word) {
$andX
->add(
$queryBuilder->expr()->like(
$queryBuilder->expr()->concat(
'v.name',
$queryBuilder->expr()->literal(' '),
'ppt.title',
$queryBuilder->expr()->literal(' '),
'p.name'
),
$queryBuilder->expr()->literal('%' . $word . '%')
)
);
}
$orX = $queryBuilder->expr()->orX(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->gt(
'p.available',
0
),
$queryBuilder->expr()->not(
$queryBuilder->expr()->eq(
'p.outOfStockStatus',
Product::OutOfStockStatus_VisibleShadow
)
)
)
);
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$andX,
$queryBuilder->expr()->like(
'p.code',
$queryBuilder->expr()->literal('%' . $filter['filterSearch'] . '%')
)
)
)
->orWhere('p.ean = ' . $queryBuilder->expr()->literal($filter['filterSearch']))
->orWhere('p.partNumber = ' . $queryBuilder->expr()->literal($filter['filterSearch']))
->andWhere('m.currentVatPrice != 0')
->andWhere($orX);
}
$isNewProductPage = key_exists('filterCategories', $filter);
if ($isNewProductPage) {
$queryBuilder
->andWhere('m.activationDate > :currentDateMinus1Month')
->setParameter(':currentDateMinus1Month', (new \DateTime('-1 month')));
}
if (!isset($options['count']) && !isset($options['filterOptions'])) {
if (!empty($filter['sort']) && !empty($filter['order'])) {
$orderByOption = false;
switch ($filter['sort']) {
case 'price':
$orderByOption = 'm.currentVatPrice';
break;
case 'created':
$orderByOption = 'm.activationDate';
break;
case 'name':
$orderByOption = $queryBuilder->expr()->concat(
'v.name',
$queryBuilder->expr()->concat(
$queryBuilder->expr()->literal(' '),
'p.name'
)
);
break;
case 'popular':
$orderByOption = 'p.soldDuringTimeFrame';
break;
case 'discountedDate':
$orderByOption = 'm.discountedDate';
break;
case 'lastSale':
$orderByOption = 'p.lastSale';
break;
}
$order = $filter['order'] == 'asc' ? 'asc' : 'desc';
$queryBuilder->addOrderBy(
$orderByOption ?: ($isNewProductPage ? 'm.activationDate' : 'p.available'),
$order
);
}
if (isset($filter['start']) && isset($filter['limit'])) {
if ($filter['start'] < 0) {
$filter['start'] = 0;
}
if ($filter['limit'] < 1) {
$filter['limit'] = 12;
}
$queryBuilder
->setFirstResult($filter['start'])
->setMaxResults($filter['limit']);
}
}
if (isset($filter['searchInDockTonerDesc']) && $filter['searchInDockTonerDesc']) {
$orWhereString = "p.type IN (16,92,106,128) AND m.detail LIKE :filterSearchLike";
$queryBuilder
->setParameter('filterSearchLike', '%' . $filter['filterSearch'] . '%');
if (isset($filter['filterPriceMax']) && $filter['filterPriceMax'] > 0) {
$orWhereString .= ' AND m.currentVatPrice >= :filterPriceMin AND m.currentVatPrice <= :filterPriceMax';
$queryBuilder
->setParameter('filterPriceMin', $filter['filterPriceMin'])
->setParameter('filterPriceMax', $filter['filterPriceMax']);
}
$queryBuilder
->orWhere($orWhereString);
}
return $queryBuilder->getQuery();
}
/**
* @param Product $product
* @return array
*/
protected function getProductIcons(Product $product)
{
$productAttributeOptions = $product->getSpecificationProductAttributeOptions();
$badges = $product->getBadges();
$productTypeId = $product->getType()->getId();
$icons = [
[
'attributeId' => 141, // PC Processor family
'attributeOptionId' => 1339, // i3
'file' => 'processor-i3.svg',
'sortOrder' => 1,
'title' => 'Intel Core i3',
], [
'attributeId' => 141, // PC Processor family
'attributeOptionId' => 1340, // i5
'file' => 'processor-i5.svg',
'sortOrder' => 2,
'title' => 'Intel Core i5',
], [
'attributeId' => 141, // PC Processor family
'attributeOptionId' => 1341, // i7
'file' => 'processor-i7.svg',
'sortOrder' => 3,
'title' => 'Intel Core i7',
], [
'attributeId' => 142, // PC Processor family
'attributeOptionId' => 1357, // i3
'file' => 'processor-i3.svg',
'sortOrder' => 4,
'title' => 'Intel Core i3',
], [
'attributeId' => 142, // PC Processor family
'attributeOptionId' => 1358, // i5
'file' => 'processor-i5.svg',
'sortOrder' => 5,
'title' => 'Intel Core i5',
], [
'attributeId' => 142, // PC Processor family
'attributeOptionId' => 1359, // i7
'file' => 'processor-i7.svg',
'sortOrder' => 6,
'title' => 'Intel Core i7',
], [
'attributeId' => 15, // Bluetooth
'attributeOptionId' => 567, // Yes
'file' => 'bluetooth.svg',
'sortOrder' => 7,
'title' => 'Bluetooth',
], [
'attributeId' => 118, // Technology
'attributeOptionId' => 926, // IPS
'file' => 'ips.svg',
'sortOrder' => 8,
'title' => 'IPS display',
], [
'attributeId' => 5, // SSD
'attributeOptionId' => false, // More Options
'file' => 'ssd.svg',
'sortOrder' => 9,
'title' => 'SSD disc',
], [
'attributeId' => 16, // Wi-Fi
'attributeOptionId' => 217, // Yes
'file' => 'wifi.svg',
'sortOrder' => 10,
'title' => 'Wifi',
], [
'attributeId' => 139, // Touchscreen
'attributeOptionId' => 1295, // Yes
'file' => 'touchdisplay.svg',
'sortOrder' => 11,
'title' => 'Touch display',
], [
'attributeId' => 17, // NumPad
'attributeOptionId' => 555, // Yes
'file' => 'numeric.svg',
'sortOrder' => 12,
'title' => 'Numeric keyboard',
], [
'attributeId' => 50, // Night light
'attributeOptionId' => 556, // Yes
'file' => 'keyboardlight.svg',
'sortOrder' => 13,
'title' => 'Night light',
], [
'attributeId' => 46, // Connectors external PC
'attributeOptionId' => 504, // HDMI
'file' => 'hdmi.svg',
'sortOrder' => 14,
'title' => 'HDMI connector',
], [
'attributeId' => 45, // Connectors external NB
'attributeOptionId' => 544, // HDMI
'file' => 'hdmi.svg',
'sortOrder' => 15,
'title' => 'HDMI connector',
], [
'attributeId' => 68, // Graphical inputs
'attributeOptionId' => 733, // HDMI
'file' => 'hdmi.svg',
'sortOrder' => 16,
'title' => 'HDMI connector',
], [
'attributeId' => 55, // Fingerprint
'attributeOptionId' => 564, // Yes
'file' => 'fingerprint.svg',
'sortOrder' => 17,
'title' => 'Fingerprint sensor',
], [
'attributeId' => 63, // Maximum resolution
'attributeOptionId' => 632, // Full HD (1920 x 1080)
'file' => 'fullhd.svg',
'sortOrder' => 18,
'title' => 'Full HD display',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 201, // 19
'file' => 'screen-size-19.svg',
'sortOrder' => 19,
'title' => '19"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 1283, // 20
'file' => 'screen-size-20.svg',
'sortOrder' => 20,
'title' => '20"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 1019, // 21.5
'file' => 'screen-size-21-3.svg',
'sortOrder' => 21,
'title' => '21.3"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 402, // 21.5
'file' => 'screen-size-21-5.svg',
'sortOrder' => 21,
'title' => '21.5"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 202, // 22
'file' => 'screen-size-22.svg',
'sortOrder' => 22,
'title' => '22"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 203, // 23
'file' => 'screen-size-23.svg',
'sortOrder' => 23,
'title' => '23"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 204, // 24
'file' => 'screen-size-24.svg',
'sortOrder' => 24,
'title' => '24"',
], [
'attributeId' => 12, // Screen size
'attributeOptionId' => 205, // 27
'file' => 'screen-size-27.svg',
'sortOrder' => 25,
'title' => '27"',
], [
'attributeId' => 10, // ODD PC
'attributeOptionId' => 179, // DVD-RW
'file' => 'optical-drive-dvd-rw.svg',
'sortOrder' => 25,
'title' => 'DVD-RW',
], [
'attributeId' => 11, // ODD NB
'attributeOptionId' => 189, // DVD-RW
'file' => 'optical-drive-dvd-rw.svg',
'sortOrder' => 25,
'title' => 'DVD-RW',
], [
'attributeId' => 46, // Connector PC
'attributeOptionId' => 503, // Displayport
'file' => 'displayport.svg',
'sortOrder' => 25,
'title' => 'display port',
], [
'attributeId' => 45, // Connector NB
'attributeOptionId' => 547, // Displayport
'file' => 'displayport.svg',
'sortOrder' => 25,
'title' => 'display port',
], [
'attributeId' => 68, // Graphical input
'attributeOptionId' => 628, // Displayport
'file' => 'displayport.svg',
'sortOrder' => 25,
'title' => 'display port',
], [
'attributeId' => 71, // Speakers
'attributeOptionId' => 596, // Built in
'file' => 'speakers.svg',
'sortOrder' => 25,
'title' => 'speakers',
], [
'attributeId' => 19, // Webcam
'attributeOptionId' => 571, // Webcam
'file' => 'webcam.svg',
'sortOrder' => 25,
'title' => 'web camera',
], [
'attributeId' => 19, // Webcam
'attributeOptionId' => 574, // Webcam HD
'file' => 'webcam.svg',
'sortOrder' => 25,
'title' => 'web camera',
], [
'attributeId' => 19, // Webcam
'attributeOptionId' => 763, // standard
'file' => 'webcam.svg',
'sortOrder' => 25,
'title' => 'web camera',
], [
'attributeId' => 19, // Webcam
'attributeOptionId' => 1481, // Full hd
'file' => 'webcam.svg',
'sortOrder' => 25,
'title' => 'web camera',
], [
'attributeId' => 34, // Monitor - LED screen
'attributeOptionId' => 452,
'file' => 'led-screen.svg',
'sortOrder' => 30,
'title' => 'LED screen',
], [
'badge' => 'senior', // Senior
'attributeId' => false,
'attributeOptionId' => false,
'file' => 'senior.svg',
'sortOrder' => 26,
], [
'badge' => 'gamer', // Gamer
'attributeId' => false,
'attributeOptionId' => false,
'file' => 'gaming.svg',
'sortOrder' => 27,
], [
'badge' => 'internet', // Internet
'attributeId' => false,
'attributeOptionId' => false,
'file' => 'internet.svg',
'sortOrder' => 28,
], [
'badge' => 'business', // Work
'attributeId' => false,
'attributeOptionId' => false,
'file' => 'company.svg',
'sortOrder' => 29,
],
];
$productIcons = [];
foreach ($productAttributeOptions as $productAttributeOption) {
$attributeOption = $productAttributeOption->getOption();
$attribute = $attributeOption->getAttribute();
foreach ($icons as $icon) {
if ((int)$icon['attributeId'] == (int)$attribute->getId()) {
if ((bool)$icon['attributeOptionId'] === false) {
$productIcons[$icon['file']] = $icon;
break;
} elseif ((int)$icon['attributeOptionId'] == (int)$attributeOption->getId()) {
$productIcons[$icon['file']] = $icon;
break;
}
}
}
}
foreach ($badges as $badge) {
foreach ($icons as $icon) {
if (isset($icon['badge']) && $icon['badge'] == $badge) {
$productIcons[$icon['file']] = $icon;
break;
}
}
}
foreach ($icons as $icon) {
if (isset($icon['productTypeId']) && $icon['productTypeId'] == $productTypeId) {
$productIcons[$icon['file']] = $icon;
}
}
$sortOrder = [];
foreach ($productIcons as $key => $value) {
$sortOrder[$key] = $value['sortOrder'];
}
array_multisort($sortOrder, SORT_ASC, $productIcons);
return array_slice($productIcons, 0, 5);
}
/**
* @param string|null $detail
* @return string
*/
public static function createFormatedDetail(?string $detail): string
{
$result = '';
$lines = preg_split('/\\n\\r*/', $detail);
$is_list = false;
foreach ($lines as $line) {
$line = trim($line);
$line = str_replace('[b]', '<strong>', $line);
$line = str_replace('[/b]', '</strong>', $line);
$line = str_replace('[bl]', '', $line);
$line = str_replace('[/bl]', '', $line);
$line = str_replace('[r]', '', $line);
$line = str_replace('[/r]', '', $line);
if ($line == '[l]' && !$is_list) {
$result .= '<ul>';
$is_list = true;
} elseif ($line == '[/l]' && $is_list) {
$result .= '</ul>';
$is_list = false;
} elseif ($is_list) {
$result .= '<li>' . $line . '</li>';
} elseif ($line != '') {
$result .= '<span>' . $line . '</span>';
}
}
return $result;
}
/**
* @param Product $product
* @param Domain $domain
* @param int $limit
* @return array
* @throws \Doctrine\DBAL\DBALException
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getRecommendedProducts(Product $product, Domain $domain, $limit = 4)
{
$upsellProducts = [];
// Antivirus Software
if (in_array($product->getType()->getId(), [52, 60, 107, 116])) {
// Except Chromebook & Apple Products
if (!in_array('Chromebook', $product->getBadges()) && $product->getVendor()->getId() !== 70) {
$products = $this->entityManager
->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.productAttributes pa
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p.id AND pm.domain = :domain
WHERE pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != :qualityStatus AND p.type = 82 AND p.vendor IN ( 141, 21 ) ORDER BY p.vendor DESC")
->setParameters([
'domain' => $domain,
'qualityStatus' => Product::QualityStatus_Bazaar,
])
->getResult();
foreach ($products as $p) {
if (!isset($upsellProducts[$p->getId()]) && count($upsellProducts) < 3) {
$upsellProducts[$p->getId()] = $this->getStructuredDataForProduct($p, 'list');
}
}
}
}
// Other Accessory
$recommendedProductTypes = self::getRecommendedProductsStructureByProductType($product->getType()->getId());
if (count($recommendedProductTypes) > 0) {
$recommendedProducts = [];
foreach ($recommendedProductTypes as $rpt) {
$where = "";
$where .= count($rpt['productTypeIDs']) > 0 ? "p.type IN (" . implode(',', $rpt['productTypeIDs']) . ")" : '';
if (count($rpt['productAttributeOptionIDs']) > 0) {
if ($where != "") {
$where .= " AND ";
}
$where .= count($rpt['productTypeIDs']) > 0 ? "pa.option IN (" . implode(',', $rpt['productAttributeOptionIDs']) . ")" : '';
}
if (count($rpt['productIDs']) > 0) {
if ($where != "") {
$where .= " AND ";
}
$where .= "p.id IN (" . implode(',', $rpt['productIDs']) . ")";
}
if ($rpt['priceRange']['min'] || $rpt['priceRange']['max']) {
if ($where != "") {
$where .= " AND ";
}
if ($rpt['priceRange']['min']) {
$where .= "pm.currentVatPrice >= " . $rpt['priceRange']['min'];
}
if ($rpt['priceRange']['max']) {
if ($rpt['priceRange']['min']) {
$where .= " AND ";
}
$where .= "pm.currentVatPrice <= " . $rpt['priceRange']['max'];
}
}
if ($rpt['matchingVendor']) {
if ($where != "") {
$where .= " AND ";
}
$where .= "p.vendor = " . $product->getVendor()->getId();
}
$products = $this
->entityManager
->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.productAttributes pa
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p.id AND pm.domain = :domain
WHERE pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != :qualityStatus AND " . $where)
->setParameters([
'domain' => $domain,
'qualityStatus' => Product::QualityStatus_Bazaar,
])
->setMaxResults($rpt['limit'])
->getResult();
foreach ($products as $p) {
if (!isset($recommendedProducts[$p->getId()]) && count($recommendedProducts) < $limit) {
$recommendedProducts[$p->getId()] = $p;
}
}
}
foreach ($recommendedProducts as $p) {
$upsellProducts[$p->getId()] = $this->getStructuredDataForProduct($p, 'list');
}
$upsellProductCount = count($upsellProducts);
if ($upsellProductCount < $limit && $product->getType()->getId() != 41) {
$missingProductsCount = $limit - $upsellProductCount;
$additionalUpsellProducts = $this->getSimilarProducts($product->getId(), $missingProductsCount);
foreach ($additionalUpsellProducts as $ap) {
$upsellProducts[] = $ap;
}
}
}
return $upsellProducts;
}
/**
* @param int $productTypeId
* @param CacheItemPoolInterface $cache
* @param Domain $domain
* @param Request $request
* @param SeoUrlHelper $seoUrlHelper
* @param EntityManagerInterface $entityManager
* @return array
*/
public function getRecommendedProductCategories(int $productTypeId, CacheItemPoolInterface $cache, Domain $domain, Request $request, SeoUrlHelper $seoUrlHelper, EntityManagerInterface $entityManager)
{
$recommendedProductCategoriesCacheKey = 'product.v1.recommendedProductCategories.' . $productTypeId . '.' . $domain->getId() . '.' . $request->getLocale();
$recommendedProductCategoriesCacheItem = $cache->getItem($recommendedProductCategoriesCacheKey);
if (!$recommendedProductCategoriesCacheItem->isHit()) {
$recommendedCategories = [];
$language = $domain->getLanguage(); // TODO: Localise Title of Categories
foreach (self::getRecommendedProductTypesStructure($domain->getId(), $productTypeId) as $categoryId) {
$category = $entityManager->getRepository(CategoryPage::class)->findOneById($categoryId);
/**
* @var CategoryPage $category
*/
if ($category) {
// Parent
if ($category->getParentCategory()) {
$parentId = $category->getParentCategory()->getId();
} else {
$parentId = 0;
}
$recommendedCategories[] = [
'id' => $category->getId(),
'title' => $category->getMetaByLanguage($language)->getTitle(),
'href' => $seoUrlHelper->link('category', [
'path' => ($parentId > 0 ? $parentId . '_' : '') . $category->getId(),
'isBazaar' => $category->isShowOnlyBazaar()
]),
];
}
}
$recommendedProductCategoriesCacheItem->set($recommendedCategories);
$recommendedProductCategoriesCacheItem->expiresAfter(604800);
$cache->save($recommendedProductCategoriesCacheItem);
return $recommendedCategories;
} else {
return $recommendedProductCategoriesCacheItem->get();
}
}
/**
* @param $requestUrl
* @param $structuredDataResults
* @param $imagePlaceholder
* @return array
*/
public function convertStructuredDataToListViewData($requestUrl, $structuredDataResults, $imagePlaceholder): array
{
$convertedData = [];
foreach ($structuredDataResults as $result) {
$image = $imagePlaceholder;
if (is_object($result['images'])) {
$image = $this->getImage($result['images'], 'product/' . $result['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$result['title'] = in_array($requestUrl->getDomainId(), [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) ?
str_replace([' (Quality: Bazar)', ' (Quality: Bazár)', ' (Quality: Bazár, '], ['', '', ' ('], $result['title']) :
$result['title'];
$convertedData[] = [
'id' => $result['id'],
'title' => ProductHelper::shortenProductName($result['vendor'], $result['title']),
'vendor' => $result['vendor'],
'vendorId' => $result['vendorId'],
'typeId' => $result['productTypeId'],
'labels' => $result['badges'],
'price' => $result['vatPrice'],
'special' => ($result['isDiscounted'] ? $result['discountVatPrice'] : false),
'rawPrice' => $result['rawPrice'],
'rawDiscountPrice' => $result['rawDiscountPrice'],
'image' => $image,
'attributes' => $result['attributes'],
'attributesListTxt' => $result['attributesListTxt'],
'available' => $result['availableQty'],
'href' => $requestUrl->link('product', [
'product_id' => $result['id'],
'isBazaar' => $result['isBazaar'] ?? 0
]),
'active' => $result['active'],
'timedSalesActive' => $result['timedSalesActive'],
'reviewCount' => $result['reviewCount'],
'reviewStars' => $result['reviewStars'],
'reviews' => $result['reviews'],
'freeShipping' => $result['freeShipping'],
'labelOS' => $this->getOSLabel($result),
'qualityStatusId' => $result['qualityStatusId'],
'qualityStatusTitle' => Product::getQualityStatusChoices()[$result['qualityStatusId']],
'isBestseller' => $result['isBestseller'] ?? false
];
}
return $convertedData;
}
/**
* @param string $productGroupTitle
* @param Domain $domain
* @return array{
* productGroupProducts: array<int,Product>,
* productGroupCodesAdded: array<int,string>,
* productsToDisplay: int,
* isRandom: bool|null,
* customData: array<int, array{title: string, description?: string}>}
* }
*/
public function getProductGroupProducts(string $productGroupTitle, Domain $domain): array
{
/** @var ProductGroup|null $productGroup */
$productGroup = $this->entityManager->getRepository(ProductGroup::class)->findOneBy([
'title' => $productGroupTitle,
'domain' => $domain
]);
$productGroupProducts = [];
$productGroupCodesAdded = [];
$customData = [];
if ( !is_null($productGroup) ) {
/** @var ProductGroupMember $member */
foreach ($productGroup->getMembers() as $member) {
if (count($productGroupCodesAdded) >= $productGroup->getProductsToDisplay()) {
continue;
}
$product = $member->getProduct();
$productMeta = $product->getDomainMeta($domain);
if (!is_null($member->getTitle())) {
$customData[$product->getId()]['title'] = $member->getTitle();
}
if (!is_null($member->getDescription())) {
$customData[$product->getId()]['description'] = $member->getDescription();
}
if ( str_contains($productGroupTitle, '.bazaar') ) {
if ( $product->getAvailable() > 0
&& $productMeta->isActive()
&& $productMeta->isOrderable()
&& $productMeta->isListed()
&& $product->getQualityStatus() == Product::QualityStatus_Bazaar
) {
$productGroupProducts[] = $product;
$productGroupCodesAdded[] = $product->getCode();
}
} elseif ($productGroupTitle == 'homepage.main' && $domain->getType() == 'retail') {
if ($product->getAvailable() > 0
&& $productMeta->isActive()
&& $productMeta->isOrderable()
&& $productMeta->isListed()
&& $product->getQualityStatus() != Product::QualityStatus_Bazaar)
{
$productGroupProducts[] = $product;
$productGroupCodesAdded[] = $product->getCode();
}
} else {
if ($product->getAvailable() > 0
&& $productMeta->isActive()
&& $productMeta->isOrderable()
&& $productMeta->isListed())
{
$productGroupProducts[] = $product;
$productGroupCodesAdded[] = $product->getCode();
}
}
}
}
return [
'productGroupProducts' => $productGroupProducts,
'productGroupCodesAdded' => $productGroupCodesAdded,
'productsToDisplay' => !is_null($productGroup) ? $productGroup->getProductsToDisplay() : 0,
'isRandom' => $productGroup?->getShowRandom(),
'customData' => $customData,
];
}
/**
* @param Domain $domain
* @param integer $categoryGroupType
* @param SeoUrlHelper $seoUrlHelper
* @return array<string,string|bool|int>
*/
public function getCategoryGroup(Domain $domain, int $categoryGroupType, SeoUrlHelper $seoUrlHelper): array
{
$categoryGroup = $this->entityManager->getRepository(CategoryGroup::class)->findOneBy([
'type' => $categoryGroupType,
'domain' => $domain,
'active' => true,
]);
$result = [];
if (!is_null($categoryGroup)) {
if (in_array($categoryGroup->getType(), [CategoryGroup::CG_TYPE_FEATURED_CATEGORIES_UPPER, CategoryGroup::CG_TYPE_FEATURED_CATEGORIES_LOWER])) {
$categoryMember = $categoryGroup->getCategories()->count() > 0 ? $categoryGroup->getCategories()->first() : [];
$result['title'] = $categoryMember->getTitle();
$result['description'] = $categoryMember->getDescription();
$result['isWizard'] = $categoryMember->isWizard();
$result['href'] = $categoryMember->isWizard() ? '/wizard' : $seoUrlHelper->link('category', [
'path' => $categoryMember->getCategory()->getId(),
'isBazaar' => $categoryMember->getCategory()->isShowOnlyBazaar()
]);
$image = $categoryMember->getImage();
$imageFilenames = [
'filename' => $image ? $image->getFilename() : '',
'originalName' => $image ? $image->getOriginalName() : '',
];
$result['image'] = $image ? $this->getImage($imageFilenames, CategoryGroupMemberImage::CLASS_IMAGE_DIRECTORY)->resize(Image::HEADER_FEATURED_CATEGORY_WIDTH, Image::HEADER_FEATURED_CATEGORY_HEIGHT) : '';
}
}
return $result;
}
/**
* @param $vendor
* @param $name
* @return string
*/
public static function shortenProductName($vendor, $name): string
{
$title = $name;
$maxFullTitleLength = 75;
$longTitle = $vendor . ' ' . $name;
if (mb_strlen($longTitle) > $maxFullTitleLength) {
$vendorLength = mb_strlen($vendor . ' ');
$length = $maxFullTitleLength - $vendorLength;
$title = mb_substr($title, 0, $length) . '...';
}
return $title;
}
/**
* @param Product $product
* @param Domain $domain
* @return bool
*/
public static function isFlashSaleValidForProduct(Product $product, Domain $domain): bool
{
$pm = $product->getDomainMeta($domain);
$currentDateTime = new \DateTime();
if ($product->getAvailable() > 0 && $pm->isActive() && $pm->isOrderable() && $pm->isListed() && $pm->isDiscounted()
&& (
(!is_null($pm->getSaleStart()) && !is_null($pm->getSaleEnd()) && $pm->getSaleStart() < $currentDateTime && $currentDateTime < $pm->getSaleEnd())
|| (!is_null($pm->getSaleStart()) && is_null($pm->getSaleEnd()) && $pm->getSaleStart() < $currentDateTime)
|| (is_null($pm->getSaleStart()) && !is_null($pm->getSaleEnd()) && $currentDateTime < $pm->getSaleEnd())
)
) {
return true;
}
return false;
}
/**
* @param $product
* @param bool $skipType
* @return string
*/
public static function getHeadingTitle($product, bool $skipType = false)
{
$productType = $skipType ? '' : ' ' . $product['productType'];
return $product['title'] . $productType . ' - ' . $product['code'];
}
/**
* @param $product
* @param $translator
*/
public static function getLongTitleWithConfig($product, $translator)
{
if ($product['qualityStatusId'] != Product::QualityStatus_New) {
$isTinyPc = self::hasBadgeByStructuredData('Tiny PC', $product['badgesRaw']);
switch ($product['productTypeId']) {
case ProductType::PRODUCT_TYPE_ID_SMARTPHONE:
$h1Title = $product['title'] . ' - ' . $product['code'];
$h1Title .= (!in_array($product['qualityStatusId'], [Product::QualityStatus_New, Product::QualityStatus_Platinum]) ? ' (' . $translator->trans('refurbished') . ')' : '');
break;
case ProductType::PRODUCT_TYPE_ID_MONITOR:
$h1Title = $product['title'] . ' - ' . $product['code'];
break;
case ProductType::PRODUCT_TYPE_ID_NOTEBOOK:
$h1Title = $product['title'] . ' - ' . $product['code'];
break;
case ProductType::PRODUCT_TYPE_ID_PC:
case ProductType::PRODUCT_TYPE_ID_PC_SET:
$h1Title = $product['title'] . ' - ' . $product['code'];
break;
case ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE:
$h1Title = $product['title'] . ' - ' . $product['code'];
break;
default:
$h1Title = $product['title'] . ' - ' . $product['code'];
}
} else {
$h1Title = $product['title'] . ' - ' . $product['code'];
}
return $h1Title;
}
/**
* @param array $attributes
* @return string
*/
public static function getConfigurationInTitle($attributes)
{
$configurationInTitle = '';
$configsToAdd = [
32, 33, 35, 36, // Processors
25, // VGA
3, // RAM PC
4, // RAM NB
5, // SSD
6, 7, 8, 9, // HDD
12, // Screen size
63, // Display resolution
118, // IPS
];
foreach ($configsToAdd as $configToAdd) {
if (isset($attributes[$configToAdd])) {
if ($configurationInTitle != '') {
$configurationInTitle .= ', ';
}
$shortTitle = reset($attributes[$configToAdd]['options'])['shortTitle'];
$type = '';
if (in_array(substr($shortTitle, 0, 2), ['i3', 'i5', 'i7'])) {
$type = 'Intel Core ';
}
$postFix = '';
if ($configToAdd == 5) { // SSD
$postFix = ' SSD';
}
if (in_array($configToAdd, [6, 7, 8, 9])) { // HDD
$postFix = ' HDD';
}
if (in_array($configToAdd, [3, 4])) { // RAM
$postFix = ' RAM';
}
$configurationInTitle .= $type . $shortTitle . $postFix;
}
}
return $configurationInTitle;
}
/**
* @param $badgeTocheck
* @param $badges
* @return bool
*/
private static function hasBadgeByStructuredData($badgeTocheck, $badges)
{
$hasBadge = false;
foreach ($badges as $badge) {
if (!$hasBadge && $badge == $badgeTocheck) {
$hasBadge = true;
}
}
return $hasBadge;
}
/**
* @param $productTypeId
* @return array|array[]
*/
private static function getRecommendedProductsStructureByProductType($productTypeId)
{
switch ($productTypeId) {
case 60: // PC
case 107: // PC SET
case 116: // All in one
$recommendedProductTypes = [
[
// basic wired mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// basic wireless mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// middle wired mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// middle wireless mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// gamer wired mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// gamer wireless mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// wireless keyboard
'productTypeIDs' => [
38,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wired keyboard
'productTypeIDs' => [
38,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// gamer keyboard
'productTypeIDs' => [
38,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// wireless headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wired headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wireless headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wired headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// headset combo
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// webcam
'productTypeIDs' => [
104,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Speaker
'productTypeIDs' => [
84,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// External HDD adapter
'productTypeIDs' => [
124,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Furbify mouse pad
'productTypeIDs' => [],
'productAttributeOptionIDs' => [],
'productIDs' => [
14731,
],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 0,
],
[
// USB wifi
'productTypeIDs' => [
102,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Compressed AIR
'productTypeIDs' => [],
'productAttributeOptionIDs' => [],
'productIDs' => [
15198,
],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
];
break;
case 52: // Notebook
$recommendedProductTypes = [
[
// basic wired mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// basic wireless mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// middle wired mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// middle wireless mouse
'productTypeIDs' => [
46,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wireless keyboard
'productTypeIDs' => [
38,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wireless headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wired headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wireless headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// wired headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2020,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// headset combo
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [
2021,
],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// webcam
'productTypeIDs' => [
104,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// HDMI cable
'productTypeIDs' => [
7,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Notebook cooler
'productTypeIDs' => [
126,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Notebook bag
'productTypeIDs' => [
54,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// External HDD adapter
'productTypeIDs' => [
124,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Furbify mouse pad
'productTypeIDs' => [],
'productAttributeOptionIDs' => [],
'productIDs' => [
14731,
],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
[
// Compressed AIR
'productTypeIDs' => [],
'productAttributeOptionIDs' => [],
'productIDs' => [
15198,
],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 2,
],
];
break;
case 44: // Monitor
$recommendedProductTypes = [
[
// monitor cleaning set
'productTypeIDs' => [
20,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// Furbify mouse pad
'productTypeIDs' => [],
'productAttributeOptionIDs' => [],
'productIDs' => [
14731,
],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// hdmi cable
'productTypeIDs' => [
7,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 4,
],
[
// Speakers
'productTypeIDs' => [
84,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 8,
],
[
// headphones
'productTypeIDs' => [
35,
],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 8,
],
];
break;
case 41: // Mobile
$recommendedProductTypes = [
[
// Accessories
'productTypeIDs' => [42],
'productAttributeOptionIDs' => [],
'productIDs' => [],
'priceRange' => [
'min' => false,
'max' => false,
],
'matchingVendor' => false,
'limit' => 8,
],
];
break;
default:
$recommendedProductTypes = [];
}
return $recommendedProductTypes;
}
public static function getRecommendedProductTypesStructure($domainId, $productTypeId)
{
$recommendedProductTypes = [];
if (in_array($domainId, [1, 2])) { // RT SK, WS SK
switch ($productTypeId) {
case 60: // PC
case 107: // PC SET
case 116: // All in one
$recommendedProductTypes = [
30, // Mouse
31, // Keyboard
198, // Headphones
194, // Webcam
201, // Speaker
202, // External HDD adapter
10, // USB wifi
203, // Cleaner
];
break;
case 52: // Notebook
$recommendedProductTypes = [
30, // Mouse
31, // Keyboard
198, // Headphones
194, // Webcam
9, // Docking station
199, // HDMI cable
200, // Notebook cooler
98, // Notebook bag
];
break;
case 44: // Monitor
$recommendedProductTypes = [
203, // Cleaner
199, // HDMI cable
201, // Speaker
198, // Headphones
];
break;
default:
$recommendedProductTypes = [];
}
} elseif (in_array($domainId, [3, 4])) { // RT HU, WS HU
switch ($productTypeId) {
case 60: // PC
case 107: // PC SET
case 116: // All in one
$recommendedProductTypes = [
68, // Mouse
69, // Keyboard
204, // Headphones
195, // Webcam
205, // Speaker
206, // External HDD adapter
47, // USB wifi
207, // Cleaner
];
break;
case 52: // Notebook
$recommendedProductTypes = [
68, // Mouse
69, // Keyboard
204, // Headphones
195, // Webcam
66, // Docking station
208, // HDMI cable
209, // Notebook cooler
99, // Notebook bag
];
break;
case 44: // Monitor
$recommendedProductTypes = [
207, // Cleaner
208, // HDMI cable
205, // Speaker
204, // Headphones
];
break;
default:
$recommendedProductTypes = [];
}
} elseif (in_array($domainId, [5, 9])) { // RT CZ, WS CZ
switch ($productTypeId) {
case 60: // PC
case 107: // PC SET
case 116: // All in one
$recommendedProductTypes = [
142, // Mouse
143, // Keyboard
210, // Headphones
196, // Webcam
211, // Speaker
212, // External HDD adapter
121, // USB wifi
213, // Cleaner
];
break;
case 52: // Notebook
$recommendedProductTypes = [
142, // Mouse
143, // Keyboard
210, // Headphones
196, // Webcam
120, // Docking station
214, // HDMI cable
215, // Notebook cooler
165, // Notebook bag
];
break;
case 44: // Monitor
$recommendedProductTypes = [
213, // Cleaner
214, // HDMI cable
211, // Speaker
210, // Headphones
];
break;
default:
$recommendedProductTypes = [];
}
}
return $recommendedProductTypes;
}
/**
* @param int $categoryId
*/
public function countInCategory(array $filter)
{
$query = $this->getProductListingQuery($filter);
$result = $query->getScalarResult();
if (!empty($result)) {
return count($result);
} else {
return 0;
}
}
/**
* @param int $domainId
* @return array
*/
public static function getFreeShipLimitsForDomain(int $domainId): array
{
return self::getFreeShipLimits()[$domainId] ?? [
'freeShipLimit' => 0,
];
}
/**
* @return int[][]
*/
public static function getFreeShipLimits(): array
{
return [
Domain::DOMAIN_ID_RT_SK => [
'freeShipLimit' => 50,
],
Domain::DOMAIN_ID_WS_SK => [
'freeShipLimit' => 50,
],
Domain::DOMAIN_ID_RT_HU => [
'freeShipLimit' => 18000,
],
Domain::DOMAIN_ID_WS_HU => [
'freeShipLimit' => 200000,
],
Domain::DOMAIN_ID_WS_CZ => [
'freeShipLimit' => 0,
],
Domain::DOMAIN_ID_WS_EU => [
'freeShipLimit' => 0,
],
Domain::DOMAIN_ID_RT_CZ => [
'freeShipLimit' => 1400,
],
Domain::DOMAIN_ID_RT_EU => [
// RT EU
'freeShipLimit' => 0,
],
];
}
/**
* @param int $domainId
* @param string $locale
* @param int $productId
* @return string
*/
public static function getProductCacheKey(int $domainId, string $locale, int $productId): string
{
return 'product.v29.' . $domainId . '.' . $locale . '.' . $productId;
}
/**
* @param int $domainId
* @param string $locale
* @param int $productId
* @return string
*/
public static function getSimiliarProductsCacheKey(int $domainId, string $locale, int $productId): string
{
return 'product.v3.similiar.' . $productId . '.' . $domainId . '.' . $locale;
}
/**
* @param int $domainId
* @param string $locale
* @param int $productId
* @return string
*/
public static function getRecommendedProductsCacheKey(int $domainId, string $locale, int $productId): string
{
return 'product.v4.recommended.' . $productId . '.' . $domainId . '.' . $locale;
}
/**
* @param int $productId
* @return array
*/
public function getNotifications(int $productId): array
{
$customerNotifications = $this->entityManager
->createQuery("SELECT cn
FROM AtechNetCoreBundle:CustomerNotification cn
WHERE cn.product = :product AND cn.domain = :domain")
->setParameters([
'product' => $productId,
'domain' => $this->priceDomainId,
])
->getResult();
if ($customerNotifications) {
return $customerNotifications;
}
return [];
}
/**
* @param int $productId
* @param Customer|null $customer
* @param string|null $visitor
* @return bool
*/
public function isPriceMonitorActivated(int $productId, ?Customer $customer, ?string $visitor): bool
{
$notifications = $this->getNotifications($productId);
if (!is_null($customer)) {
foreach ($notifications as $notification) {
if (!is_null($notification->getCustomer()) && $notification->getCustomer()->getId() == $customer->getId()) {
return true;
}
}
} elseif (!is_null($visitor)) {
foreach ($notifications as $notification) {
if ($notification->getVisitor() == $visitor) {
return true;
}
}
}
return false;
}
/**
* @param object|string $photo
* @param string $directory
* @return Image
*/
protected function getImage($photo, string $directory = 'product'): Image
{
return new Image($this->cloudFlareApiConfig, $photo, $directory);
}
/**
* @param int $albumId
* @return bool
*/
public function getAlbumImages(int $albumId): array
{
$album = $this->entityManager->getRepository(Album::class)->findOneById($albumId);
$images = [];
if (count($album->getPhotos()) > 0) {
foreach ($album->getPhotos() as $image) {
$imgs = [
'original' => $image->getCdnUrl('ProductViewPop'),
];
$images[] = $imgs;
}
}
return $images;
}
/**
* @param array $productData
* @return bool
*/
public function getOSLabel(array $productData): ?array
{
$operationSystem = array_key_exists(Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM, $productData['attributes']) ? $productData['attributes'][Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM]['options'][array_key_first($productData['attributes'][Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM]['options'])]['title'] : null;
$filename = null;
$productTypeId = array_key_exists('typeId', $productData) ? $productData['typeId'] : $productData['productTypeId'];
if (str_contains(strtolower($operationSystem), 'chrome')) {
$filename = 'chrome';
} elseif (str_contains(strtolower($operationSystem), 'ios') || (array_key_exists('vendorId', $productData) && $productData['vendorId'] == Vendor::VENDOR_ID_APPLE)) {
if (in_array($productTypeId, [
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_PC_SET,
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE,
])) {
$filename = 'apple';
} elseif ($productTypeId == ProductType::PRODUCT_TYPE_ID_SMARTPHONE) {
$filename = 'ios';
} elseif ($productTypeId == ProductType::PRODUCT_TYPE_ID_TABLET) {
$filename = 'ipados';
}
} elseif (str_contains(strtolower($operationSystem), 'android')) {
$filename = 'android';
} elseif (
str_contains(strtolower($operationSystem), 'win') ||
(
(
in_array($productTypeId, [
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_PC_SET,
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE,
])
) &&
$productData['vendorId'] != Vendor::VENDOR_ID_APPLE
)
) {
$labels = isset($productData['badges']) ? $productData['badges'] : $productData['labels'];
$filename = 'windows' . (in_array('Windows 11', $labels) ? '_11' : '');
}
return [
'filename' => $filename,
'title' => $operationSystem,
];
}
/**
* @param string $locale
* @param string $webshopPhoneNumber
* @param array $salesManager
* @return array
*/
public function getSalesManagerForProductShow(string $locale, string $webshopPhoneNumber, array $salesManager): array
{
$position = '';
$phoneNumber = $webshopPhoneNumber;
switch ($locale) {
case 'en':
$photoFilename = 'mária-face.png';
$name = 'Mária';
$position = 'sales specialist';
break;
case 'cz':
case 'sk':
$photoFilename = 'mária-face.png';
$name = 'Mária';
break;
default:
$photoFilename = 'mária-face.png';
$name = 'Mária';
break;
}
$customerTypeId = $this->multiStore->getCustomerTypeId();
if (isset($salesManager['id']) && in_array($salesManager['id'], [Customer::SALES_MANAGER_WS_SK1_ID, Customer::SALES_MANAGER_NIKI_ID])) {
$photoFilename = 'kati-face.png';
$name = 'Kati';
$phoneNumber = '+421 220 512 060';
} else {
if ($customerTypeId == MultiStore::CUSTOMER_TYPE_WHOLESALE && !is_null($salesManager) && isset($salesManager['username']) && isset($salesManager['name'])) {
if (in_array($salesManager['id'], [Customer::SALES_MANAGER_DENISA_ID, 296])) {
$photoFilename = "";
} else {
$photoFilename = strtolower($salesManager['name']) . '-face.png';
}
$name = $salesManager['name'];
$position = 'sales manager';
if ($salesManager['phone'] != '' && $salesManager['phone'] != null && $locale != 'hu') {
$phoneNumber = $salesManager['phone'];
} elseif ($locale == 'hu') {
$phoneNumber = '+36 17 65 46 57';
} elseif ($locale == 'sk') {
$phoneNumber = '+421 220 512 060';
}
}
}
return [
'photoFilename' => $photoFilename,
'name' => $name,
'position' => $position,
'phoneNumber' => $phoneNumber,
];
}
public function getFullSpecificationList(array $data, $translator, $reviewUrl): array
{
$specificationList = [
[
'title' => 'Brand',
'content' => $data['categoryLinkWithBrandFilter'] ? "<a href=\"{$data['categoryLinkWithBrandFilter']}\" class=\"link-bold\" target=\"_blank\">{$data['brand']}</a>" : $data['brand'],
],
[
'title' => 'Model',
'content' => $data['productName'],
],
[
'title' => 'Product code',
'content' => $data['model'] . ($data['partNumber'] && $data['partNumber'] != '' ? "<small class=\"text-secondary\">({$data['partNumber']})</small>" : ''),
],
[
'title' => 'Availability',
'content' => $this->getStockStatus($data, $translator),
],
[
'title' => 'Quality grading',
'content' => $data['domainId'] == Domain::DOMAIN_ID_WS_EU ? "<strong>{$translator->trans($data['quality'])}</strong>" : $this->getQualityGradingContent($data, $translator, $reviewUrl),
],
];
if (count($data['containerParts']) > 0) {
return $specificationList;
}
foreach ($data['attributes'] as $attribute) {
if ($attribute == null || !array_key_exists('title', $attribute)) {
continue;
}
if (in_array($attribute['id'], [Attribute::ATTRIBUTE_ID_RAM_PC_TYPE, Attribute::ATTRIBUTE_ID_RAM_NB_TYPE, Attribute::ATTRIBUTE_ID_RAM_SIZE])) {
continue;
}
$isAttributeTypeEqualsStorage = in_array($attribute['id'], $data['storageAttributeIds']);
$title = $isAttributeTypeEqualsStorage ? 'Storage' : $attribute['title'];
$content = '';
if ($attribute['options']) {
foreach ($attribute['options'] as $option) {
$content .= '<span class="fw-bold">';
$content .= ($option['multiplier'] > 0 ? "{$option['multiplier']} x " : '') . $option['title'];
if ($isAttributeTypeEqualsStorage) {
$content .= " {$attribute['title']}";
}
$content .= '</span><br>';
}
}
$specificationList[] = [
'title' => $title,
'content' => $content,
];
}
if ($data['weight']) {
$specificationList[] = [
'title' => 'Weight',
'content' => $data['weight'],
];
}
if ($data['dimensions']) {
$specificationList[] = [
'title' => 'Dimensions',
'content' => $data['dimensions'],
];
}
if (
in_array($data['typeId'], [
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_MONITOR,
ProductType::PRODUCT_TYPE_ID_SMARTPHONE,
ProductType::PRODUCT_TYPE_ID_TABLET,
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE,
ProductType::PRODUCT_TYPE_ID_PROJECTOR,
])) {
$specificationList[] = [
'title' => 'Disclaimer',
'content' => $this->getDisclaimer($translator, $data['typeId']),
];
}
return $specificationList;
}
public function getSSDSize(array $data): ?string
{
$ssdSize = null;
foreach ($data as $attribute) {
if ($attribute && $attribute['title'] === 'SSD' && !empty($attribute['options'])) {
foreach ($attribute['options'] as $option) {
// Example: "1TB (M.2)" or "512GB"
if (preg_match('/(\d+(?:\.\d+)?)\s*(TB|GB)/i', $option['title'], $matches)) {
$ssdSize = $matches[1] . strtoupper($matches[2]);
break 2;
}
}
}
}
return $ssdSize;
}
private function getQualityGradingContent($data, $translator, $reviewUrl)
{
$quality = match ($data['quality']) {
'Gold' => 'A',
'Silver' => 'B',
'Bronze' => 'C',
default => $data['quality'],
};
$quality_description = $data['quality_description'];
$elements = "<strong>{$translator->trans("grades.$quality")}";
if ($quality && $quality_description) {
$elements .= ": ";
}
$elements .= "</strong>";
if ($quality && $quality_description) {
$elements .= "<span>{$quality_description} ";
}
$elements .= str_replace(
['{qualityTitle}', '{hrefValue}'],
[
$translator->trans($quality),
"$reviewUrl?category={$data['product_type_id']}&quality={$data['qualityStatusId']}",
],
$translator->trans('Customer reviews and photos of our {qualityTitle} rated products')
);
return $elements;
}
private function getStockStatus(array $data, $translator): string
{
$active = $data['active'];
$available = $data['available'];
$orderWaitingDays = $data['orderWaitingDays'];
if (!$active) {
return "<span class=\"in-stock text-grey\"><span class=\"dot\"></span>{$translator->trans('Out of stock')}</span>";
}
$classList = 'in-stock text-grey';
$textContent = 'Out of stock';
if ($orderWaitingDays > 0 && $available < 1) {
$textContent = str_replace('%d', $orderWaitingDays, $translator->trans('On order within %d working days'));
return "<span class=\"$classList\"><span class=\"dot\"></span>{$textContent}</span>";
}
if ($available > 1) {
$classList = "in-stock text-success";
}
if ($available == 1) {
return "<span class=\"in-stock text-danger\"><span class=\"dot\"></span>{$translator->trans('Only one left')}</span>";
}
if ($available > 10) {
$textContent = '10+ in stock';
} elseif ($available >= 5) {
$textContent = '5-10 in stock';
} elseif ($available > 1) {
$textContent = '2-4 in stock';
}
return "<span class=\"$classList\"><span class=\"dot\"></span>{$translator->trans($textContent)}</span>";
}
private function getDisclaimer($translator, int $productType)
{
return $translator->trans("Disclaimer_note.$productType");
}
private function getTnDisplayAttributeOptionIds(): string
{
$attribute = $this->entityManager->find(Attribute::class, Attribute::ATTRIBUTE_ID_DISPLAY_TECHNOLOGY);
if ($attribute) {
$panelIds = '';
foreach ($attribute->getOptions() as $option) {
if (!in_array($option->getId(), [
AttributeOption::ATTRIBUTE_OPTION_IPS_PANEL,
AttributeOption::ATTRIBUTE_OPTION_OLED_PANEL,
AttributeOption::ATTRIBUTE_OPTION_QLED_PANEL,
])) {
$panelIds .= $option->getId() . ',';
}
}
return trim($panelIds, ',');
}
return '';
}
private function getAttributeOptionIdsBasedOnTheAge(int $age): string
{
$dateTime = new \DateTime();
$currentYear = $dateTime->format('Y');
$yearFrom = 0;
$yearTo = 0;
switch ($age) {
case self::AGE_0_to_2_YEARS:
$yearFrom = $currentYear - 0; // to convert int
$yearTo = $currentYear - 2;
break;
case self::AGE_3_to_5_YEARS:
$yearFrom = $currentYear - 3;
$yearTo = $currentYear - 5;
break;
case self::AGE_6_PLUS_YEARS:
$yearFrom = $currentYear - 6;
$yearTo = 2005;
break;
}
if ($yearFrom == 0 && $yearTo == 0) {
return '';
}
$yearOptionIds = '';
for ($i = $yearFrom; $i >= $yearTo; $i--) {
$yearOptionIds .= AttributeOption::getYearAttributeOptionIds()[$i] . ',';
}
return trim($yearOptionIds, ',');
}
private function getPriorityProductsForCategoryPages(array $filter, CategoryPage $categoryPage): array
{
/**
* CHECK IF ANY FILTER IS APPLIED BY THE USER IF YES THEN DON`T SHOW THE PRIORITY PRODUCTS
*/
if (!$this->isUserApplyingFilters($filter, $categoryPage)) {
$priorityProducts = [];
if ($categoryPage->getPriorityProducts()->count() > 0) {
$priorityProducts = [];
foreach ($categoryPage->getPriorityProducts() as $priorityProduct) {
if ($priorityProduct->getProduct()->isAvailable()) {
$priorityProducts[$priorityProduct->getSortIndex()] = $priorityProduct->getProduct();
}
}
ksort($priorityProducts);
$priorityProducts = array_slice($priorityProducts, 0, 12);
}
return $priorityProducts;
}
return [];
}
private function isUserApplyingFilters(array $filter, CategoryPage $categoryPage): bool
{
$sideFilters = true;
$sortFilter = true;
if ((array_key_exists('filterVendor', $filter) && is_null($filter['filterVendor']))
&& (is_null($filter['filterAttribute']) || count($filter['filterAttribute']) == 0)
&& is_null($filter['filterPriceMin'])
&& is_null($filter['filterPriceMax'])
&& is_null($filter['filterLastPieces'])
&& (is_null($filter['filterDiscounted']) || $categoryPage->isShowOnlyDiscounted() == $filter['filterDiscounted'])
&& is_null($filter['filterCpuMarkMin'])
&& is_null($filter['filterCpuMarkMax'])
&& is_null($filter['filterProductType'])
&& (array_key_exists('start', $filter) && $filter['start'] == 0)
) {
$sideFilters = false;
}
if ($filter['sort'] == 'popular') {
$sortFilter = false;
}
return $sideFilters || $sortFilter;
}
private function getProductMetaText(?string $rawText, array $attributes): ?string
{
if (!$rawText) {
return null;
}
preg_match_all('/\[\[(.*?)\]\]/', $rawText, $matches);
foreach ($matches[1] as $i => $match) {
$translatedTitle = $this->translator->trans($match);
$result = array_filter($attributes, function ($item) use ($translatedTitle) {
return isset($item['title']) && $item['title'] === $translatedTitle;
});
$shortTitle = "";
foreach ($result as $item) {
if (isset($item['options']) && is_array($item['options'])) {
foreach ($item['options'] as $option) {
if (isset($option['title'])) {
$shortTitle .= $option['title'] . ", ";
}
}
}
}
$rawText = str_replace($matches[0][$i], rtrim($shortTitle, ', '), $rawText);
}
return $rawText;
}
}