<?php
namespace App\AtechNet\CoreBundle\Controller;
use App\AtechNet\CoreBundle\Entity\Attribute;
use App\AtechNet\CoreBundle\Entity\AttributeOption;
use App\AtechNet\CoreBundle\Entity\CategoryPage;
use App\AtechNet\CoreBundle\Entity\Coupon;
use App\AtechNet\CoreBundle\Entity\Customer;
use App\AtechNet\CoreBundle\Entity\CustomerNotification;
use App\AtechNet\CoreBundle\Entity\Domain;
use App\AtechNet\CoreBundle\Entity\DomainShippingType;
use App\AtechNet\CoreBundle\Entity\ErrorCode;
use App\AtechNet\CoreBundle\Entity\Language;
use App\AtechNet\CoreBundle\Entity\PageMeta;
use App\AtechNet\CoreBundle\Entity\Product;
use App\AtechNet\CoreBundle\Entity\ProductAttribute;
use App\AtechNet\CoreBundle\Entity\ProductMeta;
use App\AtechNet\CoreBundle\Entity\ProductType;
use App\AtechNet\CoreBundle\Entity\Review;
use App\AtechNet\CoreBundle\Entity\ReviewSurveyMedia;
use App\AtechNet\CoreBundle\Entity\SeoUrl;
use App\AtechNet\CoreBundle\Entity\StockItem;
use App\AtechNet\CoreBundle\Entity\SurveyMedia;
use App\AtechNet\CoreBundle\Entity\User;
use App\AtechNet\CoreBundle\Entity\Vendor;
use App\AtechNet\CoreBundle\Form\ReviewType;
use App\AtechNet\CoreBundle\Helper\Collections;
use App\AtechNet\CoreBundle\Helper\DeliveryUtil as DeliveryDate;
use App\AtechNet\CoreBundle\Helper\Furbify\CartHelper;
use App\AtechNet\CoreBundle\Helper\Furbify\Heureka;
use App\AtechNet\CoreBundle\Helper\Furbify\Image;
use App\AtechNet\CoreBundle\Helper\Furbify\MultiStore;
use App\AtechNet\CoreBundle\Helper\Furbify\ProductHelper;
use App\AtechNet\CoreBundle\Helper\Furbify\SearchHelper;
use App\AtechNet\CoreBundle\Helper\Furbify\TextHelper;
use App\AtechNet\CoreBundle\Helper\Packeta;
use App\AtechNet\CoreBundle\Sevices\ProductService;
use App\AtechNet\CoreBundle\Translation\DatabaseTranslator;
use Mpdf\Config\ConfigVariables;
use Mpdf\Config\FontVariables;
use Mpdf\Mpdf;
use Psr\Cache\CacheItemPoolInterface;
use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Stopwatch\Stopwatch;
class ProductController extends AbstractController
{
public const READY_BOX_PRODUCT_TYPES = [
52, // Notebook
60, // PC
107, // PC SET
116, // ALL IN ONE
77, // SERVER
];
private const REGENERATE_CACHE_TOKEN = '4d23c8c0629bf93f2a68e999df58283a';
private function parseSizeToGb(?string $title): ?int
{
if (is_null($title)) {
return null;
}
if (!preg_match('/(\d+(?:\.\d+)?)\s*(TB|GB)/i', $title, $m)) {
return null;
}
$value = (float) $m[1];
$unit = strtoupper($m[2]);
return $unit === 'TB'
? (int) ($value * 1024)
: (int) $value;
}
/**
* @Route("/product/{productId}", name="product_show", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/{productId}", name="product_show_locale", defaults={"_locale":""})
* @param int $productId
* @param Request $request
* @return Response
* @throws \Exception
*/
public function showAction($productId, Request $request): Response
{
// get rid of bots trying to access old search page
if ($productId == 'search' || !is_numeric($productId)) {
return $this->redirectToRoute('not_found');
}
$multiStore = $this->getMultiStoreHelper($request);
$entityManager = $this->getEntityManager();
$productHelper = $this->getProductHelper($request);
$domain = $multiStore->getDomain();
$domainId = $domain->getId();
$cache = $this->cache;
$productCacheKey = ProductHelper::getProductCacheKey($domainId, $request->getLocale(), $productId);
$productCacheItem = $cache->getItem($productCacheKey);
$productCacheTimeKey = ProductHelper::getProductCacheKey($domainId, $request->getLocale(), $productId) . '.time';
$productCacheTimeItem = $cache->getItem($productCacheTimeKey);
if ($productCacheItem->isHit()) {
// Product Cache Data
$pcd = $productCacheItem->get();
// Product Live Data
$pld = $entityManager->createQuery("SELECT p.id, p.available, pm.orderable, pm.active, pm.discounted, c.id as CouponId, c.showBadgeOnWebsite as showCouponBadgeOnWebsite
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p AND pm.domain = :domain
LEFT JOIN AtechNetCoreBundle:Coupon c WITH :productId MEMBER OF c.products AND c.domain = :domain AND c.enabled = true AND c.validFrom <= :now AND (c.validTo IS NULL OR c.validTo >= :now)
WHERE p.id = :productId")
->setParameters([
'domain' => $domain,
'productId' => $productId,
'now' => new \DateTime('now'),
])
->getResult();
if (count($pld) == 0) {
return $this->redirectToRoute('not_found');
}
$pld = $pld[0];
$valid = (int)$pcd['available'] == (int)$pld['available']
&& (int)$pcd['orderable'] == (int)$pld['orderable']
&& (int)$pcd['active'] == (int)$pld['active']
&& (int)$pcd['isDiscounted'] == (int)$pld['discounted'];
if (isset($pcd['coupon']) && (($pcd['coupon']['id'] != $pld['CouponId']) || ($pcd['coupon']['showCouponBadgeOnWebsite'] != $pld['showCouponBadgeOnWebsite']))) {
$valid = false;
} elseif (!isset($pcd['coupon']) && $pld['CouponId'] != null) {
$valid = false;
}
$product = $entityManager->getRepository(Product::class)->find($productId);
$productMetaForLanguage = $product->getProductModel()?->getMetaByLanguage($domain->getLanguage()->getCode());
if (!is_null($productMetaForLanguage?->getText())) {
if (!isset($pcd['productModelDescription'])) {
$valid = false;
} else {
if ($productMetaForLanguage->getText() != $pcd['productModelDescription']) {
$valid = false;
}
}
} else {
if (isset($pcd['productModelDescription'])) {
$valid = false;
}
}
if ($valid) {
$data = $pcd;
} else {
$data = $this->getProductViewData($productId, $request, $domain, $entityManager, $multiStore);
$productCacheItem->set($data);
$productCacheItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheItem);
$productCacheTimeItem->set((new \DateTime('now'))->getTimestamp());
$productCacheTimeItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheTimeItem);
}
} else {
$data = $this->getProductViewData($productId, $request, $domain, $entityManager, $multiStore);
$productCacheItem->set($data);
$productCacheItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheItem);
$productCacheTimeItem->set((new \DateTime('now'))->getTimestamp());
$productCacheTimeItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheTimeItem);
}
//For EU doamins add all keyboard reprints
if (in_array($domainId, [Domain::DOMAIN_ID_WS_EU, Domain::DOMAIN_ID_RT_EU])) {
//Check if product already has a reprint option
$existsKeyboardReprint = array_filter($data['secondaryOptions'], function ($item) {
return isset($item['id']) && $item['id'] == Attribute::ATTRIBUTE_ID_ACCESSORY_KEYBOARD_REPRINT;
});
if (count($existsKeyboardReprint) > 0) {
$key = array_key_first($existsKeyboardReprint);
//Get all languages
$allKeyboardLanguages = $entityManager->getRepository(AttributeOption::class)
->createQueryBuilder('ao')
->where('ao.attribute = :attribute')
->andWhere('ao.title NOT LIKE :excludedWord')
->andWhere('ao.title != :excludedExactWord')
->andWhere('ao.archived = 0')
->setParameter('attribute', Attribute::ATTRIBUTE_ID_ACCESSORY_KEYBOARD_REPRINT)
->setParameter('excludedWord', '%backlit%')
->setParameter('excludedExactWord', "Don't need")
->getQuery()->getResult();
/** @var AttributeOption $attributeOption */
foreach ($allKeyboardLanguages as $attributeOption) {
if (!isset($data['secondaryOptions'][$key]['options'][$attributeOption->getId()])) {
$attrOptionProductSuggestedPrice = $attrOptionProductVatSuggestedPrice = 0;
$attrOptionProduct = $attributeOption->getProduct();
if ($domain->getType() == Domain::TYPE_WHOLESALE) {
if ($attrOptionProduct) {
$attrOptionProductPriceMeta = $attrOptionProduct->getDomainMeta($domain);
if ($attrOptionProductPriceMeta->getDomainSuggestedPrice() > 0 && $attrOptionProductPriceMeta->getDomainVatSuggestedPrice() > 0) {
$attrOptionProductSuggestedPrice = $attrOptionProductPriceMeta->getDomainSuggestedPrice();
$attrOptionProductVatSuggestedPrice = $attrOptionProductPriceMeta->getDomainVatSuggestedPrice();
}
}
if ($attrOptionProductSuggestedPrice === 0 && $attrOptionProductVatSuggestedPrice === 0) {
$attrOptionRetailPriceMeta = $attributeOption->getDomainMeta($this->getMultiStoreHelper($request)->getRetailDomainByWholesaleDomain());
$attrOptionProductSuggestedPrice = $attrOptionRetailPriceMeta->getDomainPrice();
$attrOptionProductVatSuggestedPrice = $attrOptionRetailPriceMeta->getDomainVatPrice();
}
}
$attrOptionPriceMeta = $attributeOption->getDomainMeta($domain);
if ($attrOptionPriceMeta) {
$data['secondaryOptions'][$key]['options'][$attributeOption->getId()] = [
'id' => $attributeOption->getId(),
'title' => $attributeOption->getTitle(),
'discounted' => $attrOptionPriceMeta->isDiscounted(),
'price' => $attrOptionPriceMeta->getDomainPrice(),
'vatPrice' => $attrOptionPriceMeta->getDomainVatPrice(),
'discount' => $attrOptionPriceMeta->getDomainDiscount(),
'vatDiscounted' => $attrOptionPriceMeta->getDomainVatDiscount(),
'suggestedPrice' => $attrOptionProductSuggestedPrice,
'vatSuggestedPrice' => $attrOptionProductVatSuggestedPrice,
'productId' => $attributeOption->getProduct() != null ? $attributeOption->getProduct()->getId() : 0,
'image' => $attrOptionProduct?->getAlbum()?->getNthPhoto()
? $this->getImage($attrOptionProduct?->getAlbum()?->getNthPhoto(), '')
->resize(
Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_WIDTH,
Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_HEIGHT
)
: $this->getImage('placeholder.png', '')
->resize(
Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_WIDTH,
Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_HEIGHT
)
];
}
}
}
}
}
// Set back to a product link for cart
$request->getSession()->set('cartBackToProductsLink', $this->url($request)->link('product', [
'product_id' => $productId,
'isBazaar' => $data['isBazaar'] ?? 0
]));
if (!empty($data)) {
// Default Locale
$defaultLocale = $multiStore->getDefaultLocale();
$data['domainType'] = $domain->getType();
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
// Similar Products
$data['similarProducts'] = $this->getSimiliarProducts($productId, $cache, $domain, $request, $productHelper);
// Recommended Products
$data['recommendedProducts'] = $this->getRecommendedProducts($productId, $cache, $domain, $request, $productHelper);
$deliveryDate = (new DeliveryDate())->getEstimatedDeliveryDate($domainId, $data['isGamer'], in_array('7d', $data['labels']), is_null($data['orderWaitingDays']) ? 0 : $data['orderWaitingDays']);
$day = $deliveryDate->format('d.m.Y');
$data['estimated_deliver_date'] = $this->getTranslator()->trans('Estimated deliver is {day}', [
'day' => $day,
]);
// Review form
$data['reviewForm'] = $this->getProductDetailReviewForm($request, $multiStore->getDefaultLanguage(), $productId, $this->getTranslator());
$data['services_link'] = $this->url($request)->link('page', [
'static_id' => $this->getServicesPageLink($defaultLocale),
]);
$data['free_ship_limit'] = $productHelper::getFreeShipLimits()[$domainId]['freeShipLimit'];
$data['reviewsRedirectLink'] = $data['typeId'] > 0 && $data['qualityStatusId'] > 0;
//review_list
if ($data['reviewsRedirectLink']) {
$data['reviewLinkWithFilter'] = $this->generateUrl('review_list_' . $defaultLocale) . '?category=' . $data['typeId'] . '&quality=' . $data['qualityStatusId'];
}
// Price Monitor
$loggedInCustomerId = $request->getSession()->get('customerId');
$data['isLoggedIn'] = !is_null($loggedInCustomerId) && is_numeric($loggedInCustomerId);
$data['customer'] = $data['isLoggedIn'] ? $entityManager->getRepository(Customer::class)->findOneById($loggedInCustomerId) : null;
$identifier = hash('sha512', $request->getClientIp() . $request->server->get('HTTP_USER_AGENT'), false);
$data['warrantyYear'] = $this->getWarrantyForProductType($domainId, $data['typeId'])['year'];
$data['priceWarrantyDay'] = $this->getWarrantyForProductType($domainId, $data['typeId'])['priceWarrantyDay'];
$data['benefitList'] = ['warranty'];
$data['benefitList'][] = 'payback';
if ($multiStore->getCustomerTypeId() == Multistore::CUSTOMER_TYPE_RETAIL) {
$data['benefitList'][] = 'price-guarantee';
}
if (in_array($data['typeId'], [116, 60, 52])) { // AIO, PC, NB
$data['benefitList'][] = 'configuration';
}
$categoryShortTitle = null;
$seoUrlHelper = $this->getSeoUrlHelper($request);
switch ($defaultLocale) {
case 'sk':
$mainCategoryIds = [
'pc' => CategoryPage::SK_CATEGORYPAGE_ID_PC,
'nb' => CategoryPage::SK_CATEGORYPAGE_ID_NOTEBOOK,
'monitor' => CategoryPage::SK_CATEGORYPAGE_ID_MONITOR,
];
break;
case 'hu':
$mainCategoryIds = [
'pc' => CategoryPage::HU_CATEGORYPAGE_ID_PC,
'nb' => CategoryPage::HU_CATEGORYPAGE_ID_NOTEBOOK,
'monitor' => CategoryPage::HU_CATEGORYPAGE_ID_MONITOR,
];
break;
case 'cz':
$mainCategoryIds = [
'pc' => CategoryPage::CZ_CATEGORYPAGE_ID_PC,
'nb' => CategoryPage::CZ_CATEGORYPAGE_ID_NOTEBOOK,
'monitor' => CategoryPage::CZ_CATEGORYPAGE_ID_MONITOR,
];
break;
case 'en':
$mainCategoryIds = [
'pc' => CategoryPage::EU_CATEGORYPAGE_ID_PC,
'nb' => CategoryPage::EU_CATEGORYPAGE_ID_NOTEBOOK,
'monitor' => CategoryPage::EU_CATEGORYPAGE_ID_MONITOR,
];
break;
}
$categoryLinkWithBrandFilter = false;
switch ($data['typeId']) {
case 116:
case 60:
$categoryShortTitle = 'pc';
$categoryLinkWithBrandFilter = $seoUrlHelper->link('category', [
'path' => $mainCategoryIds[$categoryShortTitle],
]);
break;
case 52:
$categoryShortTitle = 'nb';
$categoryLinkWithBrandFilter = $seoUrlHelper->link('category', [
'path' => $mainCategoryIds[$categoryShortTitle],
]);
break;
case 44:
$categoryShortTitle = 'monitor';
$categoryLinkWithBrandFilter = $seoUrlHelper->link('category', [
'path' => $mainCategoryIds[$categoryShortTitle],
]);
break;
}
if ($categoryShortTitle != null) {
$data['benefitList'][] = 'power-cable-' . $categoryShortTitle;
}
$data['categoryLinkWithBrandFilter'] = $categoryLinkWithBrandFilter ? $categoryLinkWithBrandFilter . '?fv=' . $data['vendorId'] : null;
$data['isPriceMonitorActivated'] = $productHelper->isPriceMonitorActivated($productId, $data['customer'], $identifier);
$data['priceMonitorEmailDictionary'] = json_encode(TextHelper::dictionaryEmail());
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['showAdminLoginPanel'] = $request->getSession()->get('isAdminLogin');
$data['hasStockItemAlbum'] = $data['qualityStatusId'] == Product::QualityStatus_Bazaar ? $entityManager->getRepository(Product::class)->hasStockItemAlbum($productId, $data['isContainer']) : false;
$data['loggedInCustomer'] = $this->getLoginHelper($request)->getLoggedInCustomer();
// Shipping Methods
$data['shippingMethods'] = [];
$shippingMethods = $entityManager->getRepository(DomainShippingType::class)->findBy([
'domain' => $domainId,
'activeOnWeb' => true,
], [
'sortIndex' => 'ASC',
]);
$translator = $this->getTranslator();
$maxShippingPrice = 0;
$minShippingPrice = array_key_exists(0, $shippingMethods) ? $shippingMethods[0]->getPrice() : 0;
foreach ($shippingMethods as $shippingMethod) {
if ($shippingMethod->getType() == DomainShippingType::ShippingType_Carrier_Id && $domainId == Domain::DOMAIN_ID_WS_HU) {
$translationKey = 'shipping.method.type.' . $shippingMethod->getType() . '.achu';
} else {
$translationKey = 'shipping.method.type.' . $shippingMethod->getType();
}
if (($title = $translator->trans($translationKey)) == $translationKey) {
$title = false;
}
if (($description = $translator->trans($translationKey . '.description')) == $translationKey . '.description') {
$description = false;
}
if (($icon = $translator->trans($translationKey . '.icon')) == $translationKey . '.icon') {
$icon = false;
}
$shippingPrice = $shippingMethod->getPrice();
if (in_array($domainId, [Domain::DOMAIN_ID_RT_HU, Domain::DOMAIN_ID_WS_HU])) {
$shippingPrice = number_format($shippingPrice, 0, '.', '');
}
$minShippingPrice = $shippingPrice < $minShippingPrice && $shippingPrice > 0 ? $shippingPrice : $minShippingPrice;
$maxShippingPrice = $shippingPrice > $maxShippingPrice ? $shippingPrice : $maxShippingPrice;
if ($title) {
$data['shippingMethods'][$shippingMethod->getId()] = [
'id' => $shippingMethod->getId(),
'type' => $shippingMethod->getType(),
'title' => $title,
'description' => $description,
'price' => $shippingPrice,
'icon' => $icon,
'deliveryDays' => $shippingMethod->getShippingDays(),
'restriction' => isset($this->paymentMethodRestriction[$shippingMethod->getType()]) ? $this->paymentMethodRestriction[$shippingMethod->getType()] : [],
];
}
}
$data['minShippingPrice'] = $minShippingPrice;
$data['maxShippingPrice'] = $maxShippingPrice;
$data['currencyForShippingRate'] = $data['addressCountry'] = '';
switch ($defaultLocale) {
case 'sk':
$data['currencyForShippingRate'] = 'EUR';
$data['addressCountry'] = 'SK';
break;
case 'cz':
$data['currencyForShippingRate'] = 'CZK';
$data['addressCountry'] = 'CZ';
break;
case 'hu':
$data['currencyForShippingRate'] = 'HUF';
$data['addressCountry'] = 'HU';
break;
default:
$data['currencyForShippingRate'] = 'EUR';
$data['addressCountry'] = 'EU';
$data['minShippingPrice'] = 0;
break;
}
// Last Update
if ($productCacheTimeItem->isHit()) {
$timestamp = $productCacheTimeItem->get();
$data['lastCacheUpdate'] = (new \DateTime())->setTimestamp($timestamp);
}
$data['labelOs'] = $this->getProductHelper($request)->getOSLabel($data);
$data['shippingTitle'] = '';
$data['shippingCost'] = 0;
$dataForLowestShippingPriceFunction = [
'domain' => $domain,
'subTotal' => 0,
'packetaCodLimit' => Packeta::getCodLimitByDomainMarketCode(strtoupper($domain->getLanguage()->getCode())),
];
$shippingMethodWithLowestPrice = CartHelper::getShippingMethodWithLowestPriceForDomain($dataForLowestShippingPriceFunction, $entityManager);
if ($shippingMethodWithLowestPrice) {
// Shipping Cost
$data['shippingCost'] = $shippingMethodWithLowestPrice->getPrice();
// Lowest shipping Name
$data['shippingTitle'] = str_replace("(%address%)", "", $translator->trans("shipping.method.type." . $shippingMethodWithLowestPrice->getType()));
// Free Shipping
if ((float)$shippingMethodWithLowestPrice->getFreeShipLimit() > 0 && (float)$shippingMethodWithLowestPrice->getFreeShipLimit() < $data['subTotal']) {
$data['shippingCost'] = 0;
}
}
// Payment Methods
$paymentData = $this->getOrderHelper($request)->getPaymentMethodData($domain->getId());
$data['paymentMethods'] = $paymentData['paymentList'];
// Sales Manager
$salesManagerCacheKey = 'product.v3.salesManager.' . $domainId;
$salesManagerCacheItem = $cache->getItem($salesManagerCacheKey);
if ($salesManagerCacheItem->isHit()) {
$data['salesManager'] = $salesManagerCacheItem->get();
} else {
$webshopPhoneNumber = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
$data['salesManager'] = $this->getProductHelper($request)->getSalesManagerForProductShow($defaultLocale, $webshopPhoneNumber, $data['salesManager']);
$salesManagerCacheItem->set($data['salesManager']);
$salesManagerCacheItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($salesManagerCacheItem);
}
$productRepo = $entityManager->getRepository(Product::class);
$productRepo->getCpuGrouppedProductUAttributeArray($data['attributes']);
$data['storageAttributeIds'] = [
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_HDD18,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_HDD_35,
Attribute::ATTRIBUTE_ID_SSHD25,
Attribute::ATTRIBUTE_ID_SSHD35,
Attribute::ATTRIBUTE_ID_SAS_HDD25,
];
$data['cetelem_hu_shop_id'] = $this->getParameter('cetelem_hu_shop_id');
$data['cetelem_hu_url'] = $this->getParameter('cetelem_hu_url');
$data['cetelem_hu_barem_code'] = $this->getParameter('cetelem_hu_barem_code');
$data['cetelem_hu_price_minimum'] = $this->getParameter('cetelem_hu_price_minimum');
$priceToPay = $data['special'] ?: $data['price'];
$data['showKlarna'] = false;
if (in_array($domainId, [
Domain::DOMAIN_ID_RT_SK,
Domain::DOMAIN_ID_RT_HU,
Domain::DOMAIN_ID_RT_CZ,
Domain::DOMAIN_ID_RT_EU,
])) {
$data['showKlarna'] = $this->getKlarna($domainId, $request)->priceIsWithinRange($data['special'] ?: $data['price']);
}
if (in_array($domain->getLanguage()->getCode(), ['hu']) && $this->getEnvironment() == 'prod') {
// Milpay
$milpayHelper = $this->getMilpay($domain->getLanguage()->getCode());
$data['milpayInfo'] = $milpayHelper->getInfoForProductShow($data['special'] ?: $data['price'], $domain);
if (!empty($data['milpayInfo'])) {
$data['milpayInfo']['staticpageUrl'] = $this->url($request)->link('page', [
'static_id' => match($domainId) {
Domain::DOMAIN_ID_RT_SK => 157,
Domain::DOMAIN_ID_RT_HU => 150,
Domain::DOMAIN_ID_RT_CZ => 169,
}
]);
$milpayOfferInfo = $milpayHelper->getAvailableOffers();
$milpayOfferId = $milpayOfferInfo['offerId'];
$milpayOfferMerchantId = $milpayOfferInfo['merchantId'];
$linkHeadingTitle = str_replace([' ', '"'], ['+', "+inch"], $data['heading_title']);
$linkDescription = str_replace([' ', '"'], ['+', '+inch'], $data['description']);
$linkDescription = str_replace(
['Gold', 'Silver', 'Bronze', 'New', 'Bazaar'],
[
$translator->trans('grades.A'),
$translator->trans('grades.B'),
$translator->trans('grades.C'),
$translator->trans('grades.New'),
$translator->trans('grades.Bazaar'),
],
$linkDescription
);
$data['milpayInfo']['minAmount'] = $milpayOfferInfo['minAmount'];
$data['milpayInfo']['maxAmount'] = $milpayOfferInfo['maxAmount'];
$redirectUrl = $seoUrlHelper->link('product', [
'product_id' => $productId,
'isBazaar' => $data['isBazaar'] ?? 0
]);
$priceToPay = $data['special'] ?: $data['price'];
$data['milpayInfo']['prescoreLink'] = $milpayHelper->getPrescoreUrl(
$domain->getLanguage()->getCode(),
$milpayOfferId,
$priceToPay,
$milpayOfferMerchantId,
$linkHeadingTitle,
$linkDescription,
$redirectUrl
);
}
}
$data['domainId'] = $domainId;
$data['specificationList'] = $productHelper->getFullSpecificationList($data, $translator, $this->generateUrl("review_list_{$request->getLocale()}"));
$storageSpec = $this->parseSizeToGb($productHelper->getSSDSize($data['attributes']));
$data['secondaryOptions'] = array_map(function ($item) use ($storageSpec) {
if (str_contains($item['title'], 'SSD')) {
$item['options'] = array_filter(
$item['options'],
function ($option) use ($storageSpec) {
$optionSizeGb = $this->parseSizeToGb($option['title']);
return $optionSizeGb !== null && $optionSizeGb > $storageSpec;
}
);
}
return $item;
}, $data['secondaryOptions']);
if (in_array($domain->getId(), MultiStore::getRetailDomainIDs())
&& $data['labelOs']['filename'] != 'chrome'
&& in_array($data['typeId'], [
ProductType::PRODUCT_TYPE_ID_PC,
ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE,
ProductType::PRODUCT_TYPE_ID_PHONE,
ProductType::PRODUCT_TYPE_ID_SMARTPHONE,
ProductType::PRODUCT_TYPE_ID_TABLET,
ProductType::PRODUCT_TYPE_ID_PC_SET,
]))
{
$data['showNorton'] = true;
$data['nortonUrl'] = match($domainId){
Domain::DOMAIN_ID_RT_SK => 'https://www.furbify.sk/norton-360-standard',
Domain::DOMAIN_ID_RT_HU => 'https://www.furbify.hu/norton-360-standard',
Domain::DOMAIN_ID_RT_CZ => 'https://www.furbify.cz/norton-360-standard',
Domain::DOMAIN_ID_RT_EU => 'https://www.furbify.eu/norton-360-standard',
};
}
//Free packeta shipping
if ($data['typeId'] == ProductType::PRODUCT_TYPE_ID_NOTEBOOK
&& !in_array($domainId, [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU])
&& (new \DateTime('NOW'))->format('Y-m-d') >= '2025-05-19'
&& (new \DateTime('NOW'))->format('Y-m-d') <= '2025-06-30')
{
$data['freePacketaShipping'] = true;
}
if ($domain->getId() == Domain::DOMAIN_ID_RT_HU) {
$packageFeeProduct = $entityManager->getRepository(Product::class)->find(Product::MPL_PACKAGE_FEE_PRODUCT_ID);
$data['MPL_PACKAGE_FEE'] = $packageFeeProduct->getDomainMeta($domain)->getCurrentVatPrice();
}
return $this->render('AtechNetCoreBundle/Product/product.html.twig', $data);
}
return $this->redirectToRoute('not_found');
}
/**
* @param int $productId
* @param Request $request
* @param Domain $domain
* @param $entityManager
* @param MultiStore $multiStore
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
private function getProductViewData(int $productId, Request $request, Domain $domain, $entityManager, MultiStore $multiStore)
{
$product = $this->getProductHelper($request)->getStructuredDataByProductId($productId);
if ($product) {
return $this->buildProductViewData($product, $request, $domain, $entityManager, $multiStore);
}
return false;
}
/**
* @param $product
* @param Request $request
* @param Domain $domain
* @param $entityManager
* @param MultiStore $multiStore
* @return array
* @throws \Exception
*/
private function buildProductViewData($product, Request $request, Domain $domain, $entityManager, MultiStore $multiStore): array
{
$seoUrlHelper = $this->getSeoUrlHelper($request);
$translator = $this->getTranslator();
$data = [];
$data['currency'] = $domain->getCurrency();
$data['currency_ISO'] = $this->getCurrencyISOForm($data['currency']);
$data['precision'] = $domain->getPricePrecision();
$data['vatPercentage'] = $domain->getVat();
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
// Category Repository
$categoryPageRepository = $entityManager->getRepository(CategoryPage::class);
$categoryPageRepository->setSession($request->getSession());
switch ($domain->getId()) {
case Domain::DOMAIN_ID_WS_SK:
$categoryDomain = $entityManager->getRepository(Domain::class)->findOneBy([
'id' => Domain::DOMAIN_ID_RT_SK,
]);
break;
case Domain::DOMAIN_ID_WS_HU:
$categoryDomain = $entityManager->getRepository(Domain::class)->findOneBy([
'id' => Domain::DOMAIN_ID_RT_HU,
]);
break;
case Domain::DOMAIN_ID_WS_CZ:
$categoryDomain = $entityManager->getRepository(Domain::class)->findOneBy([
'id' => Domain::DOMAIN_ID_RT_CZ,
]);
break;
case Domain::DOMAIN_ID_WS_EU:
$categoryDomain = $entityManager->getRepository(Domain::class)->findOneBy([
'id' => Domain::DOMAIN_ID_RT_EU,
]);
break;
default:
$categoryDomain = $domain;
break;
}
$productMainCategoryPage = $entityManager
->createQuery("SELECT cp
FROM AtechNetCoreBundle:CategoryPage cp
LEFT JOIN cp.productTypes pt
LEFT JOIN cp.vendors v
WHERE pt.id = :productTypeId AND v.id IS NULL AND cp.domain = :domain AND cp.showOnlyBazaar = :bazaar")
->setParameters([
'productTypeId' => $product['productTypeId'],
'domain' => $categoryDomain,
'bazaar' => $request->getSession()->get('isBazaarPage')
])
->setMaxResults(1)
->getResult();
if (isset($productMainCategoryPage[0])) {
$categoryPage = $productMainCategoryPage[0];
$categoryPageMeta = $categoryPage->getMetaByLanguage($multiStore->getDefaultLanguage());
if ($categoryPageMeta) {
$useAlternativeCategoryPage = false;
if ($multiStore->isLanguageSwitched()) {
$alternativeCategoryPage = $categoryPageRepository->getAlternativeCategoryByLanguage($categoryPage);
if ($alternativeCategoryPage) {
$alternativeCategoryMeta = $alternativeCategoryPage->getMetaByLanguage($multiStore->getLanguage());
if ($alternativeCategoryMeta) {
$useAlternativeCategoryPage = true;
$data['breadcrumbs'][] = [
'text' => $alternativeCategoryMeta->getTitle(),
'href' => $seoUrlHelper->link('category', [
'path' => $categoryPage->getId(),
'isBazaar' => $categoryPage->isShowOnlyBazaar()
])
];
}
}
}
if ( $useAlternativeCategoryPage === false ) {
$data['breadcrumbs'][] = [
'text' => $categoryPageMeta->getTitle(),
'href' => $seoUrlHelper->link('category', [
'path' => $categoryPage->getId(),
'isBazaar' => $categoryPage->isShowOnlyBazaar()
]),
];
}
}
}
$data['breadcrumbs'][] = [
'text' => ($product['vendor'] !== '' ? $product['vendor'] . ' ' : '') . $product['title'],
'href' => $this->url($request)->link('product', [
'product_id' => $product['id'],
'isBazaar' => $product['isBazaar'] ?? 0
]),
];
$data['heading_title'] = ($product['vendor'] !== '' ? $product['vendor'] . ' ' : '') . ProductHelper::getHeadingTitle($product);
$data['h1_title'] = ($multiStore->getCustomerTypeId() == MultiStore::CUSTOMER_TYPE_RETAIL) ?
($product['vendor'] !== '' ? $product['vendor'] . ' ' : '') . ProductHelper::getLongTitleWithConfig($product, $translator) :
$product['title'] . ' - ' . $product['code'];
$data['h1_title'] = in_array($domain->getId(), [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) ? str_replace([' (Quality: Bazar)', ' (Quality: Bazár)', ' (Quality: Bazár, '], ['', '', ' ('], $data['h1_title']) : $data['h1_title'];
$data['seoDescription'] = ($product['shortDescription'] != '' ? $product['shortDescription'] : $data['heading_title']) . ' | ' . $product['code'];
$data['product_id'] = $product['id'];
$data['title'] = $product['vendor'] . ' ' . $product['title'];
$data['productName'] = $product['title'];
$data['type'] = $product['productType'];
$data['typeId'] = $product['productTypeId'];
$data['product_type_id'] = $product['productTypeId'];
$data['model'] = $product['code'];
$data['partNumber'] = $product['partNumber'];
$data['available'] = $product['availableQty'];
$data['orderWaitingDays'] = $product['orderWaitingDays'];
$data['description'] = str_replace(' | ', ', ', $product['shortDescription']);
$data['quality'] = $product['qualityTitle'];
$data['qualityStatusId'] = $product['qualityStatusId'];
$data['active'] = $product['active'];
$data['timedSalesActive'] = $product['timedSalesActive'];
$data['timedSalesEndDate'] = $product['timedSalesEndDate'];
$data['priceWoVAT'] = $product['price'];
$data['discountWoVAT'] = $product['discountPrice'];
$data['rawPriceWoVAT'] = $product['rawPrice'];
$data['rawDiscountPriceWoVAT'] = $product['rawDiscountPrice'];
$data['weight'] = $product['weight'] != 0 ? number_format($product['weight'] / 1000, 1, ',', ' ') . ' kg' : '';
$data['isContainer'] = $product['isContainer'];
$data['containerParts'] = $product['containerParts'];
$data['connectedBatteries'] = $product['connectedBatteries'] ?? [];
$data['isBazaar'] = $product['isBazaar'] ?? 0;
$dimensions = [];
if ($product['width'] != 0) {
$dimensions[] = $product['width'] . ' mm';
}
if ($product['length'] != 0) {
$dimensions[] = $product['length'] . ' mm';
}
if ($product['height'] != 0) {
$dimensions[] = $product['height'] . ' mm';
}
$data['dimensions'] = !empty($dimensions) ? implode(' x ', $dimensions) : '';
$data['additionalDetail'] = ProductHelper::createFormatedDetail($product['additionalDetail']);
switch ($domain->getId()) {
case Domain::DOMAIN_ID_RT_SK:
case Domain::DOMAIN_ID_WS_SK:
$data['quality_descriptions_link'] = $seoUrlHelper->link('page', [
'static_id' => 11,
]);
$data['shipping_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 14,
]);
$data['price_guarantee_link'] = $seoUrlHelper->link('page', [
'static_id' => 41,
]);
$data['cetelem_desc_page_link'] = $seoUrlHelper->link('page', [
'static_id' => 16,
]);
break;
case Domain::DOMAIN_ID_RT_HU:
case Domain::DOMAIN_ID_WS_HU:
$data['quality_descriptions_link'] = $seoUrlHelper->link('page', [
'static_id' => 27,
]);
$data['shipping_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 30,
]);
$data['price_guarantee_link'] = $seoUrlHelper->link('page', [
'static_id' => 40,
]);
$data['cetelem_desc_page_link'] = $seoUrlHelper->link('page', [
'static_id' => 19,
]);
break;
case Domain::DOMAIN_ID_RT_CZ:
case Domain::DOMAIN_ID_WS_CZ:
$data['quality_descriptions_link'] = $seoUrlHelper->link('page', [
'static_id' => 60,
]);
$data['shipping_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 63,
]);
$data['price_guarantee_link'] = $seoUrlHelper->link('page', [
'static_id' => 67,
]);
$data['cetelem_desc_page_link'] = $seoUrlHelper->link('page', [
'static_id' => 65,
]);
break;
default:
$data['quality_descriptions_link'] = $seoUrlHelper->link('page', [
'static_id' => 11,
]);
$data['shipping_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 14,
]);
$data['price_guarantee_link'] = $seoUrlHelper->link('page', [
'static_id' => 41,
]);
$data['cetelem_desc_page_link'] = $seoUrlHelper->link('page', [
'static_id' => 16,
]);
}
if ($data['quality']) {
switch ($data['quality']) {
case 'New':
$data['quality_description'] = $translator->trans('quality description new');
break;
case 'Gold':
$data['quality_description'] = $translator->trans('quality description gold');
break;
case 'Silver':
$data['quality_description'] = $translator->trans('quality description silver');
break;
case 'Bronze':
$data['quality_description'] = $translator->trans('quality description bronze');
break;
case 'Platinum':
$data['quality_description'] = $translator->trans('quality description platinum');
break;
default:
$data['quality_description'] = '';
}
}
$data['brand'] = $product['vendor'];
$data['vendorId'] = $product['vendorId'];
$data['orderable'] = (int)$product['orderable'];
$data['price'] = $product['vatPrice'];
$data['suggestedVatPrice'] = $product['suggestedVatPrice'];
$data['suggestedPrice'] = $product['suggestedPrice'];
$data['profitPercentage'] = 0;
$data['isDiscounted'] = $product['isDiscounted'];
if ($product['isDiscounted']) {
$data['discountWithVat'] = $product['discountVatPrice'];
$data['special'] = $product['discountVatPrice'];
if ($product['discountVatPrice'] != 0 && $data['suggestedVatPrice'] != 0) {
$data['profitPercentage'] = round((1 - ($data['special'] / $data['suggestedVatPrice'])) * 100, 0);
}
} else {
$data['special'] = false;
if ($product['vatPrice'] != 0 && $data['suggestedVatPrice'] != 0) {
$data['profitPercentage'] = round((1 - ($data['price'] / $data['suggestedVatPrice'])) * 100, 0);
}
}
$data['images'] = [];
if (count($product['images']) > 0) {
foreach ($product['images'] as $photo) {
$data['images'][] = [
'popup' => $this->getImage($photo, 'product/' . $product['code'])->resize(Image::PRODUCT_VIEW_POPUP_WIDTH, Image::PRODUCT_VIEW_POPUP_HEIGHT),
'thumb' => $this->getImage($photo, 'product/' . $product['code'])->resize(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT),
'additional' => $this->getImage($photo, 'product/' . $product['code'])->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT),
];
}
$data['thumb'] = $this->getImage($product['images']->first(), 'product/' . $product['code'])->resize(Image::LIVESEARCH_THUMB_WIDTH, Image::LIVESEARCH_THUMB_HEIGHT);
} else {
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_VIEW_POPUP_WIDTH, Image::PRODUCT_VIEW_POPUP_HEIGHT);
$data['images'][] = [
'popup' => $placeholder,
'thumb' => $placeholder,
'additional' => $placeholder,
];
}
$data['labels'] = $product['badges'];
$data['isBestseller'] = $product['isBestseller'] ?? false;
$data['options'] = $product['accessories'];
$data['primaryOptions'] = $data['secondaryOptions'] = [];
$data['skinColorSelectorIsDefined'] = false;
if (!empty($product['connectedBatteries'])) {
/** @var AttributeOption $newBatteryAttributeOption */
$newBatteryAttributeOption = $entityManager->getRepository(AttributeOption::class)->find($product['batterAttributeOptionId']);
if ($newBatteryAttributeOption) {
$optionMeta = $newBatteryAttributeOption->getDomainMeta($domain);
$attributeOptionId = $newBatteryAttributeOption->getId();
$defaultData = [
'id' => Attribute::ATTRIBUTE_ID_NEW_BATTERY,
'title' => $this->translator->trans('New battery'),
'options' => [
$attributeOptionId => [
'id' => $attributeOptionId,
'title' => $newBatteryAttributeOption->getTitle($this->getDatabaseTranslator($request)),
'discounted' => $optionMeta->isDiscounted(),
'vatPrice' => $optionMeta->getDomainVatPrice(),
'price' => $optionMeta->getDomainPrice(),
"discount" => $optionMeta->getDomainDiscount(),
"vatDiscounted" => $optionMeta->getDomainVatDiscount(),
"suggestedPrice" => $optionMeta->getDomainPrice(),
"vatSuggestedPrice" => $optionMeta->getDomainVatPrice(),
"productId" => $newBatteryAttributeOption->getProduct()->getId(),
"image" => 'battery.svg',
],
]
];
$data['secondaryOptions'][] = $defaultData;
}
}
foreach ($data['options'] as $option) {
// Scan $option['options'] for defined product_ids; if it`s true { get product`s first image }
foreach ($option['options'] as $key => $value) {
if (($value['productId'] != 0)) {
// image goes here
$configurationProduct = $this->getProductHelper($request)->getStructuredDataByProductId($value['productId'], 'configurator');
$option['options'][$key]['image'] = $this->getImage($configurationProduct['images'], 'product/' . $value['productId'])->resize(Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_WIDTH, Image::PRODUCT_CONFIGURATOR_ITEM_THUMB_HEIGHT);
}
}
if (in_array($option['id'], [
Attribute::ATTRIBUTE_ID_ACCESSORY_OS,
Attribute::ATTRIBUTE_ID_ACCESSORY_SOFTWARE_PACKAGE,
Attribute::ATTRIBUTE_ID_ACCESSORY_ANTIVIRUS_SOFTWARE,
Attribute::ATTRIBUTE_ID_ACCESSORY_OFFICE_365,
])) {
if ($option['id'] == Attribute::ATTRIBUTE_ID_ACCESSORY_OS) {
if ($multiStore->getCustomerTypeId() == MultiStore::CUSTOMER_TYPE_RETAIL) {
unset($option['options'][425]); // MAR windows 10 pro
unset($option['options'][426]); // MAR windows 10 home
}
else {
unset($option['options'][2128]); // Windows 10 pro digital
}
}
if (in_array($domain->getId(), [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) && $option['id'] == 23) {
foreach ($option['options'] as $antivisOptionKey => $antivirusOption) {
if (!str_contains($antivirusOption['title'], 'G DATA')) {
unset($option['options'][$antivisOptionKey]);
}
}
}
$data['primaryOptions'][] = $option;
}
//SKIP POWER CABLE FOR MONITORS
else if ($product['productTypeId'] == ProductType::PRODUCT_TYPE_ID_MONITOR && $option['id'] == Attribute::ATTRIBUTE_ID_POWER_CABLE) {
continue;
}
else {
$data['secondaryOptions'][] = $option;
if ($option['id'] == Attribute::ATTRIBUTE_ID_NOTEBOOK_SKIN) {
$data['skinColorSelectorIsDefined'] = true;
}
}
}
$installSoftwarePackageOption = null;
foreach ($data['primaryOptions'] as $key => $option) {
if ($option['id'] == Attribute::ATTRIBUTE_ID_ACCESSORY_SOFTWARE_PACKAGE) {
$installSoftwarePackageOption = $option;
unset($data['primaryOptions'][$key]);
}
if ($option['id'] == Attribute::ATTRIBUTE_ID_ACCESSORY_OS) {
$order = [
AttributeOption::ATTRIBUTE_OPTION_ID_WINDOWS_11_PRO,
AttributeOption::ATTRIBUTE_OPTION_ID_WINDOWS_11_HOME,
AttributeOption::ATTRIBUTE_OPTION_ID_WINDOWS_10_PRO,
AttributeOption::ATTRIBUTE_OPTION_ID_WINDOWS_10_HOME,
AttributeOption::ATTRIBUTE_OPTION_ID_LINUX_MINT
];
uksort($option['options'], function ($a, $b) use ($order) {
$posA = array_search($a, $order);
$posB = array_search($b, $order);
return $posA <=> $posB;
});
$data['primaryOptions'][$key]['options'] = $option['options'];
}
}
// move to last position
if ($installSoftwarePackageOption != null) {
$data['primaryOptions'][] = $installSoftwarePackageOption;
}
$data['defaultOptions'] = $product['defaultOptions'];
$data['attributes'] = $product['attributes'];
$data['isGamer'] = in_array('gamer', $data['labels']);
// Includes
$data['include_cable'] = '';
if ((int)$product['productTypeId'] == 44) {
$data['include_cable'] = $translator->trans('Free power cord and data cable included');
} elseif ((int)$product['productTypeId'] == 52) {
$data['include_cable'] = $translator->trans('Free AC adapter and power cord included');
} elseif ((int)$product['productTypeId'] == 116 || (int)$product['productTypeId'] == 60) {
$data['include_cable'] = $translator->trans('Free power cord included');
}
$data['include_keyboard_sticker'] = '';
if ((int)$product['productTypeId'] == 52) {
$data['include_keyboard_sticker'] = $translator->trans('Free keyboard sticker included');
}
// Ready Box
$data['show_ready_box'] = in_array($product['productTypeId'], self::READY_BOX_PRODUCT_TYPES) && $data['quality'] != 'New' && $data['brand'] != 'Apple';
$domainLanguageCode = $domain->getLanguage()->getCode();
// Cetelem & Quatro
$data['cetelem_calculator'] = false;
$data['quatro_calculator'] = false;
if ($domain->getId() == Domain::DOMAIN_ID_RT_HU) { // LPC or FPC
$data['cetelem_calculator'] = true;
$data['cetelem_calculator_country'] = $domainLanguageCode;
}
if ($product['isDiscounted']) {
$productPrice = $domain->getType() == Domain::TYPE_RETAIL ? $data['discountWithVat'] : $data['discountWoVAT'];
} else {
$productPrice = $domain->getType() == Domain::TYPE_RETAIL ? $data['price'] : $data['rawPriceWoVAT'];
}
if ($domain->getId() == Domain::DOMAIN_ID_RT_SK && $productPrice >= 100) { // LPC
$data['quatro_calculator'] = $this->getParameter('quatro_calculator_url');
}
$data['salesManager'] = [];
$loggedInCustomer = $this->getLoginHelper($request)->getLoggedInCustomer();
if (!is_null($loggedInCustomer) && !is_null($loggedInCustomer->getSalesManager())) {
$salesManager = $loggedInCustomer->getSalesManager();
$data['salesManager']['id'] = $salesManager->getId();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domainLanguageCode . '.' . $domain->getType()];
$data['contentBottom'] = $this->getContentBottom($request, null, $this->getWarrantyForProductType($domain->getId(), $product['productTypeId'])['year']);
$data['reviewCount'] = $product['reviewCount'];
$data['reviewStars'] = $product['reviewStars'];
$data['reviews'] = $product['reviews'];
/**
* CHECK IF EXIST A SHIPPING METHOD WITH FREE SHIPPING
*/
$shippingTypes = $entityManager->createQueryBuilder()
->select('dst')
->from('AtechNetCoreBundle:DomainShippingType', 'dst')
->where('dst.domain = :domain')
->andWhere('dst.freeShippingStartDate IS NOT NULL AND dst.freeShippingEndDate IS NOT NULL')
->andWhere('dst.freeShippingStartDate <= :now AND dst.freeShippingEndDate >= :now')
->setParameters([
'domain' => $domain->getId(),
'now' => (new \DateTime())->format('Y-m-d'),
])
->getQuery()
->getResult();
$filteredShippingTypes = array_filter($shippingTypes, function ($shippingType) use ($product) {
/** @var DomainShippingType $shippingType */
return in_array($product['productTypeId'], $shippingType->getFreeShippingProductTypes(), true);
});
$data['freeShipping'] = count($filteredShippingTypes) > 0;
if (!is_null($product['couponCode'])) {
$data['coupon'] = [
'id' => $product['couponId'],
'code' => $product['couponCode'],
'discount' => $product['couponDiscount'],
'priceWithCoupon' => $product['vatPriceWithCoupon'],
'showCouponBadgeOnWebsite'=> $product['showCouponBadgeOnWebsite'],
];
}
if (!is_null($product['productModelDescription'])) {
$data['productModelDescription'] = $product['productModelDescription'];
}
if (!is_null($product['warranties'])) {
$data['warranties'] = [];
$extendedWarranty = $entityManager->getRepository(Attribute::class)->findOneById(Attribute::ATTRIBUTE_ID_EXTENDED_WARRANTY);
$data['warranties']['attribute'] = $extendedWarranty;
foreach ($product['warranties'] as $optionId => $warranty) {
$attributeOption = $entityManager->getRepository(AttributeOption::class)->find($optionId);
$warrantyPercent = $warranty['percentPrice'];
//2025 christmas ->
$now = new \DateTime('now');
$startDate = new \DateTime("2025-11-30 00:00:00");
$endDate = new \DateTime("2025-12-21 23:59:59");
$discountWarrantyPercent = $warrantyPercent;
if ($now >= $startDate && $now <= $endDate) {
$discountWarrantyPercent /= 2;
}
$productPrice = $product['isDiscounted'] ? $product['rawDiscountPrice'] : $product['price'];
$productVatPrice = $product['isDiscounted'] ? $product['discountVatPrice'] : $product['vatPrice'];
$data['warranties']['data'][] = [
'id' => $attributeOption->getId(),
'title' => $attributeOption->getTitle(),
'vatPrice' => $domain->createVatPrice((($productVatPrice * $warrantyPercent) / 100), 1.),
'price' => $domain->createVatPrice((($productPrice * $warrantyPercent) / 100), 1.),
'vatDiscounted' => $domain->createVatPrice((($productVatPrice * $discountWarrantyPercent) / 100), 1.),
'discount' => $domain->createVatPrice((($productPrice * $discountWarrantyPercent) / 100), 1.),
'image' => $warranty['image'],
];
}
}
return $data;
}
/**
* @param int $productId
* @param CacheItemPoolInterface $cache
* @param Domain $domain
* @param Request $request
* @param ProductHelper $productHelper
* @return array
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function getSimiliarProducts($productId, CacheItemPoolInterface $cache, Domain $domain, Request $request, ProductHelper $productHelper)
{
$similarProductsCacheKey = ProductHelper::getSimiliarProductsCacheKey($domain->getId(), $request->getLocale(), $productId);
$similarProductsCacheItem = $cache->getItem($similarProductsCacheKey);
if (!$similarProductsCacheItem->isHit()) {
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
$similiarProducts = [];
foreach ($productHelper->getSimilarProducts($productId) as $similarProduct) {
$image = $placeholder;
if (is_object($similarProduct['images'])) {
$image = $this->getImage($similarProduct['images'], 'product/' . $similarProduct['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$attributeListTxt = in_array(
$similarProduct['productTypeId'],
[ProductType::PRODUCT_TYPE_ID_TABLET, ProductType::PRODUCT_TYPE_ID_SMARTWATCH]
) ?
str_replace([' | ', 'Win 10 Pro'], [', ', 'Windows'], $similarProduct['shortDescription']) :
str_replace([' | ', 'Win 10 Pro'], [', ', 'Windows'], $similarProduct['attributesListTxt'])
;
$similiarProducts[] = [
'image' => $image,
'labels' => $similarProduct['badges'],
'vendor' => $similarProduct['vendor'],
'vendorId' => $similarProduct['vendorId'],
'typeId' => $similarProduct['productTypeId'],
'title' => $similarProduct['title'],
'price' => $similarProduct['vatPrice'],
'rawPrice' => $similarProduct['rawPrice'],
'rawDiscountPrice' => $similarProduct['rawDiscountPrice'],
'attributes' => $similarProduct['attributes'],
'available' => $similarProduct['availableQty'],
'special' => ($similarProduct['isDiscounted'] ? $similarProduct['discountVatPrice'] : false),
'href' => $this->url($request)->link('product', [
'product_id' => $similarProduct['id'],
'isBazaar' => $similarProduct['isBazaar'] ?? 0
]),
'active' => $similarProduct['active'],
'timedSalesActive' => $similarProduct['timedSalesActive'],
'reviewCount' => $similarProduct['reviewCount'],
'reviewStars' => $similarProduct['reviewStars'],
'reviews' => $similarProduct['reviews'],
'freeShipping' => $similarProduct['freeShipping'],
'attributesListTxt' => $attributeListTxt,
'warrantyYear' => $similarProduct['qualityStatusId'] == Product::QualityStatus_Bazaar ? 1 : $this->getWarrantyForProductType($domain->getId(), $similarProduct['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($similarProduct),
'qualityStatusTitle' => Product::getQualityStatusChoices()[$similarProduct['qualityStatusId']],
];
}
$similarProductsCacheItem->set($similiarProducts);
$similarProductsCacheItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
$cache->save($similarProductsCacheItem);
return $similiarProducts;
} else {
return $similarProductsCacheItem->get();
}
}
/**
* @param Request $request
* @param $language
* @param $productId
* @param $translator
* @return bool|\Symfony\Component\Form\FormView
*/
public function getProductDetailReviewForm(Request $request, $language, $productId, $translator)
{
// Reviews
if ($this->getLoginHelper($request)->isLoggedIn()) {
$review = new Review();
$customer = $this->getLoginHelper($request)->getLoggedInCustomer();
$form = $this->createForm(ReviewType::class, $review, [
'locale' => $request->getLocale(),
]);
if ($customer) {
$name = $customer->getBusinessName();
if ($name == '') {
$name = $customer->getFirstName();
}
$form->get('name')->setData($name);
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getEntityManager();
$review->setName($form->get('name')->getData());
$review->setText($form->get('text')->getData());
$review->setStars($form->get('stars')->getData());
$review->setLanguage($language);
$review->setType(Review::TYPE_PRODUCT);
$review->setApproved(0);
$productObject = $entityManager->getRepository(Product::class)->findOneById($productId);
$review->setProduct($productObject);
if ($customer) {
$review->setCustomer($customer);
}
$entityManager->persist($review);
// Upload Files
$fileCount = 0;
$subDirectory = 'survey-images';
$addedSurveyMedias = [];
$files = $request->files->get('reviewImages');
foreach ($files as $file) {
$response = $this->uploadFile($file, $subDirectory, ['image/jpeg', 'image/jpg', 'image/png']);
if ($response && $fileCount < 3) {
$surveyMedia = new SurveyMedia();
$surveyMedia->setOrder(null);
$surveyMedia->setDomain($customer->getDomain());
$surveyMedia->setFilename($response['filename']);
$surveyMedia->setDirectory('uploads/' . $subDirectory);
$surveyMedia->setMimeType($response['mimeType']);
$entityManager->persist($surveyMedia);
$addedSurveyMedias[] = $surveyMedia;
$fileCount++;
}
}
$entityManager->flush();
// Connect Survey Media to Review
if (!empty($addedSurveyMedias)) {
$centralisUser = $entityManager->getRepository(User::class)->findOneById(User::CENTRALIS_USER_ID);
foreach ($addedSurveyMedias as $surveyMedia) {
$reviewSurveyMedia = new ReviewSurveyMedia();
$reviewSurveyMedia->setReview($review);
$reviewSurveyMedia->setSurveyMedia($surveyMedia);
$reviewSurveyMedia->setApproved(false);
$reviewSurveyMedia->setCreatedBy($centralisUser);
}
$entityManager->persist($reviewSurveyMedia);
}
$entityManager->flush();
$this->addFlash(
'successReview',
$translator->trans('Thank you for your review. It has been submitted to the webmaster for approval')
);
}
return $form->createView();
}
return false;
}
/**
* @param int $productId
* @param CacheItemPoolInterface $cache
* @param Domain $domain
* @param Request $request
* @param ProductHelper $productHelper
* @return array
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function getRecommendedProducts(int $productId, CacheItemPoolInterface $cache, Domain $domain, Request $request, ProductHelper $productHelper)
{
$recommendedProductsCacheKey = ProductHelper::getRecommendedProductsCacheKey($domain->getId(), $request->getLocale(), $productId);
$recommendedProductsCacheItem = $cache->getItem($recommendedProductsCacheKey);
if (!$recommendedProductsCacheItem->isHit()) {
$entityManager = $this->getEntityManager();
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
$productEntity = $entityManager->getRepository(Product::class)->findOneById($productId);
$recommendedProducts = [];
foreach ($productHelper->getRecommendedProducts($productEntity, $domain, 24) as $recommendedProduct) {
$image = $placeholder;
if (is_object($recommendedProduct['images'])) {
$image = $this->getImage($recommendedProduct['images'], 'product/' . $recommendedProduct['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$recommendedProducts[] = [
'id' => $recommendedProduct['id'],
'image' => $image,
'labels' => $recommendedProduct['badges'],
'vendor' => $recommendedProduct['vendor'],
'vendorId' => $recommendedProduct['vendorId'],
'typeId' => $recommendedProduct['productTypeId'],
'title' => $recommendedProduct['title'],
'price' => $recommendedProduct['vatPrice'],
'attributes' => $recommendedProduct['attributes'],
'available' => $recommendedProduct['availableQty'],
'special' => ($recommendedProduct['isDiscounted'] ? $recommendedProduct['discountVatPrice'] : false),
'href' => $this->url($request)->link('product', [
'product_id' => $recommendedProduct['id'],
'isBazaar' => $recommendedProduct['isBazaar'] ?? 0
]),
'active' => $recommendedProduct['active'],
'timedSalesActive' => $recommendedProduct['timedSalesActive'],
'reviewCount' => $recommendedProduct['reviewCount'],
'reviewStars' => $recommendedProduct['reviewStars'],
'reviews' => $recommendedProduct['reviews'],
'freeShipping' => $recommendedProduct['freeShipping'],
'warrantyYear' => $this->getWarrantyForProductType($domain->getId(), $recommendedProduct['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($recommendedProduct),
];
}
$recommendedProductsCacheItem->set($recommendedProducts);
$recommendedProductsCacheItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
$cache->save($recommendedProductsCacheItem);
return $recommendedProducts;
} else {
return $recommendedProductsCacheItem->get();
}
}
/**
* @param Request $request
* @param array $filterData
* @param Domain $domain
*/
private function getProductListByFilter(Request $request, array $filterData, Domain $domain): array
{
$multiStore = $this->getMultiStoreHelper($request);
// Default Locale
$defaultLocale = $multiStore->getDefaultLocale();
foreach ($filterData as $key => $value) {
$filterData[$key] = $filterData[$key] === "" ? null : $filterData[$key];
}
$categoryInfo = $this->getEntityManager()->getRepository(CategoryPage::class)->findOneBy([
'id' => $filterData['filterCategoryId'],
'published' => true,
'type' => CategoryPage::CATEGORY_TYPE_PRODUCT,
]);
if (!$categoryInfo) {
return [];
}
$categoryProductTypes = $categoryInfo->getProductTypes();
$showWizard = false;
if ($filterData['start'] == 0 && $categoryProductTypes->count() >= 1) {
foreach ($categoryProductTypes as $categoryProductType) {
if (in_array($categoryProductType->getId(), [52, 60])) {
#$showWizard = true;
#$filterData['limit'] -= 1;
break;
}
}
} elseif ($filterData['start'] > 0 && $categoryProductTypes->count() >= 1) {
$filterData['start'] -= 1;
}
$products = [];
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
$results = $this->getProductHelper($request)->getStructuredDataByFilters($filterData);
foreach ($results as $result) {
$image = $placeholder;
if (is_object($result['images'])) {
$image = $this->getImage($result['images'], 'product/' . $result['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$products[] = [
'id' => $result['id'],
'code' => $result['code'],
'title' => ProductHelper::getHeadingTitle($result, true),
'vendor' => $result['vendor'],
'vendorId' => $result['vendorId'],
'labels' => $result['badges'],
'price' => $result['vatPrice'],
'priceWithCoupon' => $result['vatPriceWithCoupon'],
'couponCode' => $result['couponCode'],
'special' => ($result['isDiscounted'] ? $result['discountVatPrice'] : false),
'rawPrice' => $result['rawPrice'],
'rawDiscountPrice' => $result['rawDiscountPrice'],
'image' => $image,
'attributes' => $result['attributes'],
'attributesListTxt' => in_array($result['productTypeId'], [ProductType::PRODUCT_TYPE_ID_SMARTWATCH]) ? str_replace([' | ', 'Win 10 Pro'], [', ', 'Windows'], $result['shortDescription']) : str_replace([' | ', 'Win 10 Pro'], [', ', 'Windows'], $result['attributesListTxt']),
'available' => $result['availableQty'],
'type' => $result['productType'],
'typeId' => $result['productTypeId'],
'href' => $this->url($request)->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'],
'orderWaitingDays' => $result['orderWaitingDays'],
'warrantyYear' => $result['qualityStatusId'] == Product::QualityStatus_Bazaar ? 1 : $this->getWarrantyForProductType($domain->getId(), $result['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($result),
'isBestseller' => $result['isBestseller'] ?? false
];
}
if (in_array($filterData['filterCategoryId'], [639, 640, 641]) && !empty($products)) {
$products = array_merge([-1 => 'halloweenBanner'], $products);
}
if ($showWizard && !empty($products)) {
$products = array_slice($products, 0, 2, true) +
[
'w' => 'wizardBanner',
] +
array_slice($products, 2, count($products) - 1, true);
}
return $products;
}
/**
* @param Request $request
* @param array $filterData
* @param Domain $domain
*/
private function getNewProductListByFilter(Request $request, array $filterData, Domain $domain): array
{
$cache = $this->cache;
foreach ($filterData as $key => $value) {
$filterData[$key] = $filterData[$key] === "" ? null : $filterData[$key];
}
$filterDataCacheKey = md5(serialize($filterData)) . 'v2';
$filterDataCacheItem = $cache->getItem($filterDataCacheKey);
$products = [];
if ($filterDataCacheItem->isHit()) {
$products = $filterDataCacheItem->get();
} else {
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
$results = $this->getProductHelper($request)->getStructuredDataByFilters($filterData);
foreach ($results as $result) {
$image = $placeholder;
if (is_object($result['images'])) {
$image = $this->getImage($result['images'], 'product/' . $result['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$products[] = [
'id' => $result['id'],
'title' => ProductHelper::getHeadingTitle($result, $result['productTypeId'] == ProductType::PRODUCT_TYPE_ID_NOTEBOOK),
'vendor' => $result['vendor'],
'vendorId' => $result['vendorId'],
'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'],
'type' => $result['productType'],
'typeId' => $result['productTypeId'],
'href' => $this->url($request)->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'],
'orderWaitingDays' => $result['orderWaitingDays'],
'warrantyYear' => $result['qualityStatusId'] == Product::QualityStatus_Bazaar ? 1 : $this->getWarrantyForProductType($domain->getId(), $result['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($result),
'isBestseller' => $result['isBestseller'] ?? false
];
}
$filterDataCacheItem->set($products);
$filterDataCacheItem->expiresAfter(self::CACHE_LIFETIME_30_MINUTES);
$cache->save($filterDataCacheItem);
}
return $products;
}
/**
* @Route("/category/{categoryId}", name="category_show", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/category/{categoryId}", name="category_show_locale", defaults={"_locale":""})
* @param int $categoryId
* @param Request $request
* @return Response
* @throws \Exception
*/
public function listAction(int $categoryId, Request $request): Response
{
$canRegenerateCache = $request->get('regenerate-cache') == self::REGENERATE_CACHE_TOKEN ?? false;
$regenerateWholeSaleDomain = $canRegenerateCache && ($request->get('wholesale') ?? false);
if ($this->getEnvironment() == 'prod') {
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser([
'ip_address' => $_SERVER['REMOTE_ADDR'],
]);
});
}
// Entity Manager
$entityManager = $this->getEntityManager();
$data = [];
if ($request->get('_route_params')['slug'] != null) {
$categoryId = $entityManager->getRepository(Product::class)->checkRouteSlugForOtherCategoriesPages($request->get('_route_params')['slug'], $categoryId);
if ($request->get('_route_params')['slug'] == 'laptop/mobil-munkaallomasok') {
$baseUrl = $this->getEnvironment() == 'prod' ? 'https://www.furbify.hu' : 'https://furbify.dev.hu';
return $this->redirect("$baseUrl/mobil-munkaallomasok", 301);
}
}
$categoryInfo = $entityManager->getRepository(CategoryPage::class)->findOneBy([
'id' => $categoryId,
'published' => true,
'type' => CategoryPage::CATEGORY_TYPE_PRODUCT,
]);
$cache = $this->cache;
// Set back to products link for cart
$request->getSession()->set('cartBackToProductsLink', $this->url($request)->link('category', [
'path' => $categoryId,
'isBazaar' => $categoryInfo->isShowOnlyBazaar()
]));
if (!$categoryInfo) {
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
$multiStore = $this->getMultiStoreHelper($request);
$currentDate = new \DateTime();
$endDate = new \DateTime('2025-11-30');
$startDate = new \DateTime('2025-11-07');
$blackFridayDateIsActive = $startDate <= $currentDate && $currentDate <= $endDate;
if ($blackFridayDateIsActive && in_array($categoryInfo->getId(), [622, 218, 621, 217, 623, 219, 624])) {
return $this->redirect($this->url($request)->link('category_show') . '/black-friday');
}
// Multi-Store
$multiStore = $this->getMultiStoreHelper($request);
// Category Page Repository
$categoryPageRepository = $entityManager->getRepository(CategoryPage::class);
$categoryPageRepository->setSession($request->getSession());
// Use Alternative Category by Language
if ($multiStore->isLanguageSwitched()) {
$categoryInfo = $categoryPageRepository->getAlternativeCategoryByLanguage($categoryInfo);
if (is_null($categoryInfo)) {
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction', []);
}
}
$translator = $this->getTranslator();
$productHelper = $this->getProductHelper($request);
$seoUrlHelper = $this->getSeoUrlHelper($request);
$language = $multiStore->getLanguage();
$defaultLanguage = $multiStore->getDefaultLanguage();
// Different theme for bazaar category
if ( $categoryInfo->isShowOnlyBazaar() && in_array($multiStore->getDomain()->getId(), MultiStore::getRetailDomainIDs()) ) {
$data['isBazaar'] = true;
} else {
$data['isBazaar'] = false;
}
$data['customerTypeId'] = $request->getSession()->get('customerTypeId');
$data['categoryId'] = $categoryId;
$domainId = $regenerateWholeSaleDomain ? Domain::getRetailWholesaleDomainPairs()[$multiStore->getDomainId()] : $multiStore->getDomainId();
$domain = $entityManager->getRepository(Domain::class)->findOneById($domainId);
$parentCategoryId = $categoryInfo->getParentCategory() ? $categoryInfo->getParentCategory()->getId() : null;
$currentParentCategorySeoUrl = $entityManager->getRepository(SeoUrl::class)->findOneBy([
'query' => 'category_id=' . $parentCategoryId,
'language' => $defaultLanguage,
'archived' => false,
]);
// Redirect to current parent category if archived parent called
if (!is_null($currentParentCategorySeoUrl) && !str_contains($request->getPathInfo(), $currentParentCategorySeoUrl->getKeyWord())) {
$seoUrl = $entityManager->getRepository(SeoUrl::class)->findOneBy([
'query' => 'category_id=' . $categoryId,
'language' => $defaultLanguage,
'archived' => false,
]);
$filters = $request->query->all();
if ($seoUrl) {
$url = $request->getSchemeAndHttpHost() . '/' . $currentParentCategorySeoUrl->getKeyWord() . '/' . $seoUrl->getKeyword();
if (count($filters) > 0) {
$filters = substr($request->getRequestUri(), strPos($request->getRequestUri(), '?'));
$url .= $filters;
}
return $this->redirect($url, 301);
}
}
$reGenerateCache = $canRegenerateCache || $regenerateWholeSaleDomain;
/**
* @var PageMeta $categoryMeta
*/
$categoryMeta = $categoryInfo->getMetaByLanguage($language);
$showPopularProducts = $categoryInfo->isShowPopularProducts();
$additionalSeoTitle = '';
$indexable = $categoryInfo->isIndexable();
if (!$categoryMeta) {
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
// Filter ProductType ->
if ($request->get('fpt') || ($request->get('sfpt') && is_numeric($request->get('sfpt')))) {
$filterProductType = $request->get('fpt') ?? (int)$request->get('sfpt');
$showPopularProducts = false;
$indexable = false;
} else {
$filterProductType = null;
}
// Filter Vendor ->
if ($request->get('fv')) {
$filterVendor = $request->get('fv');
$showPopularProducts = false;
$indexable = false;
} else {
$filterVendor = null;
}
// Filter Attribute ->
if ($request->get('fa')) {
$filterAttribute = $request->get('fa');
$showPopularProducts = false;
$indexable = false;
} else {
$filterAttribute = null;
}
// Filter Price ->
if ($request->get('fp')) {
$currency = $domain->getCurrency();
$filterPrice = explode('-', $request->get('fp'));
if (!empty($filterPrice[0])) {
$filterPriceMin = floor((float)$filterPrice[0]);
} else {
$filterPriceMin = null;
}
if (!empty($filterPrice[1])) {
$filterPriceMax = ceil((float)$filterPrice[1]);
} else {
$filterPriceMax = null;
}
$showPopularProducts = false;
if ($defaultLanguage->getCode() == 'sk') {
$additionalSeoTitle .= ', ' . $translator->trans('from') . ' ' . $filterPriceMin . ' ' . $currency . ' ' . $translator->trans('to') . ' ' . $filterPriceMax . ' ' . $currency;
} else {
$additionalSeoTitle .= ', ' . $filterPriceMin . ' ' . $currency . ' - ' . $filterPriceMax . ' ' . $currency;
}
} else {
$filterPriceMin = $filterPriceMax = null;
}
//Filter CPU mark ->
if ($request->get('fcm')) {
$filterCpuMark = explode('-', $request->get('fcm'));
if (!empty($filterCpuMark[0])) {
$filterCpuMarkMin = (int)$filterCpuMark[0];
} else {
$filterCpuMarkMin = null;
}
if (!empty($filterCpuMark[1])) {
$filterCpuMarkMax = (int)$filterCpuMark[1];
} else {
$filterCpuMarkMax = null;
}
} else {
$filterCpuMarkMin = $filterCpuMarkMax = null;
}
$data['showOnlyDiscounted'] = $categoryInfo->isShowOnlyDiscounted();
// Filter Discounted
if ($request->get('fd') || $categoryInfo->isShowOnlyDiscounted()) {
$filterDiscounted = $categoryInfo->isShowOnlyDiscounted() ? 1 : (int)$request->get('fd');
$additionalSeoTitle .= ', ' . $translator->trans('discounted products');
$showPopularProducts = false;
} else {
$filterDiscounted = null;
}
// Filter Last Pieces ->
if ($request->get('fl')) {
$filterLastPieces = (int)$request->get('fl');
$additionalSeoTitle .= ', ' . $translator->trans('last pieces');
$showPopularProducts = false;
} else {
$filterLastPieces = null;
}
// Sort ->
$defaultSort = 'popular';
if ( $request->get('sort') ) {
$sort = $request->get('sort');
$indexable = false;
} else {
$sort = $defaultSort;
}
// Order ->
$defaultOrder = 'desc';
if ( $request->get('order') ) {
$order = $request->get('order');
$indexable = false;
} else {
/*if (in_array($categoryId, [460, 461, 462])) { // Cyber weekend
$order = 'desc';
} else {
$order = 'asc';
}*/
$order = $defaultOrder;
}
// Limit ->
$defaultLimit = 24;
if ( $request->get('limit') ) {
$limit = $request->get('limit');
$indexable = false;
} else {
$limit = $defaultLimit;
}
if ($request->query->count() > 0 && $request->query->count() != 1 && !is_null($request->query->get('page'))) {
$indexable = false;
}
// Page ->
if ($request->get('page')) {
$page = $request->get('page');
$additionalSeoTitle .= ', ' . $page . '.' . $translator->trans('page');
} else {
$page = 1;
}
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
$parentCategoryId = 0;
if ($categoryInfo->getParentCategory()) {
$categoryParentMeta = $categoryInfo->getParentCategory()->getMetaByLanguage($multiStore->getLanguage());
if ($categoryParentMeta) {
$data['breadcrumbs'][] = [
'text' => $categoryParentMeta->getTitle(),
'href' => $this->url($request)->link('category', [
'path' => $categoryInfo->getParentCategory()->getId(),
'isBazaar' => $categoryInfo->getParentCategory()->isShowOnlyBazaar()
]),
];
$parentCategoryId = $categoryInfo->getParentCategory()->getId();
}
}
$data['breadcrumbs'][] = [
'text' => $categoryMeta->getTitle(),
'href' => $this->url($request)->link('category', [
'path' => ($parentCategoryId > 0 ? $parentCategoryId . '_' : '') . $categoryId,
'isBazaar' => $categoryInfo->isShowOnlyBazaar()
]),
];
$data['seoTitle'] = trim($categoryMeta->getSeoTitle()) . $additionalSeoTitle;
if (empty($data['seoTitle'])) {
$data['seoTitle'] = $categoryMeta->getTitle();
}
$data['seoDescription'] = $categoryMeta->getSeoDesc() . ($additionalSeoTitle != '' ? ' ' . ucfirst(substr($additionalSeoTitle, 2)) . '.' : '');
$data['categoryId'] = $categoryInfo->getId();
$data['title'] = $categoryMeta->getTitle() . $additionalSeoTitle;
$data['description'] = str_replace(' ', ' ', $categoryMeta->getContent());
$data['socialShareImage'] = $this->getSocialShareImageHelper()->getImageUrl($categoryInfo->getSocialShareImage(), 'category');
$data['extraSeoDesc'] = $categoryMeta->getExtraSeoDesc();
$data['indexable'] = $indexable;
$data['categories'] = [];
$data['popularItems'] = [];
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_CART_THUMB_WIDTH, Image::PRODUCT_CART_THUMB_HEIGHT);
if ($showPopularProducts) {
$popularProductsCacheKey = 'category.popular.products.c.v7.' . $domainId . '.' . $language->getCode() . '.' . $categoryInfo->getId();
$popularProductsCacheItem = $cache->getItem($popularProductsCacheKey);
if (!$popularProductsCacheItem->isHit() || $reGenerateCache) {
$popularItems = $productHelper->getPopularItemsByCategory($categoryId);
foreach ($popularItems as $popularItem) {
$image = $mobileImage = $placeholder;
if (is_object($popularItem['images'])) {
$image = $mobileImage = $this->getImage($popularItem['images'], 'product/' . $popularItem['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$shortDescription = mb_strlen($popularItem['shortDescription']) > 88 ? mb_substr($popularItem['shortDescription'], 0, 88) . '...' : $popularItem['shortDescription'];
$data['popularItems'][] = [
'id' => $popularItem['id'],
'image' => $image,
'mobileImage' => $mobileImage,
'vendor' => $popularItem['vendor'],
'title' => $popularItem['title'],
'description' => str_replace(' | ', ', ', $shortDescription),
'quantity' => $popularItem['availableQty'],
'price' => $popularItem['vatPrice'],
'special' => ($popularItem['isDiscounted'] ? $popularItem['discountVatPrice'] : false),
'href' => $this->url($request)->link('product', [
'product_id' => $popularItem['id'],
'isBazaar' => $popularItem['isBazaar'] ?? 0
]),
'active' => $popularItem['active'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($popularItem),
];
}
$popularProductsCacheItem->set($data['popularItems']);
$popularProductsCacheItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
$cache->save($popularProductsCacheItem);
} else {
$data['popularItems'] = $popularProductsCacheItem->get();
}
}
$productTypes = [];
//sale filter change for the other category
if (in_array($categoryInfo->getId(), CategoryPage::SALE_CATEGORY_PAGES)
&& !is_null($filterProductType)
&& $filterProductType == ProductType::PRODUCT_TYPE_ID_OTHER)
{
foreach ($categoryInfo->getProducts() as $product) {
$productType = $product->getType();
if (in_array($productType->getId(), ProductType::getSaleProductTypeFilterTypes())) {
continue;
}
if (!isset($productTypes[$productType->getId()])) {
$productTypes[$productType->getId()] = $productType->getId();
}
}
$filterProductType = implode(',', $productTypes);
}
$filterData = [
'domainId' => $domainId,
'filterCategoryId' => $categoryInfo->getId(),
'filterProductType' => $filterProductType,
'filterVendor' => $filterVendor,
'filterAttribute' => $filterAttribute,
'filterPriceMin' => $filterPriceMin,
'filterPriceMax' => $filterPriceMax,
'filterCpuMarkMin' => $filterCpuMarkMin,
'filterCpuMarkMax' => $filterCpuMarkMax,
'filterDiscounted' => $filterDiscounted,
'filterLastPieces' => $filterLastPieces,
'sort' => $sort,
'order' => $order,
'start' => ($page - 1) * $limit,
'limit' => $limit,
'language' => $language->getCode(),
'cacheVer' => 3,
];
$data['pagination'] = [];
$data['categoryListLinks'] = [];
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
$total = $this->getProductHelper($request)->getTotalByFilters($filterData);
$arguments = [];
$arguments['path'] = $categoryInfo->getId();
if (!is_null($filterProductType)) {
$arguments['fpt'] = $filterProductType;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$arguments['page'] = '{page}';
$data['pagination'] = [
'total' => $total,
'page' => $page,
'limit' => $limit,
'moreButton' => true,
'url' => $this->url($request)->link('category', $arguments),
];
if ($page == 1) {
$arguments['page'] = 2;
$data['categoryListLinks']['next'] = $this->url($request)->link('category', $arguments);
}
if ($page > 1) {
if ($page == 2) {
unset($arguments['page']);
} else {
$arguments['page'] = $page - 1;
}
$data['categoryListLinks']['prev'] = $this->url($request)->link('category', $arguments);
if ($data['pagination']['total'] > 0 && $page < round($data['pagination']['total'] / $data['pagination']['limit'], PHP_ROUND_HALF_UP)) {
$arguments['page'] = $page + 1;
$data['categoryListLinks']['next'] = $this->url($request)->link('category', $arguments);
}
}
// 404 Page if Page Number exceeded
if ($page != 1 && $page > ceil($total / $limit)) {
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction', []);
}
$filterDataForBuildingFilterOptions = $filterData;
// Avoiding cache create for $filtersCacheKey in every page value change
unset($filterDataForBuildingFilterOptions['start']);
unset($filterDataForBuildingFilterOptions['limit']);
unset($filterDataForBuildingFilterOptions['sort']);
unset($filterDataForBuildingFilterOptions['order']);
$filterDataForBuildingFilterOptionsForFilter = $filterDataForBuildingFilterOptions;
unset($filterDataForBuildingFilterOptions['filterProductType']);
unset($filterDataForBuildingFilterOptions['filterVendor']);
unset($filterDataForBuildingFilterOptions['filterPriceMin']);
unset($filterDataForBuildingFilterOptions['filterPriceMax']);
unset($filterDataForBuildingFilterOptions['filterDiscounted']);
unset($filterDataForBuildingFilterOptions['filterLastPieces']);
unset($filterDataForBuildingFilterOptions['filterAttribute']);
$filtersCacheKey = 'category.v18.' . $domainId . '.' . $language->getCode() . '.' . $categoryId . '.' . $total . md5(serialize($filterDataForBuildingFilterOptions));
$filtersCacheItem = $cache->getItem($filtersCacheKey);
if (!$filtersCacheItem->isHit() || $reGenerateCache) {
$filters = $this->getProductHelper($request)->buildFilterOptions($filterDataForBuildingFilterOptionsForFilter);
$filtersCacheItem->set($filters);
$filtersCacheItem->expiresAfter(self::CACHE_LIFETIME_3_DAYS);
$cache->save($filtersCacheItem);
} else {
$filters = $filtersCacheItem->get();
}
$data['filters'] = $filters;
// For product list ajax-request
$data['filterData'] = $filterData;
// Filter Action
$data['action'] = $this->url($request)->link('category', $arguments);
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
$data['filterProductType'] = [];
if (!is_null($filterProductType)) {
$data['filterProductType'] = explode(',', $filterProductType);
}
$data['filterVendor'] = [];
if (!is_null($filterVendor)) {
$data['filterVendor'] = explode(',', $filterVendor);
}
$data['filterAttribute'] = [];
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $attribute) {
$options = explode(',', $attribute);
foreach ($options as $option) {
array_push($data['filterAttribute'], $option);
}
}
}
if (!is_null($filterPriceMin)) {
$data['filterPriceMin'] = $filterPriceMin;
} else {
$data['filterPriceMin'] = false;
}
if (!is_null($filterPriceMax)) {
$data['filterPriceMax'] = $filterPriceMax;
} else {
$data['filterPriceMax'] = false;
}
if (!is_null($filterDiscounted)) {
$data['filterDiscounted'] = $filterDiscounted;
} else {
$data['filterDiscounted'] = false;
}
if (!is_null($filterLastPieces)) {
$data['filterLastPieces'] = $filterLastPieces;
} else {
$data['filterLastPieces'] = false;
}
// Arguments
$arguments = [];
$arguments['path'] = $categoryInfo->getId();
if (!is_null($filterProductType)) {
$arguments['fpt'] = $filterProductType;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$data['sort'] = $sort;
$data['order'] = $order;
$data['limit'] = $limit;
$data['defaultSort'] = $defaultSort;
$data['defaultOrder'] = $defaultOrder;
$data['defaultLimit'] = $defaultLimit;
$data['quality_info_link'] = $this->getQualityInfoLink($domainId, $seoUrlHelper);
$data['salesManager'] = [];
if ($data['customerTypeId'] == MultiStore::CUSTOMER_TYPE_WHOLESALE) {
$loggedInCustomer = $this->getLoginHelper($request)->getLoggedInCustomer();
$salesManager = $loggedInCustomer->getSalesManager();
if (!is_null($salesManager)) {
$data['salesManager']['id'] = $salesManager->getID();
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
} else {
$salesManager = $domain->getDefaultSalesManager();
if (!is_null($salesManager)) {
$data['salesManager']['id'] = $salesManager->getID();
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
}
$data['domainLanguageCode'] = $domain->getLanguage()->getCode();
if ($domain->getLanguage()->getCode() == 'hu') {
$data['salesManager']['phone'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
}
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
//-> Canonical Link
if (!is_null($categoryInfo->getParentCategory())) {
$canonicalUrl = $seoUrlHelper->link('category', [
'path' => $categoryInfo->getParentCategory()->getId() . '_' . $categoryId,
'isBazaar' => $categoryInfo->isShowOnlyBazaar()
]);
} else {
$canonicalUrl = $seoUrlHelper->link('category', [
'path' => $categoryId,
'isBazaar' => $categoryInfo->isShowOnlyBazaar()
]);
}
if ($canonicalUrl != $request->getUri()) {
$data['canonical_link'] = $canonicalUrl;
} else {
$data['canonical_link'] = '';
}
//<- Canonical Link
$data['heureka_reviews'] = '';
if ($multiStore->getCustomerTypeId() == MultiStore::CUSTOMER_TYPE_RETAIL && in_array($domainId, [Domain::DOMAIN_ID_RT_SK, Domain::DOMAIN_ID_RT_CZ])) {
$heureka_reviews_cache_key = 'categoryPage.heureka.reviews.V2';
$heureka_reviews_cache_item = $cache->getItem($heureka_reviews_cache_key);
if (!$heureka_reviews_cache_item->isHit() || $reGenerateCache) {
$reviews = $this->getHeurekaSiteReviews($domainId, 3);
$data['heureka_reviews'] = $reviews;
$heureka_reviews_cache_item->set($data['heureka_reviews']);
$heureka_reviews_cache_item->expiresAfter(self::CACHE_LIFETIME_1_DAY);
$cache->save($heureka_reviews_cache_item);
} else {
$data['heureka_reviews'] = $heureka_reviews_cache_item->get();
}
}
$flashSaleCacheKey = 'homepage.flash_sale_product.category.v1.' . $domainId . '.' . $language->getCode();
$flashSaleCacheItem = $cache->getItem($flashSaleCacheKey);
if ($flashSaleCacheItem->isHit()) {
$flashSaleProduct = $flashSaleCacheItem->get();
$active = false;
if (!empty($flashSaleProduct) && $flashSaleProduct['timedSalesEndDate']) {
$saleEnd = $flashSaleProduct['timedSalesEndDate'];
$date = $saleEnd['month'] . ' ' . $saleEnd['day'] . ' ' . $saleEnd['year'];
$saleEnd['month'] = date('m', strtotime($date));
$active = new \DateTime() <= (new \DateTime())->setDate($saleEnd['year'], $saleEnd['month'], $saleEnd['day'])->setTime($saleEnd['hour'], 0);
}
$data['flashSaleProduct'] = $active ? $flashSaleProduct : [];
} else {
$data['flashSaleProduct'] = $this->getHiglightedFlashSaleData($request, $domain);
$flashSaleCacheItem->set($data['flashSaleProduct']);
$flashSaleCacheItem->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($flashSaleCacheItem);
}
$filterCacheKey = $request->query->get('fa') ?
implode(',', $request->query->get('fa')) :
($request->query->get('fp') ? $request->query->get('fp') : '')
;
$filterFd = (int) $request->query->get('fd');
$filterFl = (int) $request->query->get('fl');
$filterFa118 = (isset($request->query->get('fa')[118]) && $request->query->get('fa')[118] == 926 ? 926 : 0);
// Header Categories
$headerCategoriesKey = "category.header_categories.v8.$categoryId.{$filterFd}_{$filterFl}_{$filterFa118}.$domainId.{$domain->getLanguage()->getId()}.{$language->getId()}.$filterCacheKey";
$headerCategoriesItem = $cache->getItem($headerCategoriesKey);
if ($headerCategoriesItem->isHit()) {
$data['header_categories'] = $headerCategoriesItem->get();
}
else {
$headerCategories = [];
if ( !in_array($categoryId, [186, 187, 197, 659, CategoryPage::UJVARI_FURDO_BANNER_SK, CategoryPage::UJVARI_FURDO_BANNER_HU, CategoryPage::UJVARI_FURDO_BANNER_CZ]) && !$categoryInfo->isShowOnlyBazaar() ) {
// SK
if ($domain->getLanguage()->getCode() == 'sk') {
// PC
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_PC) || in_array($categoryId, [16, 14, 17])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '4_14',
]),
'title' => $translator->trans('Workstations'),
'active' => $categoryId == 14,
'icon' => 'workstation-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '4_17',
]),
'title' => $translator->trans('Gamer PC'),
'active' => $categoryId == 17,
'icon' => 'gamer-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '4_177',
]),
'title' => $translator->trans('Tiny PCs'),
'active' => $categoryId == 177,
'icon' => 'mini-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '4_84',
]),
'title' => $translator->trans('All in one PC'),
'active' => $categoryId == 84,
'icon' => 'all-in-one-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '634',
]),
'title' => $translator->trans('Windows 10 PC'),
'active' => $categoryId == 634,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '578',
]),
'title' => $translator->trans('Windows 11 PC'),
'active' => $categoryId == 578,
'icon' => 'windows_11.svg',
],
];
}
// Notebook
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_NOTEBOOK) || in_array($categoryId, [113, 87, 21, 241, 244, 250])) {
$activeState = null;
if ($request->query->get('fa') && isset($request->query->get('fa')[12])) {
$activeState = $request->query->get('fa')[12];
}
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '630',
]),
'title' => $translator->trans('Windows 10 notebook'),
'active' => $categoryId == 630,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '573',
]),
'title' => $translator->trans('Windows 11 notebook'),
'active' => $categoryId == 573,
'icon' => 'windows_11.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 5,
]) . '?fa[12]=102,103,104,857,1107,1827,2064,3900,3904,3932,4011,4066,4074,4943',
'title' => $translator->trans('Notebook for work'),
'active' => $categoryId == 5 && $activeState == '102,103,104,857,1107,1827,2064,3900,3904,3932,4011,4066,4074,4943',
'icon' => 'notebook-na-pracu.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '113',
]),
'title' => $translator->trans('Workstation laptops'),
'active' => $categoryId == 113,
'icon' => 'workstation-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 5,
'fd' => 1,
]),
'title' => $translator->trans('Discounted laptops'),
'active' => $categoryId == 5 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '7',
]),
'title' => $translator->trans('Accessories'),
'active' => $categoryId == 7,
'icon' => 'furbify-komp-notebook-taska.jpg',
],
/*[
'href' => $seoUrlHelper->link('category', ['path' => 5]) . '?fa[12]=196,198,251,4009,674',
'title' => $translator->trans('For free time'),
'active' => $categoryId == 5 && $activeState == '196,198,251,4009,674',
'icon' => 'na-volny-cas.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => 5]) . '?fa[12]=4756,2111,609,1219,2183,5005,398,194,2332,2295,195',
'title' => $translator->trans('For travelling'),
'active' => $categoryId == 5 && $activeState == '4756,2111,609,1219,2183,5005,398,194,2332,2295,195',
'icon' => 'travel-laptop-2.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => 5]) . '?fp=154-500',
'title' => $translator->trans("It doesn't cost a whole paycheck"),
'active' => $categoryId == 5 && $request->query->get('fp') && $request->query->get('fp') == '154-500',
'icon' => 'notebook-do-500.svg'
], [
'href' => $seoUrlHelper->link('category', ['path' => 5]) . '?fp=501-3000',
'title' => $translator->trans('Well built'),
'active' => $categoryId == 5 && $request->query->get('fp') && $request->query->get('fp') == '501-3000',
'icon' => 'gold-stav.svg'
], [
'href' => $seoUrlHelper->link('category', ['path' => '244']),
'title' => 'Chromebook',
'active' => $categoryId == 244,
'icon' => 'chromebook.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '5_43']),
'title' => $translator->trans('Laptops for seniors'),
'active' => $categoryId == 43,
'icon' => 'senior-laptop.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '5_21']),
'title' => $translator->trans('Workstation notebooks'),
'active' => $categoryId == 21,
'icon' => 'office-laptop.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '250']), // Bazar (251)
'title' => $translator->trans('Bazaar'),
'active' => $categoryId == 250,
'icon' => 'bazar-quicklink.svg',
'withPadding' => TRUE
]*/
];
}
// Monitor
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_MONITOR) || in_array($categoryId, [41, 39, 38])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '6_41',
]),
'title' => 'Dell',
'active' => $categoryId == 41,
'icon' => 'dell_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '6_39',
]),
'title' => 'Samsung',
'active' => $categoryId == 39,
'icon' => 'samsung_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '6_38',
]),
'title' => 'HP',
'active' => $categoryId == 38,
'icon' => 'hp_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 6,
]) . '?fv=47',
'title' => 'Philips',
'active' => $categoryId == 6 && $request->query->get('fv') && $request->query->get('fv') == 47,
'icon' => 'philips_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 6,
]) . '?fv=32',
'title' => 'Lenovo',
'active' => $categoryId == 6 && $request->query->get('fv') && $request->query->get('fv') == 32,
'icon' => 'lenovo_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 6,
]) . '?fa[63]=632',
'title' => 'Full HD',
'active' => $categoryId == 6 && isset($request->query->get('fa')[63]) && $request->query->get('fa')[63] == 632,
'icon' => 'full_hd_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 6,
]) . '?fa[118]=926',
'title' => 'IPS panel',
'active' => $categoryId == 6 && isset($request->query->get('fa')[118]) && $request->query->get('fa')[118] == 926,
'icon' => 'ipslogo_quicklink_125x119.svg',
], /*[
'href' => $seoUrlHelper->link('category', [
'path' => '378',
]),
'title' => $translator->trans('Bazaar'),
'active' => $categoryId == 378,
'icon' => 'bazar-quicklink.svg',
'withPadding' => true,
],*/ [
'href' => $seoUrlHelper->link('category', [
'path' => 6,
'fd' => 1,
]),
'title' => $translator->trans('Discounted monitors'),
'active' => $categoryId == 6 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 581,
]),
'title' => $translator->trans('Touch monitors'), // 'Dotykové monitory',
'active' => $categoryId == 581,
'icon' => 'monitor_touchscreen.svg',
],
];
}
}
// HU
if ($domain->getLanguage()->getCode() == 'hu') {
// PC
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_PC) || in_array($categoryId, [54, 52, 55])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '48_52',
]),
'title' => $translator->trans('Workstations'),
'active' => $categoryId == 52,
'icon' => 'workstation-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '48_55',
]),
'title' => $translator->trans('Gamer PC'),
'active' => $categoryId == 55,
'icon' => 'gamer-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '48_178',
]),
'title' => $translator->trans('Tiny PCs'),
'active' => $categoryId == 178,
'icon' => 'mini-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '48_85',
]),
'title' => $translator->trans('All in one PC'),
'active' => $categoryId == 85,
'icon' => 'all-in-one-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '635',
]),
'title' => $translator->trans('Windows 10 PC'),
'active' => $categoryId == 635,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '577',
]),
'title' => $translator->trans('Windows 11 PC'),
'active' => $categoryId == 577,
'icon' => 'windows_11.svg',
],
];
}
// Notebook
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_NOTEBOOK) || in_array($categoryId, [112, 88, 60, 61, 240, 243, 249])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '631',
]),
'title' => $translator->trans('Windows 10 notebook'),
'active' => $categoryId == 631,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '574',
]),
'title' => $translator->trans('Windows 11 notebook'),
'active' => $categoryId == 574,
'icon' => 'windows_11.svg',
],[
'href' => $seoUrlHelper->link('category', [
'path' => '56_60',
]),
'title' => $translator->trans('Work laptops'),
'active' => $categoryId == 60,
'icon' => 'office-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '112',
]),
'title' => $translator->trans('Workstation laptop'),
'active' => $categoryId == 112,
'icon' => 'workstation-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 56,
'fd' => 1,
]),
'title' => $translator->trans('Discounted notebooks'),
'active' => $categoryId == 56 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '567',
]),
'title' => $translator->trans('Accessories'),
'active' => $categoryId == 567,
'icon' => 'furbify-komp-notebook-taska.jpg',
],
/* [
'href' => $seoUrlHelper->link('category', ['path' => '243']),
'title' => 'Chromebook',
'active' => $categoryId == 243,
'icon' => 'chromebook.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '56_76']),
'title' => $translator->trans('Laptops for seniors'),
'active' => $categoryId == 76,
'icon' => 'senior-laptop.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '249']),
'title' => $translator->trans('Bazaar') . ' / szépséghibás',
'active' => $categoryId == 249,
'icon' => 'bazar-quicklink.svg',
'withPadding' => TRUE
]*/
];
}
// Monitor
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_MONITOR) || in_array($categoryId, [75, 80, 79])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '78_75',
]),
'title' => 'Dell',
'active' => $categoryId == 75,
'icon' => 'dell_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '78_80',
]),
'title' => 'Samsung',
'active' => $categoryId == 80,
'icon' => 'samsung_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '78_79',
]),
'title' => 'HP',
'active' => $categoryId == 79,
'icon' => 'hp_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 78,
]) . '?fv=47',
'title' => 'Philips',
'active' => $categoryId == 78 && $request->query->get('fv') && $request->query->get('fv') == 47,
'icon' => 'philips_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 78,
]) . '?fv=32',
'title' => 'Lenovo',
'active' => $categoryId == 78 && $request->query->get('fv') && $request->query->get('fv') == 32,
'icon' => 'lenovo_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 78,
]) . '?fa[63]=632',
'title' => 'Full HD',
'active' => $categoryId == 78 && isset($request->query->get('fa')[63]) && $request->query->get('fa')[63] == 632,
'icon' => 'full_hd_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 78,
]) . '?fa[118]=926',
'title' => 'IPS panel',
'active' => $categoryId == 78 && isset($request->query->get('fa')[118]) && $request->query->get('fa')[118] == 926,
'icon' => 'ipslogo_quicklink_125x119.svg',
], /*[
'href' => $seoUrlHelper->link('category', [
'path' => '377',
]),
'title' => $translator->trans('Bazaar'),
'active' => $categoryId == 377,
'icon' => 'bazar-quicklink.svg',
'withPadding' => true,
],*/ [
'href' => $seoUrlHelper->link('category', [
'path' => 78,
'fd' => 1,
]),
'title' => $translator->trans('Discounted monitors'),
'active' => $categoryId == 78 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 580,
]),
'title' => 'Érintőképernyős monitor',
'active' => $categoryId == 580,
'icon' => 'monitor_touchscreen.svg',
],
];
}
}
// CZ
if ($domain->getLanguage()->getCode() == 'cz') {
// PC
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_PC) || in_array($categoryId, [128, 126, 129])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '122_126',
]),
'title' => $translator->trans('Workstations'),
'active' => $categoryId == 126,
'icon' => 'workstation-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '122_129',
]),
'title' => $translator->trans('Gamer PC'),
'active' => $categoryId == 129,
'icon' => 'gamer-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '122_179',
]),
'title' => $translator->trans('Tiny PCs'),
'active' => $categoryId == 179,
'icon' => 'mini-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '122_155',
]),
'title' => $translator->trans('All in one PC'),
'active' => $categoryId == 155,
'icon' => 'all-in-one-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '636',
]),
'title' => $translator->trans('Windows 10 PC'),
'active' => $categoryId == 636,
'icon' => 'windows_11.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '579',
]),
'title' => $translator->trans('Windows 11 PC'),
'active' => $categoryId == 579,
'icon' => 'windows_11.svg',
],
];
}
// Notebook
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_NOTEBOOK) || in_array($categoryId, [175, 157, 134, 242, 245, 251])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '632',
]),
'title' => $translator->trans('Windows 10 notebook'),
'active' => $categoryId == 630,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '575',
]),
'title' => $translator->trans('Windows 11 notebook'),
'active' => $categoryId == 575,
'icon' => 'windows_11.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '130_134',
]),
'title' => $translator->trans('Workstation notebooks'),
'active' => $categoryId == 134,
'icon' => 'office-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '130_175',
]),
'title' => $translator->trans('Workstation laptops'),
'active' => $categoryId == 175,
'icon' => 'workstation-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 130,
'fd' => 1,
]),
'title' => $translator->trans('Discounted laptops'),
'active' => $categoryId == 130 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
'withPadding' => true,
], [
'href' => $seoUrlHelper->link('category', [
'path' => '118',
]),
'title' => $translator->trans('Accessories'),
'active' => $categoryId == 118,
'icon' => 'furbify-komp-notebook-taska.jpg',
],
/* [
'href' => $seoUrlHelper->link('category', ['path' => '130_245']),
'title' => 'Chromebook',
'active' => $categoryId == 245,
'icon' => 'chromebook.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '130_154']),
'title' => $translator->trans('Laptops for seniors'),
'active' => $categoryId == 154,
'icon' => 'senior-laptop.png'
], [
'href' => $seoUrlHelper->link('category', ['path' => '130_251']),
'title' => $translator->trans('Bazaar'),
'active' => $categoryId == 251,
'icon' => 'bazar-quicklink.svg'
]*/
];
}
// Monitor
if ($this->categoryHasProductType($categoryInfo, ProductType::PRODUCT_TYPE_ID_MONITOR) || in_array($categoryId, [153, 151, 150])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '149_153',
]),
'title' => 'Dell',
'active' => $categoryId == 153,
'icon' => 'dell_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '149_151',
]),
'title' => 'Samsung',
'active' => $categoryId == 151,
'icon' => 'samsung_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '149_150',
]),
'title' => 'HP',
'active' => $categoryId == 150,
'icon' => 'hp_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 149,
]) . '?fv=47',
'title' => 'Philips',
'active' => $categoryId == 149 && $request->query->get('fv') && $request->query->get('fv') == 47,
'icon' => 'philips_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 149,
]) . '?fv=32',
'title' => 'Lenovo',
'active' => $categoryId == 149 && $request->query->get('fv') && $request->query->get('fv') == 32,
'icon' => 'lenovo_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 149,
]) . '?fa[63]=632',
'title' => 'Full HD',
'active' => $categoryId == 149 && isset($request->query->get('fa')[63]) && $request->query->get('fa')[63] == 632,
'icon' => 'full_hd_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 149,
]) . '?fa[118]=926',
'title' => 'IPS panel',
'active' => $categoryId == 149 && isset($request->query->get('fa')[118]) && $request->query->get('fa')[118] == 926,
'icon' => 'ipslogo_quicklink_125x119.svg',
], /*[
'href' => $seoUrlHelper->link('category', [
'path' => '379',
]),
'title' => $translator->trans('Bazaar'),
'active' => $categoryId == 379,
'icon' => 'bazar-quicklink.svg',
'withPadding' => true,
],*/ [
'href' => $seoUrlHelper->link('category', [
'path' => 149,
'fd' => 1,
]),
'title' => $translator->trans('Discounted monitors'),
'active' => $categoryId == 149 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 582,
]),
'title' => 'Dotykové monitory',
'active' => $categoryId == 582,
'icon' => 'monitor_touchscreen.svg',
],
];
}
}
if ($domain->getLanguage()->getCode() == 'en') {
// PC
if ($this->categoryHasProductType($categoryInfo, 60) || in_array($categoryId, [54, 52, 55])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '281',
]),
'title' => 'Workstation PC',
'active' => $categoryId == 281,
'icon' => 'workstation-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '284',
]),
'title' => 'Gaming PC',
'active' => $categoryId == 284,
'icon' => 'gamer-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '323',
]),
'title' => 'Mini PC',
'active' => $categoryId == 323,
'icon' => 'mini-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '310',
]),
'title' => 'All In One PC',
'active' => $categoryId == 310,
'icon' => 'komplet-pc.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '637',
]),
'title' => $translator->trans('Windows 10 PC'),
'active' => $categoryId == 637,
'icon' => 'windows_11.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '638',
]),
'title' => $translator->trans('Windows 11 PC'),
'active' => $categoryId == 638,
'icon' => 'windows_11.svg',
],
];
}
// Notebook
if ($this->categoryHasProductType($categoryInfo, 52) || in_array($categoryId, [112, 88, 60, 61, 240, 243, 249])) {
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '633',
]),
'title' => $translator->trans('Windows 10 notebook'),
'active' => $categoryId == 633,
'icon' => 'windows_10.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '576',
]),
'title' => $translator->trans('Windows 11 notebook'),
'active' => $categoryId == 576,
'icon' => 'windows_11.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '346',
]),
'title' => 'Workstation laptop',
'active' => $categoryId == 346,
'icon' => 'workstation-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '291',
]),
'title' => 'Gaming laptop',
'active' => $categoryId == 291,
'icon' => 'gamer-laptop.png',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 285,
'fd' => 1,
]),
'title' => 'Laptop Sale',
'active' => $categoryId == 285 && $request->query->get('fd') == 1,
'icon' => 'sale_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '273',
]),
'title' => $translator->trans('Accessories'),
'active' => $categoryId == 273,
'icon' => 'furbify-komp-notebook-taska.jpg',
],
];
}
if ($this->categoryHasProductType($categoryInfo, 44) || in_array($categoryId, [75, 80, 79])) { // Monitor
$headerCategories = [
[
'href' => $seoUrlHelper->link('category', [
'path' => '488',
]),
'title' => 'Samsung',
'active' => $categoryId == 488,
'icon' => 'samsung_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '490',
]),
'title' => 'Dell',
'active' => $categoryId == 490,
'icon' => 'dell_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => '487',
]),
'title' => 'HP',
'active' => $categoryId == 487,
'icon' => 'hp_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 304,
]) . '?fv=47',
'title' => 'Philips',
'active' => $categoryId == 304 && $request->query->get('fv') && $request->query->get('fv') == 47,
'icon' => 'philips_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 304,
]) . '?fv=32',
'title' => 'Lenovo',
'active' => $categoryId == 304 && $request->query->get('fv') && $request->query->get('fv') == 32,
'icon' => 'lenovo_logo_quicklink_125x119.svg',
], [
'href' => $seoUrlHelper->link('category', [
'path' => 304,
]) . '?fa[63]=632',
'title' => 'Monitor Sale',
'active' => $categoryId == 304 && isset($request->query->get('fa')[63]) && $request->query->get('fa')[63] == 632,
'icon' => 'sale_quicklink_125x119.svg',
],
];
}
}
}
$data['header_categories'] = $headerCategories;
$headerCategoriesItem->set($data['header_categories']);
$headerCategoriesItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($headerCategoriesItem);
}
if (in_array($categoryId, CategoryPage::SALE_CATEGORY_PAGES)) {
$headerProductTypesKey = "category.header_product_types.{$categoryId}.{$domain->getId()}";
$headerProductTypesItem = $cache->getItem($headerProductTypesKey);
$salesSelectedProductType = null;
if ($request->query->has('sfpt') && is_numeric($request->get('sfpt'))) {
$salesSelectedProductType = $request->query->get('sfpt');
}
$productTypes = [
ProductType::PRODUCT_TYPE_ID_NOTEBOOK => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
'title' => $translator->trans('Notebooks'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_NOTEBOOK,
'icon' => 'theme/images/category/laptop-200x150.png',
],
ProductType::PRODUCT_TYPE_ID_PC => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_PC,
'title' => $translator->trans('Desktop PC'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_PC,
'icon' => '/theme/images/category/pc-set-200x150.png',
],
ProductType::PRODUCT_TYPE_ID_MONITOR => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_MONITOR,
'title' => $translator->trans('Monitors'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_MONITOR,
'icon' => '/theme/images/category/monitor-quicklink.png',
],
ProductType::PRODUCT_TYPE_ID_SMARTPHONE => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_SMARTPHONE,
'title' => $translator->trans('Mobile phones'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_SMARTPHONE,
'icon' => '/theme/images/category/mobile-200x150.png',
],
ProductType::PRODUCT_TYPE_ID_TABLET => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_TABLET,
'title' => $translator->trans('Tablets'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_TABLET,
'icon' => '/theme/images/category/tablet-200x150.png',
],
ProductType::PRODUCT_TYPE_ID_OTHER => [
'href' => '?sfpt=' . ProductType::PRODUCT_TYPE_ID_OTHER,
'title' => $translator->trans('Other'),
'active' => $salesSelectedProductType == ProductType::PRODUCT_TYPE_ID_OTHER,
'icon' => '/theme/images/category/docking-station-200x150px.png',
],
];
$data['header_productTypes'] = $productTypes;
}
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['contentBottom'] = $this->getContentBottom($request, 'category_show');
$data['showAdminLoginPanel'] = $request->getSession()->get('isAdminLogin');
// Sort By
$data['sortOrders'] = $this->getSortOrders($translator);
// Limit
$data['limits'] = [12, 24, 48, 96];
if ($reGenerateCache) {
$data['regenerateCache'] = self::REGENERATE_CACHE_TOKEN;
}
if (in_array($domain->getId(), [Domain::DOMAIN_ID_RT_SK, Domain::DOMAIN_ID_RT_CZ])) {
$heureka = new Heureka($this->twig);
$data['heurekaSak'] = $heureka->getSakForScript($domain->getLanguage()->getCode());
}
$data['isBlackFriday'] = false;
if ($blackFridayDateIsActive && in_array($categoryId, [642, 643, 644, 645]) ) {
$data['isBlackFriday'] = true;
}
return $this->render('AtechNetCoreBundle/Product/category.html.twig', $data);
}
/**
* @Route("/latest", name="latest_products", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/latest", name="latest_products_locale", defaults={"_locale":""})
* @Route("/ujdonsagok", name="latest_products_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/ujdonsagok", name="latest_products_hu_locale", defaults={"_locale":""})
* @Route("/novinky", name="latest_products_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/novinky", name="latest_products_sk_locale", defaults={"_locale":""})
* @Route("/novinky", name="latest_products_cz", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/novinky", name="latest_products_cz_locale", defaults={"_locale":""})
* @Route("/latest", name="latest_products_en", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/latest", name="latest_products_en_locale", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function latestListAction(Request $request): Response
{
if ($this->kernel->getEnvironment() == 'dev')
{
ini_set('memory_limit', '1G');
}
$canRegenerateCache = $request->get('regenerate-cache') == self::REGENERATE_CACHE_TOKEN ?? false;
$regenerateWholeSaleDomain = $canRegenerateCache && ($request->get('wholesale') ?? false);
$entityManager = $this->getEntityManager();
$reGenerateCache = $canRegenerateCache || $regenerateWholeSaleDomain;
$request->getSession()->set('cartBackToProductsLink', $this->generateUrl('latest_products'));
$translator = $this->getTranslator();
$multiStore = $this->getMultiStoreHelper($request);
$seoUrlHelper = $this->getSeoUrlHelper($request);
$language = $multiStore->getLanguage();
$defaultLanguage = $multiStore->getDefaultLanguage();
$data['customerTypeId'] = $request->getSession()->get('customerTypeId');
$additionalSeoTitle = '';
$domainId = $regenerateWholeSaleDomain ? Domain::getRetailWholesaleDomainPairs()[$multiStore->getDomainId()] : $multiStore->getDomainId();
$domain = $entityManager->getRepository(Domain::class)->findOneById($domainId);
$indexable = null;
// Filter CategoryPage
$filterCategory = $request->get('filterCategory');
if ($filterCategory) {
$categoryInfo = $entityManager->getRepository(CategoryPage::class)->findOneById($filterCategory);
$indexable = $categoryInfo->isIndexable();
$data['categoryId'] = $filterCategory;
}
// Filter ProductType
if ($request->get('fpt')) {
$filterProductType = $request->get('fpt');
$indexable = false;
} else {
$filterProductType = null;
}
// Filter Vendor
if ($request->get('fv')) {
$filterVendor = $request->get('fv');
$indexable = false;
} else {
$filterVendor = null;
}
// Filter Attribute
if ($request->get('fa')) {
$filterAttribute = $request->get('fa');
$indexable = false;
} else {
$filterAttribute = null;
}
// Filter Price
if ($request->get('fp')) {
$currency = $domain->getCurrency();
$filterPrice = explode('-', $request->get('fp'));
if (!empty($filterPrice[0])) {
$filterPriceMin = floor((float)$filterPrice[0]);
} else {
$filterPriceMin = null;
}
if (!empty($filterPrice[1])) {
$filterPriceMax = ceil((float)$filterPrice[1]);
} else {
$filterPriceMax = null;
}
if ($defaultLanguage->getCode() == 'sk') {
$additionalSeoTitle .= ', ' . $translator->trans('from') . ' ' . $filterPriceMin . ' ' . $currency . ' ' . $translator->trans('to') . ' ' . $filterPriceMax . ' ' . $currency;
} else {
$additionalSeoTitle .= ', ' . $filterPriceMin . ' ' . $currency . ' - ' . $filterPriceMax . ' ' . $currency;
}
} else {
$filterPriceMin = $filterPriceMax = null;
}
// Filter Discounted
if ($request->get('fd')) {
$filterDiscounted = (int)$request->get('fd');
$additionalSeoTitle .= ', ' . $translator->trans('discounted products');
} else {
$filterDiscounted = null;
}
// Filter Last Pieces
if ($request->get('fl')) {
$filterLastPieces = (int)$request->get('fl');
$additionalSeoTitle .= ', ' . $translator->trans('last pieces');
} else {
$filterLastPieces = null;
}
// Sort
if ($request->get('sort')) {
$sort = $request->get('sort');
$indexable = false;
} else {
$sort = 'created';
}
// Order
if ($request->get('order')) {
$order = $request->get('order');
$indexable = false;
} else {
$order = 'desc';
}
// Limit
if ($request->get('limit')) {
$limit = $request->get('limit');
$indexable = false;
} else {
$limit = 24;
}
if ($request->query->count() > 0 && $request->query->count() != 1 && !is_null($request->query->get('page'))) {
$indexable = false;
}
// Page
if ($request->get('page')) {
$page = $request->get('page');
$additionalSeoTitle .= ', ' . $page . '.' . $translator->trans('page');
} else {
$page = 1;
}
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
$translator = $this->getTranslator();
$data['seoTitle'] = $translator->trans('Latest products') . $additionalSeoTitle;
if (empty($data['seoTitle'])) {
$data['seoTitle'] = $translator->trans('Latest products');
}
$data['seoDescription'] = $additionalSeoTitle != '' ? ' ' . ucfirst(substr($additionalSeoTitle, 2)) . '.' : '';
$data['title'] = $translator->trans('Latest products') . $additionalSeoTitle;
$data['indexable'] = $indexable;
$data['categories'] = [];
$data['popularItems'] = [];
$filterData = [
'domainId' => $domainId,
'filterCategories' => $filterCategory,
'filterProductType' => $filterProductType,
'filterVendor' => $filterVendor,
'filterAttribute' => $filterAttribute,
'filterPriceMin' => $filterPriceMin,
'filterPriceMax' => $filterPriceMax,
'filterDiscounted' => $filterDiscounted,
'filterLastPieces' => $filterLastPieces,
'sort' => $sort,
'order' => $order,
'start' => ($page - 1) * $limit,
'limit' => $limit,
'language' => $language->getCode(),
'cacheVer' => 3,
'isNewProductPage' => true,
];
// productTypes
$data['pagination'] = [];
$data['categoryListLinks'] = [];
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
$total = $this->getProductHelper($request)->getTotalByFilters($filterData);
$arguments = [];
$arguments['path'] = $filterCategory;
$arguments['isBazaar'] = $categoryInfo->isShowOnlyBazaar();
if (!is_null($filterCategory)) {
$arguments['filterCategory'] = $filterCategory;
}
if (!is_null($filterProductType)) {
$arguments['fpt'] = $filterProductType;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$arguments['page'] = '{page}';
$data['pagination'] = [
'total' => $total,
'page' => $page,
'limit' => $limit,
'moreButton' => true,
'url' => $this->url($request)->link('category', $arguments),
];
if ($page == 1) {
$arguments['page'] = 2;
$data['categoryListLinks']['next'] = $this->url($request)->link('category', $arguments);
}
if ($page > 1) {
if ($page == 2) {
unset($arguments['page']);
} else {
$arguments['page'] = $page - 1;
}
$data['categoryListLinks']['prev'] = $this->url($request)->link('category', $arguments);
if ($data['pagination']['total'] > 0 && $page < round($data['pagination']['total'] / $data['pagination']['limit'], PHP_ROUND_HALF_UP)) {
$arguments['page'] = $page + 1;
$data['categoryListLinks']['next'] = $this->url($request)->link('category', $arguments);
}
}
// 404 Page if Page Number exceeded
if ($page != 1 && $page > ceil($total / $limit)) {
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
$filterDataForBuildingFilterOptions = $filterData;
$filterDataForBuildingFilterOptionsForFilter = $filterDataForBuildingFilterOptions;
unset($filterDataForBuildingFilterOptions['filterPriceMin']);
unset($filterDataForBuildingFilterOptions['filterPriceMax']);
unset($filterDataForBuildingFilterOptions['filterAttribute']);
$cache = $this->cache;
$filtersCacheKey = 'category.v4.' . $domainId . '.' . $language->getCode() . '.' . $filterCategory . '.' . $total . md5(serialize($filterDataForBuildingFilterOptions));
$filteredCacheItem = $cache->getItem($filtersCacheKey);
if (!$filteredCacheItem->isHit() || $reGenerateCache) {
$filters = $this->getProductHelper($request)->buildFilterOptions($filterDataForBuildingFilterOptionsForFilter);
$filteredCacheItem->set($filters);
$filteredCacheItem->expiresAfter(self::CACHE_LIFETIME_1_DAY);
$cache->save($filteredCacheItem);
} else {
$filters = $filteredCacheItem->get();
}
$data['filters'] = $filters;
// For product list ajax-request
$data['filterData'] = $filterData;
// Filter Action
$data['action'] = $this->url($request)->link('category', $arguments);
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
$data['filterProductType'] = [];
if (!is_null($filterProductType)) {
$data['filterProductType'] = explode(',', $filterProductType);
}
$data['filterVendor'] = [];
if (!is_null($filterVendor)) {
$data['filterVendor'] = explode(',', $filterVendor);
}
$data['filterAttribute'] = [];
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $attribute) {
$options = explode(',', $attribute);
foreach ($options as $option) {
array_push($data['filterAttribute'], $option);
}
}
}
if (!is_null($filterPriceMin)) {
$data['filterPriceMin'] = $filterPriceMin;
} else {
$data['filterPriceMin'] = false;
}
if (!is_null($filterPriceMax)) {
$data['filterPriceMax'] = $filterPriceMax;
} else {
$data['filterPriceMax'] = false;
}
if (!is_null($filterDiscounted)) {
$data['filterDiscounted'] = $filterDiscounted;
} else {
$data['filterDiscounted'] = false;
}
if (!is_null($filterLastPieces)) {
$data['filterLastPieces'] = $filterLastPieces;
} else {
$data['filterLastPieces'] = false;
}
// Arguments
$arguments = [];
$arguments['path'] = $filterCategory;
$arguments['isBazaar'] = $categoryInfo->isShowOnlyBazaar();
if (!is_null($filterCategory)) {
$arguments['filterCategory'] = $filterCategory;
}
if (!is_null($filterProductType)) {
$arguments['fpt'] = $filterProductType;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$data['sort'] = $sort;
$data['order'] = $order;
$data['limit'] = $limit;
$data['quality_info_link'] = $this->getQualityInfoLink($domainId, $seoUrlHelper);
$data['salesManager'] = [];
if ($data['customerTypeId'] == MultiStore::CUSTOMER_TYPE_WHOLESALE) {
$loggedInCustomer = $this->getLoginHelper($request)->getLoggedInCustomer();
$salesManager = $loggedInCustomer->getSalesManager();
if (!is_null($salesManager)) {
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
}
$data['domainLanguageCode'] = $domain->getLanguage()->getCode();
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
//-> Canonical Link
$canonicalUrl = $seoUrlHelper->link('category', [
'path' => $filterCategory,
'isBazaar' => $categoryInfo->isShowOnlyBazaar()
]);
$data['canonical_link'] = $canonicalUrl != $request->getUri() ? $canonicalUrl : '';
//<- Canonical Link
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['contentBottom'] = $this->getContentBottom($request, 'category_show');
$data['showAdminLoginPanel'] = $request->getSession()->get('isAdminLogin');
// Sort By
$data['sortOrders'] = $this->getSortOrders($translator);
// Limit
$data['limits'] = [12, 24, 48, 96];
if ($reGenerateCache) {
$data['regenerateCache'] = self::REGENERATE_CACHE_TOKEN;
}
return $this->render('AtechNetCoreBundle/Product/latestList.html.twig', $data);
}
private function getQualityInfoLink($domainId, $seoUrlHelper)
{
$link = '';
switch ($domainId) {
case Domain::DOMAIN_ID_RT_SK:
case Domain::DOMAIN_ID_WS_SK:
$link = $seoUrlHelper->link('page', [
'static_id' => 11,
]);
break;
case Domain::DOMAIN_ID_RT_HU:
case Domain::DOMAIN_ID_WS_HU:
$link = $seoUrlHelper->link('page', [
'static_id' => 27,
]);
break;
case Domain::DOMAIN_ID_RT_CZ:
case Domain::DOMAIN_ID_WS_CZ:
$link = $seoUrlHelper->link('page', [
'static_id' => 60,
]);
break;
default:
$link = '';
break;
}
return $link;
}
private function getSortOrders($translator): array
{
return [
[
'text' => $translator->trans('low to high'),
'value' => 'price-asc',
'sort' => 'price',
'order' => 'asc',
],
[
'text' => $translator->trans('high to low'),
'value' => 'price-desc',
'sort' => 'price',
'order' => 'desc',
],
[
'text' => $translator->trans('most popular'),
'value' => 'popular-desc',
'sort' => 'popular',
'order' => 'desc',
],
[
'text' => $translator->trans('Last added products'),
'value' => 'created-desc',
'sort' => 'created',
'order' => 'desc',
],
[
'text' => $translator->trans('By name'),
'value' => 'name-asc',
'sort' => 'name',
'order' => 'asc',
],
];
}
/**
* @Route("/product/get/list", name="product_list_ajax", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/list", name="product_list_ajax_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function listAjaxAction(Request $request): Response
{
$domain = $this->getMultiStoreHelper($request)->getDomain();
$filterData = $request->query->all();
if ($this->getEnvironment() == 'prod') {
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser([
'ip_address' => $_SERVER['REMOTE_ADDR'],
]);
});
}
// Filter Price
if ($filterData['fp']) {
$filterPrice = explode('-', $filterData['fp']);
if (!empty($filterPrice[0])) {
$filterPriceMin = floor((float)str_replace(' ', '', $filterPrice[0]));
} else {
$filterPriceMin = null;
}
if (!empty($filterPrice[1])) {
$filterPriceMax = floor((float)str_replace(' ', '', $filterPrice[1]));
} else {
$filterPriceMax = null;
}
} else {
$filterPriceMin = $filterPriceMax = null;
}
if (isset($filterData['fcm'])) {
$filterCpuMark = explode('-', $filterData['fcm']);
if (!empty($filterCpuMark[0])) {
$filterCpuMarkMin = $filterCpuMark[0];
} else {
$filterCpuMarkMin = null;
}
if (!empty($filterCpuMark[1])) {
$filterCpuMarkMax = $filterCpuMark[1];
} else {
$filterCpuMarkMax = null;
}
} else {
$filterCpuMarkMin = $filterCpuMarkMax = null;
}
$showOnlyDiscounted = $filterData['showOnlyDiscounted'];
// Filter Discounted
if ($filterData['fd'] != '' || $showOnlyDiscounted) {
$filterDiscounted = $showOnlyDiscounted ? 1 : (int)$filterData['fd'];
} else {
$filterDiscounted = null;
}
$isNewProductPage = (bool)isset($filterData['isNewProductPage']) ?: false;
$categoryId = $filterData[$isNewProductPage ? 'filterCategory' : 'filterCategoryId'];
if (isset($filterData['sfpt']) && is_numeric($filterData['sfpt'])) {
$filterProductType = $filterData['sfpt'] ?? '';
} else {
$filterProductType = $filterData['fpt'] ?? '';
}
$filterVendor = $filterData['fv'] ?? '';
$filterAttribute = $filterData['fa'] ? json_decode($filterData['fa'], true) : null;
$filterLastPieces = (int)$filterData['fl'] ? $filterData['fl'] : '';
$sort = 'price';
if ($filterData['sort']) {
if (in_array($filterData['sort'], ['price', 'created', 'name', 'popular'])) {
$sort = $filterData['sort'];
}
}
$order = 'asc';
if ($filterData['order']) {
if (in_array($filterData['order'], ['asc', 'desc'])) {
$order = $filterData['order'];
}
}
$limit = (int)$filterData['limit'] ?? 23;
$page = (int)$filterData['page'] ?? 1;
$canRegenerateCache = isset($filterData['regenerateCache']) && $filterData['regenerateCache'] == self::REGENERATE_CACHE_TOKEN ?? false;
$regenerateWholeSaleDomain = $canRegenerateCache && ($filterData['isWholesale'] ?? false);
$reGenerateCache = $canRegenerateCache || $regenerateWholeSaleDomain || $this->getEnvironment() == 'dev';
$productTypes = [];
//sale filter change for the other category
if (in_array($categoryId, CategoryPage::SALE_CATEGORY_PAGES)
&& !is_null($filterProductType)
&& $filterProductType == ProductType::PRODUCT_TYPE_ID_OTHER)
{
$categoryInfo = $this->getEntityManager()->getRepository(CategoryPage::class)
->findOneById($categoryId);
foreach ($categoryInfo->getProducts() as $product) {
$productType = $product->getType();
if (in_array($productType->getId(), ProductType::getSaleProductTypeFilterTypes())) {
continue;
}
if (!isset($productTypes[$productType->getId()])) {
$productTypes[$productType->getId()] = $productType->getId();
}
}
$filterProductType = implode(',', $productTypes);
if (empty($filterProductType)) {
$filterProductType = ProductType::PRODUCT_TYPE_ID_OTHER;
}
}
$filterData = [
'domainId' => $regenerateWholeSaleDomain ? Domain::getRetailWholesaleDomainPairs()[$domain->getId()] : $domain->getId(),
'filterCategoryId' => $categoryId,
'filterProductType' => $filterProductType,
'filterVendor' => $filterVendor,
'filterAttribute' => $filterAttribute,
'filterPriceMin' => $filterPriceMin,
'filterPriceMax' => $filterPriceMax,
'filterCpuMarkMin' => $filterCpuMarkMin,
'filterCpuMarkMax' => $filterCpuMarkMax,
'filterDiscounted' => $filterDiscounted,
'filterLastPieces' => $filterLastPieces,
'sort' => $sort,
'order' => $order,
'start' => ($page - 1) * $limit,
'limit' => $limit,
'language' => $domain->getLanguage()->getCode(),
'cacheVer' => 3,
];
if ($isNewProductPage) {
unset($filterData['filterCategoryId']);
$filterData['filterCategories'] = $categoryId;
}
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
$data['filterProductType'] = $filterProductType ? explode(',', $filterProductType) : [];
$data['filterVendor'] = $filterVendor ? explode(',', $filterVendor) : [];
$data['filterAttribute'] = [];
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $attribute) {
$options = explode(',', $attribute);
foreach ($options as $option) {
array_push($data['filterAttribute'], $option);
}
}
}
$data['filterPriceMin'] = $filterPriceMin ?? false;
$data['filterPriceMax'] = $filterPriceMax ?? false;
$data['filterDiscounted'] = $filterDiscounted ?? false;
$data['filterLastPieces'] = $filterLastPieces ?? false;
$data['products'] = [];
$cache = $this->cache;
$productsCacheKey = 'products.v16.' . $domain->getId() . '.' . $domain->getLanguage()->getCode() . '.' . $isNewProductPage . '.' . md5(serialize($filterData));
$productsCacheItem = $cache->getItem($productsCacheKey);
$productsCacheTimeKey = 'products.v16.' . $domain->getId() . '.' . $domain->getLanguage()->getCode() . '.' . $isNewProductPage . '.' . md5(serialize($filterData)) . '.time';
$productsCacheTimeItem = $cache->getItem($productsCacheTimeKey);
if (!$productsCacheItem->isHit() || $reGenerateCache) {
$data['products'] = $isNewProductPage ? $this->getNewProductListByFilter($request, $filterData, $domain) : $this->getProductListByFilter($request, $filterData, $domain);
$productsCacheItem->set($data['products']);
if ($categoryId == 659) {
$productsCacheItem->expiresAfter(self::CACHE_LIFETIME_15_MINUTES);
} else {
$productsCacheItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
}
$cache->save($productsCacheItem);
$productsCacheTimeItem->set((new \DateTime('now'))->getTimestamp());
$productsCacheTimeItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
$cache->save($productsCacheTimeItem);
} else {
$data['products'] = $productsCacheItem->get();
}
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
$arguments = [];
if ($filterData['sort'] != '') {
$arguments['sort'] = $filterData['sort'];
}
if ($filterData['filterProductType'] != '') {
$arguments['fpt'] = $filterData['filterProductType'];
}
if ($filterData['filterVendor'] != '') {
$arguments['fv'] = $filterData['filterVendor'];
}
if ($filterData['filterAttribute'] != '') {
foreach ($filterData['filterAttribute'] as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if ($filterData['filterPriceMin'] != '' && $filterData['filterPriceMax'] != '') {
$arguments['fp'] = $filterData['filterPriceMin'] . '-' . $filterData['filterPriceMax'];
} elseif ($filterData['filterPriceMin'] != '' && $filterData['filterPriceMax'] != '') {
$arguments['fp'] = $filterData['filterPriceMin'] . '-0';
} elseif ($filterData['filterPriceMin'] != '' && $filterData['filterPriceMax'] != '') {
$arguments['fp'] = '0-' . $filterData['filterPriceMax'];
}
if ($filterData['filterDiscounted'] != '') {
$arguments['fd'] = $filterData['filterDiscounted'];
}
if ($filterData['filterLastPieces'] != '') {
$arguments['fl'] = $filterData['filterLastPieces'];
}
if ($filterData['sort']) {
$arguments['sort'] = $sort;
}
if ($filterData['order'] != '') {
$arguments['order'] = $filterData['order'];
}
if ($filterData['limit'] != '') {
$arguments['limit'] = $filterData['limit'];
}
$arguments['page'] = '{page}';
$data['pagination'] = [
'total' => $this->getProductHelper($request)->getTotalByFilters($filterData),
'page' => $page,
'limit' => $arguments['limit'],
'moreButton' => true,
'url' => $this->url($request)->link('category', $arguments),
];
$data['showAdminLoginPanel'] = $request->getSession()->get('isAdminLogin');
// Last Update
if ($productsCacheTimeItem->isHit()) {
$timestamp = $productsCacheTimeItem->get();
$data['lastCacheUpdate'] = (new \DateTime())->setTimestamp($timestamp)->format('d.m.Y H:i');
}
return new JsonResponse($data);
}
/**
* @Route("/product/get/variants", name="product_variants", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/variants", name="product_variants_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function variantsAction(Request $request): JsonResponse
{
$filter = [];
$productId = 0;
if ($request->get('productId')) {
$productId = $request->get('productId');
}
$translator = $this->getTranslator();
$multiStore = $this->getMultiStoreHelper($request);
$cache = $this->cache;
$cacheKey = 'product.variations.v4.domain.' . $multiStore->getDomain()->getId() . '.' . (int)$productId;
$cacheItem = $cache->getItem($cacheKey);
$result = [];
if ($cacheItem->isHit() && false) {
$result = $cacheItem->get();
} else {
$product = $this->getEntityManager()->getRepository(Product::class)->find($productId);
if ($product) {
$filter['vendorId'] = $product->getVendor()->getId();
$filter['name'] = $product->getName();
$filter['typeId'] = $product->getType()->getId();
$filter['productId'] = $product->getId();
$filter['basePrice'] = $multiStore->getBasePrice();
$result = $this->getProductHelper($request)->getVariantsForFilter($this->getSeoUrlHelper($request), $translator, $filter);
$cacheItem->set($result);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_12_HOURS);
$cache->save($cacheItem);
}
}
return new JsonResponse($result);
}
/**
* @Route("/product/live/search", name="product_live_search", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/live/search", name="product_live_search_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function liveSearchAction(Request $request)
{
// JSON
$json = [];
// Search Term
if ($request->get('fs')) {
$filterSearch = trim($request->get('fs'));
} else {
$filterSearch = null;
}
// Stopwatch
$stopwatch = new Stopwatch();
// Debug
$json['debug'] = [];
// Start Event
$stopwatch->start('requirements');
// Entity Manager
$entityManager = $this->getEntityManager();
// Connecion
$connection = $entityManager->getConnection();
// System Translator
$translator = $this->getTranslator();
// Tokenizer
$tokenizer = $this->getSeoUrlHelper($request);
// Multi-Store
$multiStore = $this->getMultiStoreHelper($request);
// Cache
$cache = $this->cache;
// Domain
$cacheKey = SearchHelper::getDomainCacheKey($multiStore->getDomainId());
$cacheItem = $cache->getItem($cacheKey);
if ($cacheItem->isHit() && is_numeric(($cacheItem->get())->getId())) {
$domain = $cacheItem->get();
} else {
$domain = $entityManager->createQuery("SELECT d, l FROM AtechNetCoreBundle:Domain d JOIN d.language l WHERE d.id = :domain")
->setParameters([
'domain' => $multiStore->getDomainId(),
])
->getSingleResult();
$cacheItem->set($domain);
$cacheItem->expiresAfter(SearchHelper::CACHE_LIFETIME_7_DAYS);
$cache->save($cacheItem);
}
// Currency
$currency = $domain->getCurrency();
$precision = $domain->getPricePrecision();
// Language
$language = $domain->getLanguage();
// Search Helper
$searchHelper = new SearchHelper($entityManager, $tokenizer, $cache, $domain, $language);
// Limit
$limit = 5;
// Recommend
$recommend = false;
// Debug
$json['debug']['requirements'] = (string)$stopwatch->stop('requirements');
//-> Expression
// Start Event
$stopwatch->start('expression');
$i = 0;
$expressions = [];
$expression = strtok($filterSearch, ' ');
while ($expression !== false) {
$expressions[] = [
'expression' => $expression,
'slug' => $tokenizer->slug($expression),
'mark' => 'none',
'priority' => (++$i),
];
$expression = strtok(' ');
}
// Add Expression List to Helper
$searchHelper->setExpressions($expressions);
// Debug
$json['debug']['expression'] = (string)$stopwatch->stop('expression');
//<- Expression
//-> Initialize Search
// Start Debug Event
$stopwatch->start('initialize');
$searchHelper->initialize();
// Debug
$json['debug']['initialize'] = (string)$stopwatch->stop('initialize');
//<- Initialize Search
// Vendors
$vendors = $searchHelper->getVendors();
// Product Types
$productTypes = $searchHelper->getProductTypes();
// Products
$products = $searchHelper->getProducts();
//-> Categories
// Start Event
$stopwatch->start('category');
// Category Repository
$categoryPageRepository = $entityManager->getRepository(CategoryPage::class);
$categoryPageRepository->setSession($request->getSession());
// Categories
$categories = [];
$results = $connection->fetchAllAssociative("SELECT * FROM pages_category WHERE published = '1' AND domain_id = ?", [$domain->getId()], ['integer']);
foreach ($results as $result) {
// Skip non product category
if ((int)$result['type'] !== CategoryPage::CATEGORY_TYPE_PRODUCT) {
continue;
}
// Skip category with badge
if (!empty($result['badges'])) {
continue;
}
// Skip discounted category
if ((int)$result['show_only_discounted'] == 1) {
continue;
}
// Skip flash sale category
if ((int)$result['show_only_flash_sales'] == 1) {
continue;
}
// Skip bazaar category
if ((int)$result['show_only_bazaar'] == 1) {
continue;
}
// Skip category with product limitation
if ((int)$connection->fetchOne("SELECT COUNT(product_id) FROM category_pages_products WHERE category_page_id = ?", [$result['id']], ['integer']) > 0) {
continue;
}
// Get vendors of category
$categoryVendors = array_map(function ($categoryVendor) {
return (int)$categoryVendor['vendor_id'];
}, $connection->fetchAllAssociative("SELECT * FROM category_pages_vendors WHERE category_page_id = ?", [$result['id']], ['integer']));
// Get product types of category
$categoryProductTypes = array_map(function ($categoryProductType) {
return (int)$categoryProductType['product_type_id'];
}, $connection->fetchAllAssociative("SELECT * FROM category_pages_product_types WHERE category_page_id = ?", [$result['id']], ['integer']));
// Get meta data of category
$meta = $connection->fetchAssociative("SELECT title, link FROM pages_meta WHERE language_id = ? AND category_page_id = ?", [$language->getId(), $result['id']], ['integer', 'integer']);
if (!empty($meta) && (!empty($categoryVendors) || !empty($categoryProductTypes))) {
// Remove warranty from title
$title = trim(str_replace([
'2 év garanciával', '3 év garanciával', 'garanciával',
's 2-ročnou zárukou', 's 2 letou zárukou',
], '', $meta['title']));
// Translate Title
if ($multiStore->isLanguageSwitched()) {
// Base Categories
$alternativeCategoryId = SearchHelper::getAlternativeCategory($result['id'], $request->getLocale());
if (!is_null($alternativeCategoryId)) {
// Get meta data of alternative category
$alternativeMeta = $connection->fetchAssociative("SELECT title, link FROM pages_meta WHERE language_id = ? AND category_page_id = ?", [$multiStore->getLanguageId(), $alternativeCategoryId], ['integer', 'integer']);
if (!empty($alternativeMeta)) {
// Remove warranty from alternative title
$title = trim(str_replace([
'2 év garanciával', '3 év garanciával', 'garanciával',
's 2-ročnou zárukou', 's 2 letou zárukou',
], '', $alternativeMeta['title']));
}
}
// Everything else
else {
$categoryPage = $entityManager->getRepository(CategoryPage::class)->findOneById($result['id']);
if ($categoryPage) {
$alternativeCategoryPage = $categoryPageRepository->getAlternativeCategoryByLanguage($categoryPage);
if ($alternativeCategoryPage) {
$alternativeCategoryMeta = $alternativeCategoryPage->getMetaByLanguage($multiStore->getLanguage());
if ($alternativeCategoryMeta) {
// Remove warranty from alternative title
$title = trim(str_replace([
'2 év garanciával', '3 év garanciával', 'garanciával',
's 2-ročnou zárukou', 's 2 letou zárukou',
], '', $alternativeCategoryMeta->getTitle()));
}
}
}
}
}
// Priority
$priority = 0;
// Vendor Priority
$highestPriority = 0;
foreach ($categoryVendors as $vendorId) {
if (isset($vendors[$vendorId])) {
if ($highestPriority < $vendors[$vendorId]['priority']) {
$highestPriority = $vendors[$vendorId]['priority'];
}
}
}
$priority += $highestPriority;
// Product Type Priority
$highestPriority = 0;
foreach ($categoryProductTypes as $productTypeId) {
if (isset($productTypes[$productTypeId])) {
if ($highestPriority < $productTypes[$productTypeId]['priority']) {
$highestPriority = $productTypes[$productTypeId]['priority'];
}
}
}
$priority += $highestPriority;
$categories[(int)$result['id']] = [
'id' => (int)$result['id'],
'title' => $title,
'link' => $meta['link'],
'priority' => $priority,
'vendor' => $categoryVendors,
'productType' => $categoryProductTypes,
];
}
}
// Sort categories by priority
$sortOrder = [];
foreach ($categories as $key => $value) {
$sortOrder[$key] = $value['priority'];
}
array_multisort($sortOrder, SORT_DESC, SORT_NUMERIC, $categories);
// Debug
$json['debug']['category'] = (string)$stopwatch->stop('category');
//<- Categories
//-> Search
// Start Event
$stopwatch->start('search');
$search = $searchHelper->search();
// Recommend
if (empty($search['productType']['exact']) && empty($search['productType']['misspelled']) && empty($search['vendor']['exact']) && empty($search['vendor']['misspelled']) && (!empty($search['vendor']['startWith']) || !empty($search['productType']['startWith']))) {
$recommend = true;
}
// Debug
$json['debug']['search'] = (string)$stopwatch->stop('search');
//<- Search
//-> Collection of possible results
// Start Event
$stopwatch->start('possible-result');
// Possible Results
$possibleResults = $searchHelper->possibleResults($search);
// Featured Vendors
$featuredVendors = $searchHelper->getFeaturedVendors();
// Featured Product Types
$featuredProductTypes = $searchHelper->getFeaturedProductTypes();
// Found Products
$foundProducts = [];
// Index
$index = 0;
// Group by priority
$priorityGroups = [];
foreach ($possibleResults as $result) {
$priorityGroups[$result['priority']][] = $result;
}
// Highlight 3 discounted products
$highlightProducts = [];
foreach ($priorityGroups as $priorityGroup) {
foreach ($priorityGroup as $result) {
// Product ID
$productId = (int)$result['id'];
// Product Details
if (!empty($products['all'][$productId])) {
$product = $products['all'][$productId];
if ((int)$product['discounted'] == 1) {
$highlightProducts[] = [
'id' => (int)$result['id'],
'price' => (float)$product['discount'],
];
}
}
if (count($highlightProducts) == 3) {
break 2;
}
}
break;
}
// Sort highlighted discounted products
if (count($highlightProducts) > 1) {
$sortOrder = [];
foreach ($highlightProducts as $key => $value) {
$sortOrder[$key] = $value['price'];
}
array_multisort($sortOrder, SORT_ASC, SORT_NUMERIC, $highlightProducts);
}
// Found highlighted discounted Products
if (count($highlightProducts) > 0) {
$foundProducts = array_map(function ($product) {
return (int)$product['id'];
}, $highlightProducts);
}
// Special products
$specialProducts = count($highlightProducts);
// Fill with non-special products
foreach ($priorityGroups as $priorityGroup) {
foreach ($priorityGroup as $result) {
// Product ID
$productId = (int)$result['id'];
if (!in_array($productId, $foundProducts)) {
// Product Details
if (!empty($products['all'][$productId])) {
$product = $products['all'][$productId];
if (count($highlightProducts) == 3 && (int)$product['discounted'] == 0) {
array_push($foundProducts, $productId);
} elseif (count($highlightProducts) < 3 && $specialProducts < 3) {
array_push($foundProducts, $productId);
if ((int)$product['discounted'] == 1) {
$specialProducts++;
}
} elseif ((int)$product['discounted'] == 0) {
array_push($foundProducts, $productId);
}
}
}
if (count($foundProducts) == $limit) {
break 2;
}
}
}
// Debug
$json['debug']['possible-result'] = (string)$stopwatch->stop('possible-result');
//<- Collection of possible results
// Start Event
$stopwatch->start('popular-link');
// Popular Categories
$popularLinks = [];
if (!empty($possibleResults)) {
// Clone
$clonePossibleResults = $possibleResults;
// Index
$index = 0;
while (!empty($clonePossibleResults) && count($popularLinks) < $limit && ($limit * 3) >= $index) {
// Possible Product
$possibleProduct = array_shift($clonePossibleResults);
if (isset($products['all'][$possibleProduct['id']])) {
$product = $products['all'][$possibleProduct['id']];
foreach ($categories as $category) {
if (in_array((int)$product['vendor_id'], $category['vendor'])) {
$popularLinks[$category['id']] = $category;
}
}
$index++;
}
}
}
// Debug
$json['debug']['popular-link'] = (string)$stopwatch->stop('popular-link');
//> Blog & Static Pages
$stopwatch->start('blog-static-pages');
// Blog Posts
$foundBlogs = $json['blog'] = [];
if (!empty($search['page']['exact'])) {
$foundBlogs = array_filter($search['page']['exact'], function ($value) {
return $value['type'] == 'blog';
});
}
if (!empty($search['page']['approximate']) && count($foundBlogs) < 3) {
$foundBlogs = array_merge($foundBlogs, array_filter($search['page']['approximate'], function ($value) {
return $value['type'] == 'blog';
}));
}
if (!empty($search['page']['similar']) && count($foundBlogs) < 3) {
$foundBlogs = array_merge($foundBlogs, array_filter($search['page']['similar'], function ($value) {
return $value['type'] == 'blog';
}));
}
if (count($foundBlogs) > 0) {
$sortOrder = [];
foreach ($foundBlogs as $key => $value) {
$sortOrder[$key] = $value['priority'];
}
array_multisort($sortOrder, SORT_DESC, SORT_NUMERIC, $foundBlogs);
foreach ($foundBlogs as $blog) {
$json['blog'][$blog['blog_category_id']] = [
'title' => $blog['title'],
'href' => $this->url($request)->link('blog', [
'blog_id' => $blog['blog_category_id'],
]),
];
if (count($json['blog']) >= 3) {
break;
}
}
}
// Static Pages
$foundStatic = $json['static'] = [];
if (!empty($search['page']['exact'])) {
$foundStatic = array_filter($search['page']['exact'], function ($value) {
return $value['type'] == 'static';
});
}
if (!empty($search['page']['approximate']) && count($foundStatic) < 3) {
$foundStatic = array_merge($foundStatic, array_filter($search['page']['approximate'], function ($value) {
return $value['type'] == 'static';
}));
}
if (!empty($search['page']['similar']) && count($foundStatic) < 3) {
$foundStatic = array_merge($foundStatic, array_filter($search['page']['similar'], function ($value) {
return $value['type'] == 'static';
}));
}
if (count($foundStatic) > 0) {
$sortOrder = [];
foreach ($foundStatic as $key => $value) {
$sortOrder[$key] = $value['priority'];
}
array_multisort($sortOrder, SORT_DESC, SORT_NUMERIC, $foundStatic);
foreach ($foundStatic as $static) {
$json['static'][$static['static_page_id']] = [
'title' => $static['title'],
'href' => $this->url($request)->link('page', [
'static_id' => $static['static_page_id'],
]),
];
if (count($json['static']) >= 3) {
break;
}
}
}
$json['debug']['blog-static-pages'] = (string)$stopwatch->stop('blog-static-pages');
//< Blog & Static Pages
// Start Event
$stopwatch->start('results');
// Results
if (!empty($foundProducts)) {
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::LIVESEARCH_THUMB_WIDTH, Image::LIVESEARCH_THUMB_HEIGHT);
// Retrieve product data from cache
$products = $validate = $missing = [];
foreach ($foundProducts as $productId) {
// Cache
$productCacheKey = ProductHelper::getProductCacheKey($domain->getId(), $request->getLocale(), $productId);
$productCacheItem = $cache->getItem($productCacheKey);
if ($productCacheItem->isHit()) {
$products[$productId] = $productCacheItem->get();
$validate[] = $productId;
} else {
$products[$productId] = [];
$missing[] = $productId;
}
}
// Validate retrieved product data from cache
if (!empty($validate)) {
// Retrieve live data of products for validating
$productsLiveData = $entityManager->createQuery("SELECT p.id, p.available, pm.orderable, pm.active, pm.price, pm.discount, pm.discounted
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p AND pm.domain = :domain
WHERE p.id IN ( :productIds )")
->setParameters([
'domain' => $domain,
'productIds' => $validate,
])
->getResult();
// Compare cached and live data
foreach ($productsLiveData as $productLiveData) {
// Product ID
$productId = (int)$productLiveData['id'];
// Product Cache Data
if (empty($products[$productId])) {
continue;
}
$productCacheData = $products[$productId];
// Compare
$valid = $productCacheData['available'] == $productLiveData['available'] && $productCacheData['orderable'] == $productLiveData['orderable'] && $productCacheData['active'] == $productLiveData['active'] && (int)$productCacheData['rawPriceWoVAT'] == (int)$productLiveData['price'] && (int)$productCacheData['rawDiscountPriceWoVAT'] == (int)$productLiveData['discount'] && $productCacheData['isDiscounted'] == $productLiveData['discounted'];
if (!$valid) {
$products[$productId] = [];
$missing[] = $productId;
}
}
}
// Retrieve product data from database
if (!empty($missing)) {
$productsData = $this->getProductHelper($request)->getStructuredDataForProductsById($missing);
foreach ($productsData as $productData) {
// Data
$data = $this->buildProductViewData($productData, $request, $domain, $entityManager, $multiStore);
// Cache
$productCacheKey = ProductHelper::getProductCacheKey($domain->getId(), $request->getLocale(), $productData['id']);
$productCacheItem = $cache->getItem($productCacheKey);
$productCacheTimeKey = ProductHelper::getProductCacheKey($domain->getId(), $request->getLocale(), $productData['id']) . '.time';
$productCacheTimeItem = $cache->getItem($productCacheTimeKey);
$productCacheItem->set($data);
$productCacheItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheItem);
$productCacheTimeItem->set((new \DateTime('now'))->getTimestamp());
$productCacheTimeItem->expiresAfter(self::CACHE_LIFETIME_7_DAYS);
$cache->save($productCacheTimeItem);
// List
$products[$productData['id']] = $data;
}
}
foreach ($products as $result) {
$image = $placeholder;
if (!empty($result['images'])) {
$image = $result['images'][0]['additional'];
}
if ($multiStore->getBasePrice() == MultiStore::BASE_PRICE_NET) {
$price = number_format($result['rawPriceWoVAT'], $precision, ',', ' ') . ' ' . $currency;
$special = ($result['isDiscounted'] ? number_format($result['rawDiscountPriceWoVAT'], $precision, ',', ' ') . ' ' . $currency : false);
$priceInfo = $translator->trans('without VAT');
} else {
$price = number_format($result['price'], $precision, ',', ' ') . ' ' . $currency;
$special = ($result['isDiscounted'] ? number_format($result['special'], $precision, ',', ' ') . ' ' . $currency : false);
$priceInfo = '';
}
$json['products'][] = [
'id' => $result['product_id'],
'title' => $result['title'],
'vendor' => $result['brand'],
'shortDescription' => $result['description'],
'price' => $price,
'special' => $special,
'priceInfo' => $priceInfo,
'image' => $image,
'href' => $this->url($request)->link('product', [
'product_id' => $result['product_id'],
'isBazaar' => $result['isBazaar'] ?? 0
]),
'active' => $result['active'],
];
}
$json['popular'] = [];
foreach ($popularLinks as $category) {
$json['popular'][] = [
'title' => $category['title'],
'href' => '/' . $category['link'],
];
}
} // Not Found Product
else {
$json['try'] = [];
foreach ($categories as $category) {
if (count($category['vendor']) == 0) {
$json['try'][] = [
'title' => $category['title'],
'href' => '/' . $category['link'],
];
if (count($json['try']) >= $limit) {
break;
}
}
}
}
// Debug
$json['debug']['results'] = (string)$stopwatch->stop('results');
// Recommend
$json['recommend'] = $recommend;
// Total
$json['total'] = count($possibleResults);
return new JsonResponse($json);
}
/**
* @Route("/product-search", name="product_search", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product-search", name="product_search_locale", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function searchAction(Request $request): Response
{
$data = [];
// Search
if ($request->query->has('fs')) {
$filterSearch = trim($request->query->get('fs'));
} else {
$filterSearch = null;
}
// Filter Vendor
if ($request->query->has('fv')) {
$filterVendor = $request->query->get('fv');
} else {
$filterVendor = null;
}
// Filter Product Type
if ($request->query->has('ft')) {
$filterType = $request->query->get('ft');
} else {
$filterType = null;
}
// Filter Badge
if ($request->query->has('fb')) {
$filterBadge = $request->query->get('fb');
} else {
$filterBadge = null;
}
// Filter Attribute
if ($request->query->has('fa')) {
$filterAttribute = $request->query->get('fa');
} else {
$filterAttribute = null;
}
// Filter Group OR - Create OR groups by attribute ID
if ($request->get('fgo')) {
$filterGroupOr = $request->get('fgo');
} else {
$filterGroupOr = null;
}
// Filter Price
if ($request->query->has('fp')) {
$filterPrice = explode('-', $request->query->get('fp'));
if (!empty($filterPrice[0])) {
$filterPriceMin = floor((float)$filterPrice[0]);
} else {
$filterPriceMin = null;
}
if (!empty($filterPrice[1])) {
$filterPriceMax = ceil((float)$filterPrice[1]);
} else {
$filterPriceMax = null;
}
} else {
$filterPriceMin = $filterPriceMax = null;
}
// Filter Discounted
if ($request->query->has('fd')) {
$filterDiscounted = (int)$request->query->get('fd');
} else {
$filterDiscounted = null;
}
// Filter Last Pieces
if ($request->query->has('fl')) {
$filterLastPieces = (int)$request->query->get('fl');
} else {
$filterLastPieces = null;
}
// Sort
if ($request->get('sort')) {
$sort = $request->get('sort');
} else {
$sort = 'price';
}
// Order
if ($request->get('order')) {
$order = $request->get('order');
} else {
$order = 'DESC';
}
// Page
if ($request->get('page')) {
$page = $request->get('page');
} else {
$page = 1;
}
// Limit
if ($request->get('limit')) {
$limit = $request->get('limit');
} else {
$limit = 12;
}
// Restore fix filters
if ($request->query->has('_')) {
$filterRestore = true;
} else {
$filterRestore = false;
}
// Multi-Store
$multiStore = $this->getMultiStoreHelper($request);
$productHelper = $this->getProductHelper($request);
$translator = $this->getTranslator();
$seoUrl = $this->url($request);
$data['customerTypeId'] = $request->getSession()->get('customerTypeId');
//-> Breadcrumbs
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
// Breadcrumb Arguments
$arguments = [];
if (!is_null($filterSearch)) {
$arguments['fs'] = $filterSearch;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterType)) {
$arguments['ft'] = $filterType;
}
if (!is_null($filterBadge)) {
$arguments['fb'] = $filterBadge;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterGroupOr)) {
$arguments['fgo'] = $filterGroupOr;
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$data['breadcrumbs'][] = [
'text' => $translator->trans('Search'),
'href' => $seoUrl->link('search', $arguments),
];
//<- Breadcrumbs
// Domain
$domain = $multiStore->getDomain();
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
// Debug
$data['debug'] = [];
//-> Products
$data['products'] = [];
// Placeholder
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
// Stopwatch
$stopwatch = new Stopwatch();
// Entity Manager
$entityManager = $this->getEntityManager();
// Tokenizer
$tokenizer = $this->getSeoUrlHelper($request);
// Language
$language = $domain->getLanguage();
// Cache
$cache = $this->cache;
// Search Helper
$searchHelper = new SearchHelper($entityManager, $tokenizer, $cache, $domain, $language);
//-> Expression
// Start Event
$stopwatch->start('expression');
$i = 0;
$expressions = [];
$expression = strtok($filterSearch, ' ');
while ($expression !== false) {
$expressions[] = [
'expression' => $expression,
'slug' => $tokenizer->slug($expression),
'mark' => 'none',
'priority' => (++$i),
];
$expression = strtok(' ');
}
// Add Expression List to Helper
$searchHelper->setExpressions($expressions);
// Debug
$data['debug']['expression'] = (string)$stopwatch->stop('expression');
//<- Expression
//-> Apply filters if there are no expressions
// Save default filters for restore
if (!$filterRestore) {
$defaultFilters = [];
if (!is_null($filterVendor)) {
$defaultFilters['vendor'] = $filterVendor;
}
if (!is_null($filterType)) {
$defaultFilters['productType'] = $filterType;
}
if (!is_null($filterBadge)) {
$defaultFilters['badge'] = $filterBadge;
}
if (!is_null($filterPriceMin)) {
$defaultFilters['priceMin'] = $filterPriceMin;
}
if (!is_null($filterPriceMax)) {
$defaultFilters['priceMax'] = $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$defaultFilters['discounted'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$defaultFilters['lastPieces'] = $filterLastPieces;
}
if (!is_null($filterAttribute)) {
$defaultFilters['attribute'] = $filterAttribute;
}
$request->getSession()->set('searchDefaultFilter', $defaultFilters);
} // Restore default filters
else {
$defaultFilters = $request->getSession()->get('searchDefaultFilter');
}
if (!$searchHelper->hasExpressions()) {
// Filter by Vendors
if (!empty($defaultFilters['vendor'])) {
$values = array_map(function ($value) {
return (int)$value;
}, explode(',', $defaultFilters['vendor']));
if (!empty($values)) {
$searchHelper->addFilter('vendor', $values);
}
}
// Filter by Product Types
if (!empty($defaultFilters['productType'])) {
$values = array_map(function ($value) {
return (int)$value;
}, explode(',', $defaultFilters['productType']));
if (!empty($values)) {
$searchHelper->addFilter('productType', $values);
}
}
// Filter by Badges
if (!empty($defaultFilters['badge'])) {
$values = array_map(function ($value) {
return (string)$value;
}, explode(',', $defaultFilters['badge']));
if (!empty($values)) {
$searchHelper->addFilter('badge', $values);
}
}
// Filter by Price
if (!empty($defaultFilters['priceMin'])) {
$values = [(int)$defaultFilters['priceMin']];
if (!empty($values)) {
$searchHelper->addFilter('priceMin', $values);
}
}
if (!empty($defaultFilters['priceMax'])) {
$values = [(int)$defaultFilters['priceMax']];
if (!empty($values)) {
$searchHelper->addFilter('priceMax', $values);
}
}
// Filter discounted
if (!empty($defaultFilters['discounted'])) {
$values = [1];
if (!empty($values)) {
$searchHelper->addFilter('discounted', $values);
}
}
// Filter last pieces
if (!empty($defaultFilters['lastPieces'])) {
$values = [1];
if (!empty($values)) {
$searchHelper->addFilter('lastPieces', $values);
}
}
// Filter by Attribute
if (!empty($defaultFilters['attribute'])) {
foreach ($defaultFilters['attribute'] as $attributeId => $values) {
$values = array_map(function ($value) {
return (int)$value;
}, explode(',', $values));
if (!empty($values)) {
$searchHelper->addFilter('attribute_' . $attributeId, $values);
}
}
}
}
//<- Apply filters if there are no expressions
//-> Initialize Search
// Start Debug Event
$stopwatch->start('initialize');
$searchHelper->initialize();
// Debug
$json['debug']['initialize'] = (string)$stopwatch->stop('initialize');
//<- Initialize Search
// Vendors
$vendors = $searchHelper->getVendors();
// Product Types
$productTypes = $searchHelper->getProductTypes();
// Products
$products = $searchHelper->getProducts();
//-> Search
// Start Event
$stopwatch->start('search');
$search = $searchHelper->search();
// Debug
$data['debug']['search'] = (string)$stopwatch->stop('search');
//<- Search
//-> Collection of possible results
// Start Event
$stopwatch->start('possible-result');
// Possible Results
$possibleResults = $searchHelper->possibleResults($search);
// Attributes
$attributes = $searchHelper->getAttributes($possibleResults);
//-> Filter Possible Results
$filteredPossibleResults = $possibleResults;
// Selected Vendors
if (!empty($filterVendor)) {
$selectedVendors = array_map(function ($value) {
return (int)$value;
}, explode(',', $filterVendor));
}
// Selected Product Types
if (!empty($filterType)) {
$selectedProductTypes = array_map(function ($value) {
return (int)$value;
}, explode(',', $filterType));
}
foreach ($filteredPossibleResults as $key => $result) {
if (!empty($products['all'][$result['id']])) {
$product = $products['all'][$result['id']];
if (!empty($selectedVendors) && !in_array((int)$product['vendor_id'], $selectedVendors)) {
unset($filteredPossibleResults[$key]);
continue;
} elseif (!empty($selectedProductTypes) && !in_array((int)$product['type_id'], $selectedProductTypes)) {
unset($filteredPossibleResults[$key]);
continue;
}
if ($request->query->has('fl') && $request->query->get('fl') == 1 && (int)$product['available'] > 1) {
unset($filteredPossibleResults[$key]);
continue;
}
if ($request->query->has('fd') && $request->query->get('fd') == 1 && (int)$product['discounted'] != 1) {
unset($filteredPossibleResults[$key]);
continue;
}
if (!is_null($filterPriceMin) || !is_null($filterPriceMax)) {
if ($domain->getType() == Domain::TYPE_RETAIL) {
if ((int)$product['discounted'] == 1) {
$price = (float)$product['discount'] * (1 + ((int)$domain->getVat()) / 100);
} else {
$price = (float)$product['price'] * (1 + ((int)$domain->getVat()) / 100);
}
} else {
if ((int)$product['discounted'] == 1) {
$price = (float)$product['discount'];
} else {
$price = (float)$product['price'];
}
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax) && !($price >= $filterPriceMin && $price <= $filterPriceMax)) {
unset($filteredPossibleResults[$key]);
continue;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax) && !($price >= $filterPriceMin)) {
unset($filteredPossibleResults[$key]);
continue;
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax) && !($price <= $filterPriceMax)) {
unset($filteredPossibleResults[$key]);
continue;
}
}
if ($request->query->has('fa')) {
foreach ($request->query->get('fa') as $attributeId => $filters) {
$skip = true;
if (!empty($attributes[$attributeId]['options'])) {
$selectedOptions = explode(',', $filters);
foreach ($selectedOptions as $selectedOptionId) {
if (!empty($attributes[$attributeId]['options'][(int)$selectedOptionId]['products']) && in_array((int)$product['id'], $attributes[$attributeId]['options'][(int)$selectedOptionId]['products'])) {
$skip = false;
}
}
}
if ($skip) {
unset($filteredPossibleResults[$key]);
continue 2;
}
}
}
}
}
//<- Filter Possible Results
// Custom Sort
if ($request->query->has('sort') && $request->query->get('sort') != 'default') {
$sortOrderPriority = [];
$sortOrderCustom = [];
$flagCustom = SORT_STRING;
switch ($sort) {
case 'name':
foreach ($filteredPossibleResults as $key => $result) {
// ProductId
$productId = (int)$result['id'];
// Product Details
if (!empty($products['all'][$productId])) {
$product = $products['all'][$productId];
// Vendor
$vendor = '';
if (!empty($vendors[$product['vendor_id']]['name'])) {
$vendor = $vendors[$product['vendor_id']]['name'] . ' ';
}
$sortOrderCustom[$key] = $vendor . $product['name'];
}
$sortOrderPriority[$key] = $result['priority'];
}
$flagCustom = SORT_STRING;
break;
case 'price':
foreach ($filteredPossibleResults as $key => $result) {
// ProductId
$productId = (int)$result['id'];
// Product Details
if (!empty($products['all'][$productId])) {
$product = $products['all'][$productId];
if ((int)$product['discounted'] == 1) {
$sortOrderCustom[$key] = (float)$product['discount'];
} else {
$sortOrderCustom[$key] = (float)$product['price'];
}
}
$sortOrderPriority[$key] = $result['priority'];
}
$flagCustom = SORT_NUMERIC;
break;
}
if (strtoupper($order) == 'DESC') {
array_multisort($sortOrderCustom, SORT_DESC, $flagCustom, $sortOrderPriority, SORT_DESC, SORT_NUMERIC, $filteredPossibleResults);
} else {
array_multisort($sortOrderCustom, SORT_ASC, $flagCustom, $sortOrderPriority, SORT_DESC, SORT_NUMERIC, $filteredPossibleResults);
}
}
// Offset
$offset = ($page - 1) * $limit;
// Found Products
$foundProducts = array_map(function ($product) {
return (int)$product['id'];
}, array_slice($filteredPossibleResults, $offset, $limit));
// Debug
$data['debug']['possible-result'] = (string)$stopwatch->stop('possible-result');
//<- Collection of possible results
// Results
if (!empty($foundProducts)) {
$_results = $productHelper->getStructuredDataForProductsById($foundProducts, 'list');
// Re-sort results
$results = [];
foreach ($foundProducts as $productId) {
$results[] = $_results[$productId];
}
}
//-> Filters
$data['productTypes'] = $data['vendors'] = [];
$data['priceMin'] = $data['priceMax'] = false;
foreach ($possibleResults as $possibleResult) {
if (!empty($products['all'][$possibleResult['id']])) {
// Product
$product = $products['all'][$possibleResult['id']];
// Product Type
if (!empty($productTypes[$product['type_id']])) {
$data['productTypes'][$product['type_id']] = [
'id' => $productTypes[$product['type_id']]['id'],
'name' => $productTypes[$product['type_id']]['name'],
];
}
// Vendor
if (!empty($vendors[$product['vendor_id']])) {
$data['vendors'][$product['vendor_id']] = [
'id' => $vendors[$product['vendor_id']]['id'],
'name' => $vendors[$product['vendor_id']]['name'],
];
}
// Price
if ((int)$product['discounted'] == 1) {
$price = (float)$product['discount'];
} else {
$price = (float)$product['price'];
}
if ($data['priceMin'] === false || $data['priceMax'] === false) {
$data['priceMin'] = $data['priceMax'] = $price;
}
if ($data['priceMin'] > $price) {
$data['priceMin'] = $price;
}
if ($data['priceMax'] < $price) {
$data['priceMax'] = $price;
}
}
}
if (!empty($data['productTypes'])) {
$sortOrder = [];
foreach ($data['productTypes'] as $key => $value) {
$sortOrder[$key] = $value['name'];
}
array_multisort($sortOrder, SORT_ASC, SORT_STRING, $data['productTypes']);
}
if (!empty($data['vendors'])) {
$sortOrder = [];
foreach ($data['vendors'] as $key => $value) {
$sortOrder[$key] = $value['name'];
}
array_multisort($sortOrder, SORT_ASC, SORT_STRING, $data['vendors']);
}
// Qaulity
$data['qualityStatuses'] = [];
if (!empty($attributes[Attribute::ATTRIBUTE_ID_QUALITY]['options'])) {
foreach ($attributes[Attribute::ATTRIBUTE_ID_QUALITY]['options'] as $attributeOptionId => $attributeOption) {
$data['qualityStatuses'][] = [
'id' => $attributeOptionId,
'index' => $attributeOption['index'],
'title' => $attributeOption['title'],
];
}
$qualityOrder = [
AttributeOption::ATTRIBUTE_OPTION_QUALITY_GOLD,
AttributeOption::ATTRIBUTE_OPTION_QUALITY_SILVER,
AttributeOption::ATTRIBUTE_OPTION_QUALITY_BRONZ,
AttributeOption::ATTRIBUTE_OPTION_QUALITY_NEW,
AttributeOption::ATTRIBUTE_OPTION_QUALITY_BAZAAR
];
$sortOrder = [];
foreach ($data['qualityStatuses'] as $key => $value) {
$position = array_search($value['id'], $qualityOrder);
$sortOrder[$key] = $position === false ? count($qualityOrder) : $position;
}
array_multisort($sortOrder, SORT_ASC, $data['qualityStatuses']);
}
// Attribute Filters
$data['attributeFilters'] = [];
if (empty($selectedProductTypes) && !empty($data['productTypes']) && count($data['productTypes']) == 1) {
$productType = array_shift($data['productTypes']);
$selectedProductTypes = [$productType['id']];
}
if (!empty($selectedProductTypes)) {
$selectedProductType = array_shift($selectedProductTypes);
if (in_array($selectedProductType, [ProductType::PRODUCT_TYPE_ID_NOTEBOOK, ProductType::PRODUCT_TYPE_ID_PC, ProductType::PRODUCT_TYPE_ID_MONITOR, ProductType::PRODUCT_TYPE_ID_SMARTPHONE, ProductType::PRODUCT_TYPE_ID_SMARTWATCH, ProductType::PRODUCT_TYPE_ID_TABLET])) {
$attributeFilters = $searchHelper->getAttributeFiltersByProductType($selectedProductType);
foreach ($attributeFilters as $attributeId) {
// Skip Default Filters
if (isset($defaultFilters['attribute'][$attributeId])) {
continue;
}
// Skip Quality Filter
if ($attributeId == Attribute::ATTRIBUTE_ID_QUALITY) {
continue;
}
if (!empty($attributes[$attributeId]['options']) && count($attributes[$attributeId]['options']) > 1) {
$data['attributeFilters'][$attributeId] = [
'id' => $attributeId,
'title' => $attributes[$attributeId]['title'],
'options' => [],
];
foreach ($attributes[$attributeId]['options'] as $attributeOptionId => $attributeOption) {
$data['attributeFilters'][$attributeId]['options'][] = [
'id' => $attributeOptionId,
'index' => $attributeOption['index'],
'title' => $attributeOption['title'],
];
}
$sortOrder = [];
$sortType = SORT_STRING;
foreach ($data['attributeFilters'][$attributeId]['options'] as $key => $value) {
if (in_array($attributeId, [1, 12, 25, 45, 46, 63, 68, 141])) {
$sortOrder[$key] = $value['title'];
} else {
$sortOrder[$key] = $value['index'];
$sortType = SORT_NUMERIC;
}
}
array_multisort($sortOrder, SORT_DESC, $sortType, $data['attributeFilters'][$attributeId]['options']);
}
}
}
}
// Price
if ($multiStore->getBasePrice() != MultiStore::BASE_PRICE_NET) {
$data['priceMin'] = $data['priceMin'] * (1 + ($domain->getVat() / 100));
$data['priceMax'] = $data['priceMax'] * (1 + ($domain->getVat() / 100));
}
//<- Filters
// Results
if (!empty($results)) {
foreach ($results as $result) {
$image = $placeholder;
if (is_object($result['images'])) {
$image = $this->getImage($result['images'], 'product/' . $result['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$data['products'][] = [
'id' => $result['id'],
'title' => sprintf('%s - %s', $result['title'], $result['code']),
'vendor' => $result['vendor'],
'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' => $seoUrl->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'],
'typeId' => $result['productTypeId'],
'warrantyYear' => $this->getWarrantyForProductType($domain->getId(), $result['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($result),
'isBestseller' => $result['isBestseller']
];
}
} else {
$data['mainProducts'] = [];
$productHelper = $this->getProductHelper($request);
// Main Products based on homepage
$mainProductsCacheKey = 'search.main.products.v1.' . $domain->getId() . '.' . $language->getCode();
$mainProductsCacheItem = $cache->getItem($mainProductsCacheKey);
if ($mainProductsCacheItem->isHit()) {
$data['mainProducts'] = $mainProductsCacheItem->get();
} else {
$productGroupProductData = $productHelper->getProductGroupProducts('homepage.main', $domain);
$productGroupProducts = $productGroupProductData['productGroupProducts'];
$groupProductCodesAdded = $productGroupProductData['productGroupCodesAdded'];
$productsToDisplay = $productGroupProductData['productsToDisplay'];
$productGroupResults = $productHelper->getStructuredDataForProducts($productGroupProducts);
$data['mainProducts'] = $productHelper->convertStructuredDataToListViewData($this->url($request), $productGroupResults, $placeholder);
// Fill in
if (count($groupProductCodesAdded) < $productsToDisplay) {
$maxResults = $productsToDisplay - count($groupProductCodesAdded);
// Already Added
$productAlreadyAddedWhere = '';
if (count($groupProductCodesAdded) > 0) {
$productAlreadyAddedWhere = ' AND p.code NOT IN (' . implode(',', $groupProductCodesAdded) . ')';
}
$retailPage = $domain->getType() == 'retail';
$notebookSaleProducts = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.id = (
SELECT pm2.id FROM AtechNetCoreBundle:ProductMeta pm2 WHERE pm2.product = p.id AND pm2.domain = " . $domain->getId() . "
)
WHERE p.type = 52 AND pm.discounted = 1 AND pm.active = 1 AND p.available > 0 AND pm.orderable = 1 AND pm.listed = 1" . ($retailPage ? " AND p.qualityStatus != 9" : "") . $productAlreadyAddedWhere . "
ORDER BY pm.currentVatPrice ASC, p.updated DESC")
->setMaxResults($maxResults)
->getResult()
;
$results = $productHelper->getStructuredDataForProducts($notebookSaleProducts);
$data['mainProducts'] = array_merge($data['mainProducts'], $this->getProductHelper($request)->convertStructuredDataToListViewData($this->url($request), $results, $placeholder));
}
foreach ($data['mainProducts'] as $key => $value) {
$data['mainProducts'][$key]['warrantyYear'] = $value['qualityStatusId'] == Product::QualityStatus_Bazaar ? 1 : $this->getWarrantyForProductType($domain->getId(), $value['typeId'])['year'];
}
$mainProductsCacheItem->set($data['mainProducts']);
$mainProductsCacheItem->expiresAfter(self::CACHE_LIFETIME_15_MINUTES);
$cache->save($mainProductsCacheItem);
}
}
//<- Products
//-> Pagination
if (!empty($results)) {
// Arguments
$arguments = [];
if (!is_null($filterSearch)) {
$arguments['fs'] = $filterSearch;
}
if ($request->query->has('fv')) {
$arguments['fv'] = $filterVendor;
}
if ($request->query->has('ft')) {
$arguments['ft'] = $filterType;
}
if (!is_null($filterBadge)) {
$arguments['fb'] = $filterBadge;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterGroupOr)) {
$arguments['fgo'] = $filterGroupOr;
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
if ($filterRestore) {
$arguments['_'] = '1';
}
$arguments['page'] = '{page}';
$data['pagination'] = [
'total' => count($filteredPossibleResults),
'page' => $page,
'limit' => $limit,
'moreButton' => true,
'url' => urldecode($seoUrl->link('search', $arguments)),
];
} else {
$data['pagination'] = [];
}
//<- Pagination
// Filter Values
if (!is_null($filterSearch)) {
$data['filterSearch'] = $filterSearch;
} else {
$data['filterSearch'] = '';
}
if (!is_null($filterVendor)) {
$data['filterVendor'] = explode(',', $filterVendor);
} else {
$data['filterVendor'] = [];
}
if (!is_null($filterType)) {
$data['filterType'] = explode(',', $filterType);
} else {
$data['filterType'] = [];
}
if (!is_null($filterBadge)) {
$data['filterBadge'] = explode(',', $filterBadge);
} else {
$data['filterBadge'] = [];
}
if (!is_null($filterAttribute)) {
$data['filterAttribute'] = $data['filterAttributes'] = [];
foreach ($filterAttribute as $attributeId => $attribute) {
$options = explode(',', $attribute);
foreach ($options as $option) {
array_push($data['filterAttribute'], $option);
}
if ($attributeId !== 101) {
$data['filterAttributes'][$attributeId] = $attribute;
}
}
} else {
$data['filterAttribute'] = $data['filterAttributes'] = [];
}
if (!is_null($filterGroupOr)) {
$data['filterGroupOr'] = explode(',', $filterGroupOr);
} else {
$data['filterGroupOr'] = [];
}
if (!is_null($filterPriceMin)) {
$data['filterPriceMin'] = $filterPriceMin;
} else {
$data['filterPriceMin'] = false;
}
if (!is_null($filterPriceMax)) {
$data['filterPriceMax'] = $filterPriceMax;
} else {
$data['filterPriceMax'] = false;
}
if (!is_null($filterDiscounted)) {
$data['filterDiscounted'] = $filterDiscounted;
} else {
$data['filterDiscounted'] = false;
}
if (!is_null($filterLastPieces)) {
$data['filterLastPieces'] = $filterLastPieces;
} else {
$data['filterLastPieces'] = false;
}
$data['defaultFilters'] = $defaultFilters;
// Sort By
$data['sortOrders'] = [];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Default'),
'value' => 'default-asc',
'sort' => 'default',
'order' => 'asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Name') . ' (' . $translator->trans('A to Z') . ')',
'value' => 'name-asc',
'sort' => 'name',
'order' => 'asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Name') . ' (' . $translator->trans('Z to A') . ')',
'value' => 'name-desc',
'sort' => 'name',
'order' => 'desc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Price') . ' (' . $translator->trans('low to high') . ')',
'value' => 'price-asc',
'sort' => 'price',
'order' => 'asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Price') . ' (' . $translator->trans('high to low') . ')',
'value' => 'price-desc',
'sort' => 'price',
'order' => 'desc',
];
$data['sort'] = $sort;
$data['order'] = $order;
// Limit
$data['limits'] = [];
$limits = [12, 24, 48, 96];
foreach ($limits as $value) {
$data['limits'][] = [
'text' => $value,
'value' => $value,
];
}
$data['limit'] = $limit;
$data['salesManager'] = [];
if ($data['customerTypeId'] == MultiStore::CUSTOMER_TYPE_WHOLESALE) {
$loggedInCustomer = $this->getLoginHelper($request)->getLoggedInCustomer();
$salesManager = $loggedInCustomer->getSalesManager();
$data['salesManager']['name'] = '';
$data['salesManager']['username'] = '';
if ($salesManager) {
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
}
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['contentBottom'] = $this->getContentBottom($request);
return $this->render('AtechNetCoreBundle/Product/search.html.twig', $data);
}
/**
* @Route("/product/log/search", name="product_log_search", methods = {"POST"}, defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/log/search", name="product_log_search_locale", methods = {"POST"}, defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
*/
public function logSearchAction(Request $request): JsonResponse
{
// JSON
$json = [];
return new JsonResponse($json);
if ($this->getEnvironment() == 'prod') {
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser([
'ip_address' => $_SERVER['REMOTE_ADDR'],
]);
});
}
// Stopwatch
$stopwatch = new Stopwatch();
// Debug
$stopwatch->start('log');
// Search Term
if ($request->get('keyword')) {
$keyword = urldecode(trim($request->get('keyword')));
} else {
$keyword = null;
}
// Entity Manager
$entityManager = $this->getEntityManager();
// Connection
$connection = $entityManager->getConnection();
// Multi-Store
$multiStore = $this->getMultiStoreHelper($request);
// Statistics Entry
if (!empty($keyword)) {
// Customer
$customerId = null;
if ($this->getLoginHelper($request)->isLoggedIn()) {
$customerId = $this->getLoginHelper($request)->getLoggedInCustomerId();
}
//-> Action
$action = [];
if ($request->get('event')) {
$action['event'] = $request->get('event');
}
if ($request->get('location')) {
$action['location'] = $request->get('location');
}
if (!empty($request->get('page'))) {
$action['page'] = (int)$request->get('page');
}
// Convert
if (!empty($action)) {
$action = json_encode($action);
} else {
$action = null;
}
//<- Action
//-> Payload
$payload = [];
if ($request->get('deviceType')) {
$payload['deviceType'] = $request->get('deviceType');
}
if ($request->get('screenWidth')) {
$payload['screenWidth'] = $request->get('screenWidth');
}
if ($request->get('screenHeight')) {
$payload['screenHeight'] = $request->get('screenHeight');
}
if ($request->get('screenOrientation')) {
$payload['screenOrientation'] = $request->get('screenOrientation');
}
if ($request->getClientIp()) {
$payload['ip'] = $request->getClientIp();
}
// Convert
if (!empty($payload)) {
$payload = json_encode($payload);
} else {
$payload = null;
}
//<- Payload
//-> Content
$content = [];
if ($request->get('total')) {
$content['result'] = json_decode($request->get('total'), true);
}
if ($request->get('content')) {
$content['result'] = json_decode($request->get('content'), true);
}
if ($request->get('product')) {
$content['highlighted'] = json_decode($request->get('product'), true);
}
if (!empty($request->get('select'))) {
$content['select'] = $request->get('select');
}
// Convert
if (!empty($content)) {
$content = json_encode($content);
} else {
$content = null;
}
//<- Content
// Prevent double log
$log = true;
if ($request->getSession()->has('searchLog')) {
$searchLog = $request->getSession()->get('searchLog');
if (time() < strtotime('-1 minute', $searchLog['t']) && trim($searchLog['k']) == trim($keyword)) {
if (!empty($action['event'])) {
$e = $action['event'];
} else {
$e = '-';
}
if (!empty($action['location'])) {
$l = $action['location'];
} else {
$l = '-';
}
if (!empty($action['page'])) {
$p = $action['page'];
} else {
$p = '-';
}
if ($e == $searchLog['e'] && $l == $searchLog['l'] && $p == $searchLog['p']) {
$log = false;
}
}
}
if ($log) {
// Statement
$statistics = $connection->prepare("INSERT INTO statistics_search SET domain_id = :domainId, session_id = :sessionId, customer_id = :customerId, keyword = :keyword, `action` = :action, content = :content, payload = :payload, created = NOW()");
// Save
$statistics->execute([
'domainId' => $multiStore->getDomainId(),
'sessionId' => $request->getSession()->getId(),
'customerId' => $customerId,
'keyword' => $keyword,
'action' => $action,
'content' => $content,
'payload' => $payload,
]);
$request->getSession()->set('searchLog', [
't' => time(),
'k' => $keyword,
'e' => (!empty($action['event']) ? $action['event'] : '-'),
'l' => (!empty($action['location']) ? $action['location'] : '-'),
'p' => (!empty($action['page']) ? $action['page'] : '-'),
]);
}
}
// Debug
$json['debug'] = (string)$stopwatch->stop('log');
// Response
return new JsonResponse($json);
}
/**
* @Route("/akciove-produkty", name="product_all_discount_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/akciove-produkty", name="product_all_discount_sk_locale", defaults={"_locale":""})
* @Route("/akcios-termekek", name="product_all_discount_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/akcios-termekek", name="product_all_discount_hu_locale", defaults={"_locale":""})
* @param Request $request
* @return mixed
*/
public function allDiscountProductsAction(Request $request)
{
if ($this->getEnvironment() == 'prod') {
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
$scope->setUser([
'ip_address' => $_SERVER['REMOTE_ADDR'],
]);
});
}
return $this->individualListPagesBase($request, 'discount');
}
/**
* @Route("/posledne-kusy", name="product_all_last_piece_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/posledne-kusy", name="product_all_last_piece_sk_locale", defaults={"_locale":""})
* @Route("/utolso-darabok", name="product_all_last_piece_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/utolso-darabok", name="product_all_last_piece_hu_locale", defaults={"_locale":""})
* @param Request $request
* @return mixed
*/
public function allLastPieceProductsAction(Request $request)
{
return $this->individualListPagesBase($request, 'lastPiece');
}
/**
* @param Request $request
* @param $listPageType
* @return Response
* @throws InvalidArgumentException
*/
private function individualListPagesBase(Request $request, $listPageType): Response
{
$data = [];
$seoUrlHelper = $this->getSeoUrlHelper($request);
// Search
if ($request->get('fs')) {
$filterSearch = trim($request->get('fs'));
} else {
$filterSearch = null;
}
// Filter Vendor
if ($request->get('fv')) {
$filterVendor = $request->get('fv');
} else {
$filterVendor = null;
}
// Filter Product Type
if ($request->get('ft')) {
$filterType = $request->get('ft');
} else {
$filterType = null;
}
// Filter Badge
if ($request->get('fb')) {
$filterBadge = $request->get('fb');
} else {
$filterBadge = null;
}
// Filter Attribute
if ($request->get('fa')) {
$filterAttribute = $request->get('fa');
} else {
$filterAttribute = null;
}
// Filter Group OR - Create OR groups by attribute ID
if ($request->get('fgo')) {
$filterGroupOr = $request->get('fgo');
} else {
$filterGroupOr = null;
}
// Filter Price
if ($request->get('fp')) {
$filterPrice = explode('-', $request->get('fp'));
if (!empty($filterPrice[0])) {
$filterPriceMin = floor((float)$filterPrice[0]);
} else {
$filterPriceMin = null;
}
if (!empty($filterPrice[1])) {
$filterPriceMax = ceil((float)$filterPrice[1]);
} else {
$filterPriceMax = null;
}
} else {
$filterPriceMin = $filterPriceMax = null;
}
// Filter Discounted
if ($listPageType == 'discount') {
$filterDiscounted = 1;
} else {
if ($request->get('fd')) {
$filterDiscounted = (int)$request->get('fd');
} else {
$filterDiscounted = null;
}
}
// Filter Last Pieces
if ($listPageType == 'lastPiece') {
$filterLastPieces = 1;
} else {
if ($request->get('fl')) {
$filterLastPieces = (int)$request->get('fl');
} else {
$filterLastPieces = null;
}
}
// Sort
if ($request->get('sort')) {
$sort = $request->get('sort');
} else {
$sort = 'price';
}
// Order
if ($request->get('order')) {
$order = $request->get('order');
} else {
$order = 'asc';
}
// Page
if ($request->get('page')) {
$page = $request->get('page');
} else {
$page = 1;
}
// Limit
if ($request->get('limit')) {
$limit = $request->get('limit');
} else {
$limit = 24;
}
$multiStore = $this->getMultiStoreHelper($request);
$productHelper = $this->getProductHelper($request);
$translator = $this->getTranslator();
$seoUrl = $this->url($request);
$data['customerTypeId'] = $request->getSession()->get('customerTypeId');
$data['breadcrumbs'] = [];
$data['breadcrumbs'][] = $this->getBreadCrumbsBase($request);
// Breadcrumb Arguments
$arguments = [];
if (!is_null($filterSearch)) {
$arguments['fs'] = $filterSearch;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterType)) {
$arguments['ft'] = $filterType;
}
if (!is_null($filterBadge)) {
$arguments['fb'] = $filterBadge;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterGroupOr)) {
$arguments['fgo'] = $filterGroupOr;
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$domain = $multiStore->getDomain();
$data['pageTitle'] = '';
$data['pageDescription'] = '';
if ($listPageType == 'discount') {
$data['pageTitle'] = $translator->trans('Discount PCs and notebooks');
$data['pageDescription'] = $translator->trans('Notebook, PC and monitor sale! Free shipping and Y year warranty on every product.', [
'year' => $this->getWarrantyForNonProductText($domain->getId()),
]);
}
if ($listPageType == 'lastPiece') {
$data['pageTitle'] = $translator->trans('Last pieces');
$data['pageDescription'] = $translator->trans('Choose from our last piece products, now with even better price! Y years warranty, free shipping within 24 hours!', [
'%year%' => $this->getWarrantyForNonProductText($domain->getId()),
]);
}
$argumentsConverted = '';
foreach ($arguments as $argKey => $argVal) {
$argumentsConverted .= ($argumentsConverted == '' ? '?' : '&') . $argKey . '=' . $argVal;
}
$data['breadcrumbs'][] = [
'text' => $data['pageTitle'],
'href' => $request->getUri() . '/' . $argumentsConverted,
];
$domain = $multiStore->getDomain();
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
$data['products'] = [];
$filterData = [
'filterSearch' => $filterSearch,
'filterVendor' => $filterVendor,
'filterType' => $filterType,
'filterBadge' => $filterBadge,
'filterAttribute' => $filterAttribute,
'filterGroupOr' => $filterGroupOr,
'filterPriceMin' => $filterPriceMin,
'filterPriceMax' => $filterPriceMax,
'filterDiscounted' => $filterDiscounted,
'filterLastPieces' => $filterLastPieces,
'sort' => $sort,
'order' => $order,
'start' => ($page - 1) * $limit,
'limit' => $limit,
];
if (!is_null($filterType)) {
$data['ncFilter'][] = [
'title' => $this->getEntityManager()->getRepository(ProductType::class)->findOneById($filterType)->getTitle($this->getDatabaseTranslator($request)),
'type' => 'ft',
];
}
if (!is_null($filterVendor)) {
$data['ncFilter'][] = [
'title' => $this->getEntityManager()->getRepository(Vendor::class)->findOneById($filterVendor)->getName($this->getDatabaseTranslator($request)),
'type' => 'fv',
];
}
$placeholder = $this->getImage('placeholder.png', '')->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
$results = $productHelper->getStructuredDataByFilters($filterData);
foreach ($results as $result) {
$image = $placeholder;
if (is_object($result['images'])) {
$image = $this->getImage($result['images'], 'product/' . $result['code'])->resize(Image::PRODUCT_LIST_THUMB_WIDTH, Image::PRODUCT_LIST_THUMB_HEIGHT);
}
$data['products'][] = [
'id' => $result['id'],
'title' => $result['title'],
'vendor' => $result['vendor'],
'labels' => $result['badges'],
'price' => $result['vatPrice'],
'special' => ($result['isDiscounted'] ? $result['discountVatPrice'] : false),
'rawPrice' => $result['rawPrice'],
'rawDiscountPrice' => $result['rawDiscountPrice'],
'image' => $image,
'attributes' => $result['attributes'],
'available' => $result['availableQty'],
'href' => $seoUrl->link('product', [
'product_id' => $result['id'],
'isBazaar' => $result['isBazaar'] ?? 0
]),
'active' => $result['active'],
'typeId' => $result['productTypeId'],
'warrantyYear' => $this->getWarrantyForProductType($domain->getId(), $result['productTypeId'])['year'],
'labelOS' => $this->getProductHelper($request)->getOSLabel($result),
];
}
// Pagination
if (!empty($results)) {
$result = $productHelper->getTotalByFilters($filterData);
$arguments = [];
if (!is_null($filterSearch)) {
$arguments['fs'] = $filterSearch;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterType)) {
$arguments['ft'] = $filterType;
}
if (!is_null($filterBadge)) {
$arguments['fb'] = $filterBadge;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterGroupOr)) {
$arguments['fgo'] = $filterGroupOr;
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$arguments['page'] = '{page}';
$argumentsConverted = '';
foreach ($arguments as $argKey => $argVal) {
$argumentsConverted .= ($argumentsConverted == '' ? '?' : '&') . $argKey . '=' . $argVal;
}
$data['pagination'] = [
'total' => $result,
'page' => $page,
'limit' => $limit,
'url' => strtok($request->getUri(), '?') . $argumentsConverted,
];
} else {
$data['pagination'] = [];
}
// Filter Options
$filters = $productHelper->buildFilterOptions($filterData, [
'search' => true,
]);
$data['filters'] = $filters;
if (!is_null($filterSearch)) {
$data['filterSearch'] = $filterSearch;
} else {
$data['filterSearch'] = '';
}
if (!is_null($filterVendor)) {
$data['filterVendor'] = explode(',', $filterVendor);
} else {
$data['filterVendor'] = [];
}
if (!is_null($filterType)) {
$data['filterType'] = explode(',', $filterType);
} else {
$data['filterType'] = [];
}
if (!is_null($filterBadge)) {
$data['filterBadge'] = explode(',', $filterBadge);
} else {
$data['filterBadge'] = [];
}
if (!is_null($filterAttribute)) {
$data['filterAttribute'] = $data['filterAttributes'] = [];
foreach ($filterAttribute as $attributeId => $attribute) {
$options = explode(',', $attribute);
foreach ($options as $option) {
array_push($data['filterAttribute'], $option);
}
if ($attributeId !== 101) {
$data['filterAttributes'][$attributeId] = $attribute;
}
}
} else {
$data['filterAttribute'] = $data['filterAttributes'] = [];
}
if (!is_null($filterGroupOr)) {
$data['filterGroupOr'] = explode(',', $filterGroupOr);
} else {
$data['filterGroupOr'] = [];
}
if (!is_null($filterPriceMin)) {
$data['filterPriceMin'] = $filterPriceMin;
} else {
$data['filterPriceMin'] = false;
}
if (!is_null($filterPriceMax)) {
$data['filterPriceMax'] = $filterPriceMax;
} else {
$data['filterPriceMax'] = false;
}
if (!is_null($filterDiscounted)) {
$data['filterDiscounted'] = $filterDiscounted;
} else {
$data['filterDiscounted'] = false;
}
if (!is_null($filterLastPieces)) {
$data['filterLastPieces'] = $filterLastPieces;
} else {
$data['filterLastPieces'] = false;
}
// Filter Action
$arguments = [];
$data['actionFiltered'] = false;
if ($request->get('sort')) {
$arguments['sort'] = $sort;
$data['actionFiltered'] = true;
}
if ($request->get('order')) {
$arguments['order'] = $order;
$data['actionFiltered'] = true;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
$data['actionFiltered'] = true;
}
$argumentsConverted = '';
foreach ($arguments as $argKey => $argVal) {
$argumentsConverted .= ($argumentsConverted == '' ? '?' : '&') . $argKey . '=' . $argVal;
}
$data['action'] = strtok($request->getUri(), '?') . $argumentsConverted;
// Sort Arguments
$arguments = [];
if (!is_null($filterSearch)) {
$arguments['fs'] = $filterSearch;
}
if (!is_null($filterVendor)) {
$arguments['fv'] = $filterVendor;
}
if (!is_null($filterType)) {
$arguments['ft'] = $filterType;
}
if (!is_null($filterBadge)) {
$arguments['fb'] = $filterBadge;
}
if (!is_null($filterAttribute)) {
foreach ($filterAttribute as $key => $value) {
$arguments['fa[' . $key . ']'] = $value;
}
}
if (!is_null($filterGroupOr)) {
$arguments['fgo'] = $filterGroupOr;
}
if (!is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-' . $filterPriceMax;
} elseif (!is_null($filterPriceMin) && is_null($filterPriceMax)) {
$arguments['fp'] = $filterPriceMin . '-0';
} elseif (is_null($filterPriceMin) && !is_null($filterPriceMax)) {
$arguments['fp'] = '0-' . $filterPriceMax;
}
if (!is_null($filterDiscounted)) {
$arguments['fd'] = $filterDiscounted;
}
if (!is_null($filterLastPieces)) {
$arguments['fl'] = $filterLastPieces;
}
if ($request->get('sort')) {
$arguments['sort'] = $sort;
}
if ($request->get('order')) {
$arguments['order'] = $order;
}
if ($request->get('limit')) {
$arguments['limit'] = $limit;
}
$argumentsConverted = '';
foreach ($arguments as $argKey => $argVal) {
$argumentsConverted .= ($argumentsConverted == '' ? '?' : '&') . $argKey . '=' . $argVal;
}
// Sort By
$data['sortOrders'] = [];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Default'),
'value' => 'default-asc',
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'sort=default&order=asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Name') . ' (' . $translator->trans('A to Z') . ')',
'value' => 'name-asc',
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'sort=name&order=asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Name') . ' (' . $translator->trans('Z to A') . ')',
'value' => 'name-desc',
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'sort=name&order=desc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Price') . ' (' . $translator->trans('low to high') . ')',
'value' => 'price-asc',
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'sort=price&order=asc',
];
$data['sortOrders'][] = [
'text' => $translator->trans('Sort by') . ': ' . $translator->trans('Price') . ' (' . $translator->trans('high to low') . ')',
'value' => 'price-desc',
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'sort=price&order=desc',
];
$data['sort'] = $sort;
$data['order'] = $order;
// Limit
$data['limits'] = [];
$limits = [12, 24, 48, 96];
foreach ($limits as $value) {
$data['limits'][] = [
'text' => $value,
'value' => $value,
'href' => $data['action'] . ($argumentsConverted == '' ? '?' : $argumentsConverted . '&') . 'limit=' . $value,
];
}
$data['limit'] = $limit;
$data['salesManager'] = [];
if ($data['customerTypeId'] == MultiStore::CUSTOMER_TYPE_WHOLESALE) {
$loggedInCustomer = $this->getLoginHelper($request)->getLoggedInCustomer();
$salesManager = $loggedInCustomer->getSalesManager();
$data['salesManager']['name'] = $salesManager->getFirstName();
$data['salesManager']['username'] = $salesManager->getUsername();
$data['salesManager']['phone'] = $salesManager->getPhone();
}
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['contentBottom'] = $this->getContentBottom($request);
$domainId = $domain->getId();
$data['warrantyYear'] = $this->getWarrantyForNonProductText($domainId);
$data['listPageType'] = $listPageType;
switch ($domainId) {
case 1:
case 2:
$data['quality_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 11,
]);
$data['notebooks_discount_link'] = $seoUrl->link('category', [
'path' => 5,
'fd' => 1,
]);
$data['pcs_discount_link'] = $seoUrl->link('category', [
'path' => 4,
'fd' => 1,
]);
$data['monitors_discount_link'] = $seoUrl->link('category', [
'path' => 6,
'fd' => 1,
]);
break;
case 3:
case 4:
$data['quality_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 27,
]);
$data['notebooks_discount_link'] = $seoUrl->link('category', [
'path' => 56,
'fd' => 1,
]);
$data['pcs_discount_link'] = $seoUrl->link('category', [
'path' => 48,
'fd' => 1,
]);
$data['monitors_discount_link'] = $seoUrl->link('category', [
'path' => 78,
'fd' => 1,
]);
break;
case 9:
case 5:
$data['quality_info_link'] = $seoUrlHelper->link('page', [
'static_id' => 60,
]);
$data['notebooks_discount_link'] = $seoUrl->link('category', [
'path' => 130,
'fd' => 1,
]);
$data['pcs_discount_link'] = $seoUrl->link('category', [
'path' => 122,
'fd' => 1,
]);
$data['monitors_discount_link'] = $seoUrl->link('category', [
'path' => 149,
'fd' => 1,
]);
break;
default:
$data['quality_info_link'] = '';
$data['notebooks_discount_link'] = $seoUrl->link('category', [
'path' => 5,
'fd' => 1,
]);
$data['pcs_discount_link'] = $seoUrl->link('category', [
'path' => 4,
'fd' => 1,
]);
$data['monitors_discount_link'] = $seoUrl->link('category', [
'path' => 6,
'fd' => 1,
]);
}
return $this->render('AtechNetCoreBundle/Product/individualListPage.html.twig', $data);
}
/**
* @Route("/product/{productId}/review", name="product_review", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/{productId}/review", name="product_review_locale", defaults={"_locale":""})
* @param int $productId
* @param Request $request
* @return Response
*/
public function reviewAction(int $productId, Request $request): Response
{
$data = [];
$multiStore = $this->getMultiStoreHelper($request);
if ($request->get('page')) {
$page = $request->get('page');
} else {
$page = 1;
}
$limit = 6;
$data['reviews'] = [];
$entityManager = $this->getEntityManager();
$results = $entityManager->getRepository(Review::class)->findBy(
[
'language' => $multiStore->getDefaultLanguageId(),
'type' => Review::TYPE_PRODUCT,
'product' => $productId,
'approved' => 1,
],
[
'created' => 'DESC',
],
$limit,
(($page - 1) * $limit)
);
$total = $entityManager->getRepository(Review::class)->findBy([
'language' => $multiStore->getDefaultLanguageId(),
'type' => Review::TYPE_PRODUCT,
'product' => $productId,
'approved' => 1,
]);
foreach ($results as $result) {
$data['reviews'][] = [
'name' => $result->getName(),
'text' => $result->getText(),
'rating' => $result->getStars(),
];
}
$data['pagination'] = [
'total' => count($total),
'page' => $page,
'limit' => $limit,
'url' => $this->generateUrl('review_list_' . $multiStore->getLanguage()->getCode(), [
'productId' => $productId,
'page' => '{page}',
]),
];
return $this->render('AtechNetCoreBundle/Module/review.html.twig', $data);
}
/**
* @param Request $request
* @return false|string
*/
private function onlyLastParamHandler(Request $request)
{
if ($request->get('only-last')) {
$explodedString = explode('-', $request->get('only-last'));
$number = $explodedString[0];
$unit = $explodedString[1];
switch ($unit) {
case 'hour':
$unit = 'H';
break;
case 'minute':
$unit = 'M';
break;
}
return (
$number > 0 && (
$unit == 'H' && $number <= 12 ||
$unit == 'M' && $number <= 720
)
) ? (new \DateTime())->sub(new \DateInterval('PT' . $number . $unit)) : 'invalid';
} else {
return false;
}
}
/**
* @Route("/feed/{token}", name="product_feed", defaults={"_locale":""})
* @param Request $request
* @param $token
* @return Response
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function feedAction(Request $request, $token): Response
{
if (isset($token) && $token != '' && strlen($token) > 10) {
$entityManager = $this->getEntityManager();
$productFeed = $entityManager->createQuery("SELECT cpf
FROM AtechNetCoreBundle:CustomerProductFeed cpf
WHERE cpf.token = :token AND cpf.expire > :expire AND cpf.active = 1")
->setParameters([
'token' => $token,
'expire' => (new \DateTime()),
])
->setMaxResults(1)
->getResult();
if (isset($productFeed[0])) {
$productFeed = $productFeed[0];
$cache = $this->cache;
$customer = $productFeed->getCustomer();
$seoUrlHelper = $this->getSeoUrlHelper($request);
$environment = $this->getEnvironment();
$isNlc = $customer->getId() == 18733;
$isCopyandMore = $customer->getId() == 31170;
$isAndreaShop = $customer->getId() == Customer::ANDREASHOP_ID;
$isMerxu = $customer->getId() == 56655;
$isAdLogic = $customer->getId() == 87351;
if ($isMerxu) {
$domain = $entityManager->getRepository(Domain::class)->findOneById(Domain::DOMAIN_ID_WS_SK);
} else {
$domain = $customer->getDomain();
}
$cacheKey = 'partner.feed.v3.domain.' . $domain->getId() . '.' . ($isNlc ? 1 : 0) . '.' . ($isCopyandMore ? 1 : 0) . '.' . ($isAndreaShop ? 1 : 0) . '.' . ($isMerxu ? 1 : 0) . '.' . ($isAdLogic ? 1 : 0);
$cacheItem = $cache->getItem($cacheKey);
$onlyLast = $this->onlyLastParamHandler($request);
if ($onlyLast == 'invalid') {
return new Response('Invalid only-last parameter!');
}
if ($cacheItem->isHit() && !$onlyLast) {
$xml = $cacheItem->get();
} else {
$qualityStatuses = Product::getQualityStatusChoices();
$translator = new DatabaseTranslator($entityManager, $domain->getId());
$queryParams = [
'domain' => $domain,
'bazarQualityStatus' => Product::QualityStatus_Bazaar,
];
$setCache = false;
$allowedProductTypesIDs = [
1, 4, 5, 6, 7, 35, 41, 44, 45, 46, 52, 60, 64, 66, 68, 69, 75, 76, 77, 84, 90, 103, 104, 106, 107, 110, 113, 114, 116, 138, 145, 147, 149, 150, 154, 155, 156, 160, 167, 180, 182, 184, 185, 192, 199,
];
if ($onlyLast) {
$queryParams['onlyLast'] = $onlyLast;
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.metas pm
LEFT JOIN p.orderItems poi
WHERE pm.domain = :domain
AND p.updated > :onlyLast
AND poi IS NOT null
AND p.qualityStatus != :bazarQualityStatus")
->setParameters($queryParams)
->getResult();
} elseif ($isAdLogic) {
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.metas pm
WHERE p.available > 0
AND pm.domain = :domain
AND pm.listed = 1
AND pm.active = 1
AND pm.orderable = 1
AND (p.qualityStatus = :bazarQualityStatus OR p.type IN (" . implode(',', $this->getAccessoriesProductTypeIdList()) . "))")
->setParameters($queryParams)
->getResult();
$setCache = true;
} else {
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.metas pm
WHERE p.available > 0
AND pm.domain = :domain
AND pm.listed = 1
AND pm.active = 1
AND pm.orderable = 1
AND p.qualityStatus != :bazarQualityStatus" . ($customer->getId() == 56655 ? " AND p.type IN (41,44,52,60,116)" : " AND p.type IN (" . implode(',', $allowedProductTypesIDs) . ")"))
->setParameters($queryParams)
->getResult();
$setCache = true;
}
$xml = '<?xml version="1.0" encoding="utf-8" ?><SHOP>';
$multistorHelper = $this->getMultiStoreHelper($request);
$requestDomain = $multistorHelper->getDomain();
$language = $requestDomain->getLanguage();
$categoryPageTitles = [];
foreach ($products as $product) {
$productMeta = $product->getDomainMeta($domain);
if (!$productMeta) {
continue;
}
$price = $productMeta->isDiscounted() ? $productMeta->getDomainVatDiscount() : $productMeta->getDomainVatPrice();
$originalPrice = $productMeta->isDiscounted() ? $productMeta->getDomainVatPrice() : '';
if (1 > $price) {
continue;
}
$image = '';
$images = '';
if ($environment == 'prod') {
$photos = $product->getAlbum()->getPhotos();
if (count($photos) > 0) {
$photos = Collections::sort($photos);
foreach ($photos as $photo) {
if (is_object($photo)) {
if ($image == '') {
$image = $this->getImage($photo, 'product/' . $product->getCode(), true)->resize(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT);
} else {
$images .= '<IMAGE_URL>' . $this->getImage($photo, 'product/' . $product->getCode(), true)->resize(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT) . '</IMAGE_URL>';
}
}
}
}
}
if ($productMeta->getDomainVatSuggestedPrice() != 0) {
$suggestedVatPrice = $productMeta->getDomainVatSuggestedPrice();
} else {
$suggestedPrice = $this->calculateSuggestedPrice($productMeta);
$suggestedVatPrice = $domain->createVatPrice($suggestedPrice);
}
$subCategories = '<SUB_CATEGORIES>';
foreach ($product->getBadges() as $badge) {
if ($badge != 'win10') {
$subCategories .= '<SUB_CAT>' . ucfirst($badge) . '</SUB_CAT>';
}
}
$subCategories .= '</SUB_CATEGORIES>';
$created = $product->getCreated()->format('Y-m-d, H:i');
$updated = !is_null($product->getUpdated()) ? $product->getUpdated()->format('Y-m-d, H:i') : '-';
$productType = $product->getType();
$categoryValue = ($isCopyandMore ? trim($productType->getTitle($translator)) : trim($productType->getTitle()));
$categoryPageWithParent = $productType->getCategoryPageWithParentByDomain($requestDomain);
$parentCategoryTitle = "<FULL_CATEGORY>";
if ($categoryPageWithParent) {
$parentCategoryId = $categoryPageWithParent->getParentCategory()->getId();
if (!isset($categoryPageTitles[$parentCategoryId])) {
$pageInfo = $entityManager->getRepository(PageMeta::class)->findOneBy([
'categoryPage' => $parentCategoryId,
'language' => $language->getId(),
]);
if ($isAdLogic) {
$categoryPageTitles[$parentCategoryId] = $translator->trans(trim($pageInfo->getTitle()));
} else {
$categoryPageTitles[$parentCategoryId] = trim($pageInfo->getTitle());
}
if ($pageInfo) {
if ($isAdLogic) {
$categoryPageTitles[$parentCategoryId] = $translator->trans(trim($pageInfo->getTitle()));
} else {
$categoryPageTitles[$parentCategoryId] = trim($pageInfo->getTitle());
}
}
}
if ($isAdLogic) {
$categoryValue = $translator->trans($categoryValue);
}
if (isset($categoryPageTitles[$parentCategoryId])) {
$parentCategoryTitle .= $categoryPageTitles[$parentCategoryId] . " | " . $categoryValue;
} else {
$parentCategoryTitle .= $categoryValue;
}
}
$parentCategoryTitle .= "</FULL_CATEGORY>";
if ($isAdLogic && $parentCategoryTitle == "<FULL_CATEGORY></FULL_CATEGORY>") {
if ($isAdLogic) {
$categoryValue = $translator->trans($categoryValue);
}
$parentCategoryTitle = "<FULL_CATEGORY>" . $categoryValue . "</FULL_CATEGORY>";
}
$ean = '';
if ($isAndreaShop) {
if (is_null($product->getEan()) || $product->getEan() == '') {
$ean = $product->getFormattedEan();
} else {
$ean = $product->getEan();
}
} else {
if (!is_null($product->getEan()) && $product->getEan() != '') {
$ean = $product->getEan();
}
}
$xml .= "<SHOPITEM>
<ITEM_ID>" . $product->getId() . "</ITEM_ID>
<CODE>" . $product->getCode() . "</CODE>
<EAN>" . $ean . "</EAN>
<NAME><![CDATA[" . ($isCopyandMore ? $product->getName() : $product->getFullTitle($translator)) . "]]></NAME>
<VENDOR><![CDATA[" . $product->getVendor()->getName() . "]]></VENDOR>
<SHORT_DESCRIPTION><![CDATA[" . $product->getDescription() . "]]></SHORT_DESCRIPTION>
<DESCRIPTION><![CDATA[" . preg_replace('#<[^>]+>#', ' ', $productMeta->getFullDescription($translator)) . "]]></DESCRIPTION>
<IMAGE_URL>" . $image . "</IMAGE_URL>
<PRODUCT_URL>" . $seoUrlHelper->link('product', [
'product_id' => $product->getId(),
]) . "</PRODUCT_URL>
<PRICE>" . $price . "</PRICE>
<ORIGINAL_PRICE>" . $originalPrice . "</ORIGINAL_PRICE>
<SUGGESTED_PRICE>" . $suggestedVatPrice . "</SUGGESTED_PRICE>
<CATEGORY>$categoryValue</CATEGORY>
" . $parentCategoryTitle . "
" . $subCategories . "
<QUALITY>" . $this->getTranslator()->trans(strtolower($qualityStatuses[$product->getQualityStatus()])) . "</QUALITY>
<IN_STOCK>" . $product->getAvailable() . "</IN_STOCK>
<CREATED>" . $created . "</CREATED>
<UPDATED>" . $updated . "</UPDATED>
<IMAGES>" . $images . "</IMAGES>";
if ($isAdLogic) {
if ($product->getWeight() > 0) {
$xml .= "<Suly>" . number_format($product->getWeight() / 1000, 2, '.', '') . "</Suly>";
}
foreach ($product->getSpecificationProductAttributeOptions() as $pao) {
$ao = $pao->getOption();
if ($ao->getAttribute()->getId() == 95) {
continue;
}
if (!isset($attrTitles[$ao->getAttribute()->getId()])) {
$attrTitles[$ao->getAttribute()->getId()] = $ao->getAttribute()->getTitle($translator);
}
$attrTitle = $attrTitles[$ao->getAttribute()->getId()];
if (!isset($attrOptTitles[$ao->getId()])) {
$attrOptTitles[$ao->getId()] = $ao->getTitle($translator);
}
$attrOptTitle = $attrOptTitles[$ao->getId()];
$attributeTitle = $this->removeSpecialCharacters($attrTitle);
if ($attributeTitle != '') {
$xml .= "<" . $attributeTitle . ">" . str_replace('&', '&', $attrOptTitle) . "</" . $attributeTitle . ">";
}
}
} else {
$xml .= "<CONFIGURATION>";
/**
* @var Product $product
* @var ProductAttribute $pao
*
*/
foreach ($product->getSpecificationProductAttributeOptions() as $pao) {
$ao = $pao->getOption();
if ($ao->getAttribute()->getId() == 95) {
continue;
}
if (!isset($attrTitles[$ao->getAttribute()->getId()])) {
$attrTitles[$ao->getAttribute()->getId()] = $ao->getAttribute()->getTitle($translator);
}
$attrTitle = $attrTitles[$ao->getAttribute()->getId()];
if (!isset($attrOptTitles[$ao->getId()])) {
$attrOptTitles[$ao->getId()] = $ao->getTitle($translator);
}
$attrOptTitle = $attrOptTitles[$ao->getId()];
if ($isAdLogic) {
$attributeTitle = $this->removeSpecialCharacters($attrTitle);
if ($attributeTitle != '') {
$xml .= "<ATTR>
<" . $attributeTitle . ">" . str_replace('&', '&', $attrOptTitle) . "</" . $attributeTitle . ">
</ATTR>";
}
} else {
$xml .= "<ATTR>
" . ($pao->getMultiplier() > 0 ? '<QTY>' . $pao->getMultiplier() . '</QTY>' : '') . "
<TITLE>" . ($isNlc ? '<![CDATA[' : '') . $attrTitle . ($isNlc ? ']]>' : '') . "</TITLE>
<VALUE>" . ($isNlc ? '<![CDATA[' : '') . str_replace('&', '&', $attrOptTitle) . ($isNlc ? ']]>' : '') . "</VALUE>
</ATTR>";
}
}
$xml .= "</CONFIGURATION>";
}
$xml .= "</SHOPITEM>\n";
}
$xml .= '</SHOP>';
if ($setCache) {
$cacheItem->set($xml);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_4_HOUR);
$cache->save($cacheItem);
}
}
$productFeed->setValidRequests($productFeed->getValidRequests() + 1);
$entityManager->flush();
$response = new Response($xml);
$response->headers->set('Content-Type', 'xml');
return $response;
}
}
return new Response('Something went wrong, please contact your sales manager!');
}
/**
* @Route("/techbazar-feed/{token}", name="tech_baazar_feed", defaults={"_locale":""})
* @param Request $request
* @param $token
* @return Response
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function techBazarFeedAction(Request $request, $token): Response
{
if ($token == '0854032424-jg439043240523-ji349t430k9d0932-4j8g34ds0tu4sdl') {
$entityManager = $this->getEntityManager();
$cache = $this->cache;
$seoUrlHelper = $this->getSeoUrlHelper($request);
$environment = $this->getEnvironment();
$productRepository = $entityManager->getRepository(Product::class);
$domain = $this->getMultiStoreHelper($request)->getDomain();
$cacheKey = 'techBazar.feed.v5.' . $domain->getId();
$cacheItem = $cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
$xml = $cacheItem->get();
} else {
$qualityStatuses = Product::getQualityStatusChoices();
$translator = new DatabaseTranslator($entityManager, $domain->getId());
$queryParams = [
'domain' => $domain,
'bazarQualityStatus' => Product::QualityStatus_Bazaar,
];
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN p.metas pm
WHERE p.available > 0
AND pm.domain = :domain
AND pm.listed = 1
AND pm.active = 1
AND pm.orderable = 1
AND (p.qualityStatus = :bazarQualityStatus OR p.type IN (" . implode(',', $this->getAccessoriesProductTypeIdList()) . "))")
->setParameters($queryParams)
->getResult();
$xml = '<?xml version="1.0" encoding="utf-8" ?><SHOP>';
$multistorHelper = $this->getMultiStoreHelper($request);
$requestDomain = $multistorHelper->getDomain();
$language = $requestDomain->getLanguage();
$categoryPageTitles = [];
$errorCodeCache = [];
/**
* @var Product $product
*/
foreach ($products as $product) {
$productMeta = $product->getDomainMeta($domain);
if (!$productMeta) {
continue;
}
$price = $productMeta->isDiscounted() ? $productMeta->getDomainVatDiscount() : $productMeta->getDomainVatPrice();
$originalPrice = $productMeta->isDiscounted() ? $productMeta->getDomainVatPrice() : '';
if ($price < 1) {
continue;
}
$availableStockItems = $productRepository->getAvailableStockItems($product);
$image = '';
$images = '';
if ($environment == 'prod') {
$photos = $product->getAlbum()->getPhotos();
if (count($photos) > 0) {
$photos = Collections::sort($photos);
foreach ($photos as $photo) {
if (is_object($photo)) {
if ($image == '') {
$image = $this->getImage($photo, 'product/' . $product->getCode(), true)->resize(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT);
} else {
$images .= '<IMAGE_URL>' . $this->getImage($photo, 'product/' . $product->getCode(), true)->resize(Image::PRODUCT_VIEW_THUMB_WIDTH, Image::PRODUCT_VIEW_THUMB_HEIGHT) . '</IMAGE_URL>';
}
}
}
}
}
if ($productMeta->getDomainVatSuggestedPrice() != 0) {
$suggestedVatPrice = $productMeta->getDomainVatSuggestedPrice();
} else {
$suggestedPrice = $this->calculateSuggestedPrice($productMeta);
$suggestedVatPrice = $domain->createVatPrice($suggestedPrice);
}
$subCategories = '<SUB_CATEGORIES>';
foreach ($product->getBadges() as $badge) {
if ($badge != 'win10') {
$subCategories .= '<SUB_CAT>' . ucfirst($badge) . '</SUB_CAT>';
}
}
$subCategories .= '</SUB_CATEGORIES>';
$created = $product->getCreated()->format('Y-m-d, H:i');
$updated = !is_null($product->getUpdated()) ? $product->getUpdated()->format('Y-m-d, H:i') : '-';
$productType = $product->getType();
$categoryValue = trim($productType->getTitle());
$categoryPageWithParent = $productType->getCategoryPageWithParentByDomain($requestDomain);
$parentCategoryTitle = "<FULL_CATEGORY>";
if ($categoryPageWithParent) {
$parentCategoryId = $categoryPageWithParent->getParentCategory()->getId();
if (!isset($categoryPageTitles[$parentCategoryId])) {
$pageInfo = $entityManager->getRepository(PageMeta::class)->findOneBy([
'categoryPage' => $parentCategoryId,
'language' => $language->getId(),
]);
$categoryPageTitles[$parentCategoryId] = $translator->trans(trim($pageInfo->getTitle()));
if ($pageInfo) {
$categoryPageTitles[$parentCategoryId] = $translator->trans(trim($pageInfo->getTitle()));
}
}
$categoryValue = $translator->trans($categoryValue);
if (isset($categoryPageTitles[$parentCategoryId])) {
$parentCategoryTitle .= $categoryPageTitles[$parentCategoryId] . " | " . $categoryValue;
} else {
$parentCategoryTitle .= $categoryValue;
}
}
$parentCategoryTitle .= "</FULL_CATEGORY>";
if ($parentCategoryTitle == "<FULL_CATEGORY></FULL_CATEGORY>") {
$categoryValue = $translator->trans($categoryValue);
$parentCategoryTitle = "<FULL_CATEGORY>" . $categoryValue . "</FULL_CATEGORY>";
}
$ean = '';
if (!is_null($product->getEan()) && $product->getEan() != '') {
$ean = $product->getEan();
}
if (count($availableStockItems) > 0 && $product->getQualityStatus() == Product::QualityStatus_Bazaar) {
/**
* @var StockItem $stockItem
*/
foreach ($availableStockItems as $stockItem) {
if ($stockItem->getAlbum() && $stockItem->getAlbum()->getPhotos()->count() > 0) {
foreach ($stockItem->getAlbum()->getPhotos() as $stockItemPhoto) {
$images .= '<IMAGE_URL>' . $this->getImage(
$stockItemPhoto,
'product/' . $product->getCode(),
true
)->resize(
Image::PRODUCT_VIEW_THUMB_WIDTH,
Image::PRODUCT_VIEW_THUMB_HEIGHT
) . '</IMAGE_URL>';
}
}
$identifier = '';
if (!is_null($stockItem->getAikenCode()) && $stockItem->getAikenCode() != '') {
$identifier = $stockItem->getAikenCode();
}
if ($identifier != '' && !is_null(
$stockItem->getSerialNumber()
) && $stockItem->getSerialNumber() != '') {
$identifier = $stockItem->getSerialNumber();
}
if ($identifier == '') {
continue;
}
$xml .= "<SHOPITEM>
<ITEM_ID>" . $product->getId() . "-" . $identifier . "</ITEM_ID>
<CODE>" . $product->getCode() . "-" . $identifier . "</CODE>
<EAN>" . $ean . "</EAN>
<NAME><![CDATA[" . $product->getFullTitle($translator) . "]]></NAME>
<VENDOR><![CDATA[" . $product->getVendor()->getName() . "]]></VENDOR>
<SHORT_DESCRIPTION><![CDATA[" . $product->getDescription() . "]]></SHORT_DESCRIPTION>
<DESCRIPTION><![CDATA[" . preg_replace(
'#<[^>]+>#',
' ',
$productMeta->getFullDescription($translator)
) . "]]></DESCRIPTION>
<IMAGE_URL>" . $image . "</IMAGE_URL>
<PRODUCT_URL>" . $seoUrlHelper->link('product', [
'product_id' => $product->getId(),
'isBazaar' => $product->isBazaar()
]) . "</PRODUCT_URL>
<PRICE>" . $price . "</PRICE>
<ORIGINAL_PRICE>" . $originalPrice . "</ORIGINAL_PRICE>
<SUGGESTED_PRICE>" . $suggestedVatPrice . "</SUGGESTED_PRICE>
<CATEGORY>$categoryValue</CATEGORY>
" . $parentCategoryTitle . "
" . $subCategories . "
<QUALITY>" . $this->getTranslator()->trans(
strtolower($qualityStatuses[$product->getQualityStatus()])
) . "</QUALITY>
<IN_STOCK>1</IN_STOCK>
<CREATED>" . $created . "</CREATED>
<UPDATED>" . $updated . "</UPDATED>
<IMAGES>" . $images . "</IMAGES>";
if ($product->getWeight() > 0) {
$xml .= "<Suly>" . number_format($product->getWeight() / 1000, 2, '.', '') . "</Suly>";
}
foreach ($product->getSpecificationProductAttributeOptions() as $pao) {
$ao = $pao->getOption();
if ($ao->getAttribute()->getId() == 95) {
continue;
}
if (!isset($attrTitles[$ao->getAttribute()->getId()])) {
$attrTitles[$ao->getAttribute()->getId()] = $ao->getAttribute()->getTitle(
$translator
);
}
$attrTitle = $attrTitles[$ao->getAttribute()->getId()];
if (!isset($attrOptTitles[$ao->getId()])) {
$attrOptTitles[$ao->getId()] = $ao->getTitle($translator);
}
$attrOptTitle = $attrOptTitles[$ao->getId()];
$attributeTitle = $this->removeSpecialCharacters($attrTitle);
if ($attributeTitle != '') {
$xml .= "<" . $attributeTitle . ">" . str_replace(
'&',
'&',
$attrOptTitle
) . "</" . $attributeTitle . ">";
}
}
$xml .= '<TERMEKHIBA>';
if (!is_null($stockItem->getErrorCodes()) && $stockItem->getErrorCodes() != '') {
$errors = '';
foreach (explode(' ', $stockItem->getErrorCodes()) as $errorCode) {
if ($errors != '') {
$errors .= ', ';
}
if (isset($errorCodeCache[$errorCode])) {
$errors .= $errorCodeCache[$errorCode];
continue;
}
$errorCodeEntity = $entityManager->getRepository(ErrorCode::class)->findOneByCode(
$errorCode
);
if ($errorCodeEntity) {
$errorCodeCache[$errorCode] = $errorCodeEntity->getHuText();
$errors .= $errorCodeEntity->getHuText();
}
}
$xml .= $errors;
}
$xml .= '</TERMEKHIBA>';
$xml .= "</SHOPITEM>\n";
}
} else {
$xml .= "<SHOPITEM>
<ITEM_ID>" . $product->getId() . "</ITEM_ID>
<CODE>" . $product->getCode() . "</CODE>
<EAN>" . $ean . "</EAN>
<NAME><![CDATA[" . $product->getFullTitle($translator) . "]]></NAME>
<VENDOR><![CDATA[" . $product->getVendor()->getName() . "]]></VENDOR>
<SHORT_DESCRIPTION><![CDATA[" . $product->getDescription() . "]]></SHORT_DESCRIPTION>
<DESCRIPTION><![CDATA[" . preg_replace(
'#<[^>]+>#',
' ',
$productMeta->getFullDescription($translator)
) . "]]></DESCRIPTION>
<IMAGE_URL>" . $image . "</IMAGE_URL>
<PRODUCT_URL>" . $seoUrlHelper->link('product', [
'product_id' => $product->getId(),
'isBazaar' => $product->isBazaar()
]) . "</PRODUCT_URL>
<PRICE>" . $price . "</PRICE>
<ORIGINAL_PRICE>" . $originalPrice . "</ORIGINAL_PRICE>
<SUGGESTED_PRICE>" . $suggestedVatPrice . "</SUGGESTED_PRICE>
<CATEGORY>$categoryValue</CATEGORY>
" . $parentCategoryTitle . "
" . $subCategories . "
<QUALITY>" . $this->getTranslator()->trans(
strtolower($qualityStatuses[$product->getQualityStatus()])
) . "</QUALITY>
<IN_STOCK>" . $product->getAvailable() . "</IN_STOCK>
<CREATED>" . $created . "</CREATED>
<UPDATED>" . $updated . "</UPDATED>
<IMAGES>" . $images . "</IMAGES>";
if ($product->getWeight() > 0) {
$xml .= "<Suly>" . number_format($product->getWeight() / 1000, 2, '.', '') . "</Suly>";
}
foreach ($product->getSpecificationProductAttributeOptions() as $pao) {
$ao = $pao->getOption();
if ($ao->getAttribute()->getId() == 95) {
continue;
}
if (!isset($attrTitles[$ao->getAttribute()->getId()])) {
$attrTitles[$ao->getAttribute()->getId()] = $ao->getAttribute()->getTitle(
$translator
);
}
$attrTitle = $attrTitles[$ao->getAttribute()->getId()];
if (!isset($attrOptTitles[$ao->getId()])) {
$attrOptTitles[$ao->getId()] = $ao->getTitle($translator);
}
$attrOptTitle = $attrOptTitles[$ao->getId()];
$attributeTitle = $this->removeSpecialCharacters($attrTitle);
if ($attributeTitle != '') {
$xml .= "<" . $attributeTitle . ">" . str_replace(
'&',
'&',
$attrOptTitle
) . "</" . $attributeTitle . ">";
}
}
$xml .= "</SHOPITEM>\n";
}
}
$xml .= '</SHOP>';
$cacheItem->set($xml);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_4_HOUR);
$cache->save($cacheItem);
}
$entityManager->flush();
$response = new Response($xml);
$response->headers->set('Content-Type', 'xml');
return $response;
}
return new Response('Something went wrong, please contact your sales manager!');
}
/**
* @return int[]
*/
private function getAccessoriesProductTypeIdList(): array
{
return [
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
20,
22,
23,
32,
33,
34,
45,
55,
56,
64,
65,
70,
71,
72,
85,
86,
103,
110,
113,
114,
124,
125,
145,
146,
147,
149,
150,
151,
152,
154,
155,
156,
160,
166,
167,
168,
174,
180,
181,
182,
184,
185,
186,
187,
192,
193,
198,
202,
];
}
/**
* @Route("/partner-product-list-download", name="product_partner_product_list_download", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function partnerProductListDownloadAction(Request $request): Response
{
$multistorHelper = $this->getMultiStoreHelper($request);
if ($multistorHelper->getCustomerTypeId() != MultiStore::CUSTOMER_TYPE_WHOLESALE) {
return new Response('Permission denied!');
}
$domain = $multistorHelper->getDomain();
$domainId = $domain->getId();
$currency = $this->getCurrencyISOForm($domain->getCurrency());
$entityManager = $this->getEntityManager();
$cache = $this->cache;
$cacheKeyOutputKey = 'partner.product.list.2021.' . $domain->getLanguage()->getCode();
$cacheKeyOutput = $cache->getItem($cacheKeyOutputKey);
$cacheKeyFilenameKey = 'partner.product.list.2021.' . $domain->getLanguage()->getCode() . '.filename';
$cacheKeyFilename = $cache->getItem($cacheKeyFilenameKey);
$cacheLastProductListUpdateKey = 'partner.product.list.last_update';
$cacheLastProductListUpdate = $cache->getItem($cacheLastProductListUpdateKey);
if (!$cacheKeyOutput->isHit() || !$cacheKeyFilename->isHit()) {
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p.id AND pm.domain = " . $domainId . "
WHERE p.archived = 0 AND p.available > 0 AND pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != " . Product::QualityStatus_Bazaar . "
ORDER BY p.code ASC")
->getResult();
$attributes = $entityManager->createQuery("SELECT DISTINCT(a.id) as id, a.title
FROM AtechNetCoreBundle:Attribute a
LEFT JOIN a.options ao
LEFT JOIN ao.productAttributes pa
LEFT JOIN pa.product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p.id AND pm.domain = " . $domainId . "
WHERE a.type = 'conf' AND p.archived = 0 AND p.available > 0 AND pm.active = 1 AND pm.orderable = 1
ORDER BY a.id ASC")
->getResult();
$attributeTitles = '';
foreach ($attributes as $a) {
$attributeTitles .= '<th>' . $a['title'] . '</th>';
}
$output = '<table>
<tr>
<th colspan="6">Generated: ' . (new \DateTime())->format('d.m.Y, H:i:s') . '</th>
</tr>
<tr>
<th>Code</th>
<th>Type</th>
<th>Brand</th>
<th width="200">Name</th>
<th>Quality</th>
<th>Config</th>
<th>In stock</th>
<th>Price [' . $currency . ']</th>
<th>Price + VAT [' . $currency . ']</th>
<th>Suggested price [' . $currency . ']</th>
<th>Suggested price + VAT [' . $currency . ']</th>
' . $attributeTitles . '
</tr>';
/**
* @var Product $product
*/
foreach ($products as $product) {
$productMeta = $product->getDomainMeta($domain);
$output .= '<tr>
<td>' . $product->getCode() . '</td>
<td>' . $product->getType()->getTitle() . '</td>
<td>' . $product->getVendor()->getName() . '</td>
<td width="200">' . $product->getName() . '</td>
<td>' . $product->getQualityStatusTitle($product->getQualityStatus()) . '</td>
<td>' . $product->getDescription() . '</td>
<td>' . $product->getAvailable() . '</td>
<td>' . ($productMeta->isDiscounted() ? $productMeta->getDomainDiscount() : $productMeta->getDomainPrice()) . '</td>
<td>' . ($productMeta->isDiscounted() ? $productMeta->getDomainVatDiscount() : $productMeta->getDomainVatPrice()) . '</td>
<td>' . $productMeta->getDomainSuggestedPrice() . '</td>
<td>' . $productMeta->getDomainVatSuggestedPrice() . '</td>
' . $this->createPartnerDownloadListAttributesForProduct($product, $attributes) . '
</tr>';
}
$output .= '</table>';
$filename = 'furbify_partner_product_export_' . $domain->getLanguage()->getCode() . '_' . date('Ymd-His') . '.xls';
$cacheKeyOutput->set($output);
$cacheKeyOutput->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheKeyOutput);
$cacheKeyFilename->set($filename);
$cacheKeyFilename->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheKeyFilename);
$cacheLastProductListUpdate->set((new \DateTime())->format('d.m.Y, H:i'));
$cacheLastProductListUpdate->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheLastProductListUpdate);
} else {
$output = $cache->getItem($cacheKeyOutputKey)->get();
$filename = $cache->getItem($cacheKeyFilenameKey)->get();
}
$response = new Response();
$response->headers->set('Content-Encoding', 'UTF-8');
$response->headers->set('Content-Type', 'application/vnd.ms-excel');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $filename);
$response->setContent($output);
return $response;
}
/**
* @Route("/partner-unas-product-list-download", name="product_partner_unas_product_list_download", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function partnerUnasProductListDownloadAction(Request $request): Response
{
$multistoreHelper = $this->getMultiStoreHelper($request);
if ($multistoreHelper->getCustomerTypeId() != MultiStore::CUSTOMER_TYPE_WHOLESALE) {
return new Response('Permission denied!');
}
$domain = $multistoreHelper->getDomain();
$domainId = $domain->getId();
$entityManager = $this->getEntityManager();
$translator = new DatabaseTranslator($entityManager, $domain->getId());
$cache = $this->cache;
$cacheKeyOutputKey = 'partner.unas.product.list.' . date('Y') . '.' . $domain->getLanguage()->getCode();
$cacheKeyOutput = $cache->getItem($cacheKeyOutputKey);
$cacheKeyFilenameKey = 'partner.unas.product.list.' . date('Y') . '.' . $domain->getLanguage()->getCode() . '.filename';
$cacheKeyFilename = $cache->getItem($cacheKeyFilenameKey);
$cacheLastProductListUpdateKey = 'partner.unas.product.list.last-update';
$cacheLastProductListUpdate = $cache->getItem($cacheLastProductListUpdateKey);
if (!$cacheKeyOutput->isHit() || !$cacheKeyFilename->isHit()) {
// UTF-8 BOM
$output = "\xEF\xBB\xBF";
// Header
$header = [
'Cikkszám',
'Termék Név',
'Státusz',
'Nettó Ár',
'Bruttó Ár',
'Kategória',
'Rövid Leírás',
'Tulajdonságok',
'Min. Menny.',
'Max. Menny.',
'Raktárkészlet',
'Egység',
'Kép link',
];
$output .= '"' . implode('";"', $header) . '"' . PHP_EOL;
// Products
$products = $entityManager->createQuery("SELECT p
FROM AtechNetCoreBundle:Product p
LEFT JOIN AtechNetCoreBundle:ProductMeta pm WITH pm.product = p.id AND pm.domain = " . $domainId . "
WHERE p.archived = 0 AND p.available > 0 AND pm.active = 1 AND pm.orderable = 1 AND p.qualityStatus != " . Product::QualityStatus_Bazaar . "
ORDER BY p.code ASC")
->getResult();
foreach ($products as $product) {
// Categories
$categories = [];
$mainCategory = '';
if ($product->getCategoryPages()->count() > 0) {
foreach ($product->getCategoryPages() as $categoryPage) {
if ($categoryPage->isPublished() && $categoryPage->getDomain()->getId() == $multistoreHelper->getRetailDomainByWholesaleDomain()->getId()) {
// Category
$category = '';
if ($categoryPage->getParentCategory()) {
if ($categoryPage->getParentCategory()->getParentCategory()) {
$categoryMeta = $categoryPage->getParentCategory()->getParentCategory()->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= $categoryMeta->getTitle();
}
}
$categoryMeta = $categoryPage->getParentCategory()->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= ($category !== '' ? '|' : '') . $categoryMeta->getTitle();
}
}
$categoryMeta = $categoryPage->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= ($category !== '' ? '|' : '') . $categoryMeta->getTitle();
}
if ($category !== '') {
$categories[] = $category;
}
}
}
}
if ($product->getType()->getCategoryPages()->count() > 0) {
foreach ($product->getType()->getCategoryPages() as $categoryPage) {
// The product falls into this category
$add = false;
if ($categoryPage->isPublished() && $categoryPage->getDomain()->getId() == $multistoreHelper->getRetailDomainByWholesaleDomain()->getId()) {
// Check by Vendor
foreach ($categoryPage->getVendors() as $vendor) {
if ($vendor->getId() == $product->getVendor()->getId()) {
$add = true;
break;
}
}
// Check by Badge
if ($categoryPage->getBadges()) {
$badges = json_decode($categoryPage->getBadges());
foreach ($badges as $badge) {
if (in_array($badge, $product->getBadges())) {
$add = true;
break;
}
}
}
// Main Category
if ($categoryPage->getVendors()->count() == 0 && $categoryPage->getBadges() == '') {
$add = true;
}
}
// Add
if ($add) {
// Category Tree
$category = '';
if ($categoryPage->getParentCategory()) {
if ($categoryPage->getParentCategory()->getParentCategory()) {
$categoryMeta = $categoryPage->getParentCategory()->getParentCategory()->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= $categoryMeta->getTitle();
}
}
$categoryMeta = $categoryPage->getParentCategory()->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= ($category !== '' ? '|' : '') . $categoryMeta->getTitle();
}
}
$categoryMeta = $categoryPage->getMetaByLanguage($domain->getLanguage());
if ($categoryMeta) {
$category .= ($category !== '' ? '|' : '') . $categoryMeta->getTitle();
}
if ($category !== '') {
$categories[] = $category;
}
}
}
}
if (!empty($categories)) {
foreach ($categories as $category) {
if (mb_strlen($category) > mb_strlen($mainCategory)) {
$mainCategory = $category;
}
}
}
// Attributes
$attributes = '';
if ($product->getVendor()->getName()) {
$attributes .= '<tr><td>' . $this->getTranslator()->trans('Brand') . '</td><td>' . $product->getVendor()->getName() . '</td></tr>';
}
foreach ($product->getSpecificationAttributeOptions() as $attributeOption) {
$attributes .= '<tr><td>' . $attributeOption->getAttribute()->getTitle($translator) . '</td><td>' . addslashes(($attributeOption->getLongTitle() == '' ? $attributeOption->getTitle($translator) : $attributeOption->getLongTitle($translator))) . '</td></tr>';
}
if ($attributes) {
$attributes = '<!HTML KOD><table>' . $attributes . '</table>';
}
$productMeta = $product->getDomainMeta($domain);
// Image
$image = '';
if (count($product->getAlbum()->getPhotos()) > 0) {
foreach ($product->getAlbum()->getPhotos() as $photo) {
$image = $this->getImage($photo, 'product/' . $product->getCode(), true)->resize(Image::PRODUCT_VIEW_POPUP_WIDTH, Image::PRODUCT_VIEW_POPUP_HEIGHT);
break;
}
}
if ($mainCategory !== '') {
$data = [
$product->getCode(),
addslashes($product->getName()),
1,
number_format($productMeta->getDomainVatSuggestedPrice() / (1 + ($domain->getVat() / 100)), 3, '.', ''),
$productMeta->getDomainVatSuggestedPrice(),
$mainCategory,
addslashes($product->getDescription()),
$attributes,
1,
'',
$product->getAvailable(),
$this->getTranslator()->trans('pc'),
$image,
];
$output .= '"' . implode('";"', $data) . '"' . PHP_EOL;
}
}
$filename = 'furbify-partner-unas-product-export-' . $domain->getLanguage()->getCode() . '-' . date('Ymd-His') . '.csv';
$cacheKeyOutput->set($output);
$cacheKeyOutput->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheKeyOutput);
$cacheKeyFilename->set($filename);
$cacheKeyFilename->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheKeyFilename);
$cacheLastProductListUpdate->set((new \DateTime())->format('d.m.Y, H:i'));
$cacheLastProductListUpdate->expiresAfter(self::CACHE_LIFETIME_1_HOUR);
$cache->save($cacheLastProductListUpdate);
} else {
$output = $cacheKeyOutput->get();
$filename = $cacheKeyFilename->get();
}
$response = new Response();
$response->headers->set('Content-Type', 'text/csv;charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $filename);
$response->setContent($output);
return $response;
}
/**
* @param Product $product
* @param $attributes
* @return string
*/
private function createPartnerDownloadListAttributesForProduct(Product $product, $attributes): string
{
$attributesOutput = '';
$productattributesArray = [];
/**
* @var AttributeOption $ao
*/
foreach ($product->getSpecificationAttributeOptions() as $ao) {
$productattributesArray[$ao->getAttribute()->getId()] = $ao->getLongTitle() == '' ? $ao->getTitle() : $ao->getLongTitle();
}
foreach ($attributes as $attr) {
if (isset($productattributesArray[$attr['id']])) {
$attributesOutput .= '<td>' . $productattributesArray[$attr['id']] . '</td>';
} else {
$attributesOutput .= '<td></td>';
}
}
return $attributesOutput;
}
/**
* @param ProductMeta $productMeta
* @return int
*/
private function calculateSuggestedPrice(ProductMeta $productMeta): int
{
$product = $productMeta->getProduct();
$productTypeId = $product->getType()->getId();
$sellingPrice = $productMeta->isDiscounted() ? $productMeta->getDiscount() : $productMeta->getPrice();
if ($productTypeId == 52 || $productTypeId == 60) { // PC or NB
$suggestedPrice = $sellingPrice < 150 ? $sellingPrice + 40 : $sellingPrice + 50;
} elseif ($productTypeId == 44) { // Monitor
$suggestedPrice = $sellingPrice < 60 ? $sellingPrice + 10 : $sellingPrice + 15;
} else {
$suggestedPrice = $sellingPrice < 10 ? $sellingPrice + 10 : $sellingPrice + 15;
}
return $suggestedPrice;
}
/**
* @param CategoryPage $categoryPage
* @param $productTypeId
* @return bool
*/
private function categoryHasProductType(CategoryPage $categoryPage, $productTypeId): bool
{
foreach ($categoryPage->getProductTypes() as $productType) {
if ($productType->getId() == $productTypeId) {
return true;
}
}
return false;
}
/**
* @Route("/partner-label-download/{id}", name="product_partner_label_download", defaults={"_locale":""})
* @param Request $request
* @param int $id
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
* @throws \Mpdf\MpdfException
*/
public function productPriceLabelAction(Request $request, int $id)
{
$priceOnLabel = $request->request->get('print-label-price');
if (!$this->getLoginHelper($request)->isLoggedIn()
|| $this->getCustomerTypeId($request) != MultiStore::CUSTOMER_TYPE_WHOLESALE
|| is_null($priceOnLabel)
|| !is_numeric($priceOnLabel)) {
return $this->redirectToRoute('homepage');
}
$labelsWanted = [
ProductType::PRODUCT_TYPE_ID_MONITOR => [
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_BRIGHTNESS,
Attribute::ATTRIBUTE_ID_CONTRAST,
Attribute::ATTRIBUTE_ID_RESPONSE_TIME,
Attribute::ATTRIBUTE_ID_VIEW_ANGLES,
Attribute::ATTRIBUTE_ID_ASPECT_RATIO,
Attribute::ATTRIBUTE_ID_GRAPHIC_INPUTS,
],
ProductType::PRODUCT_TYPE_ID_NOTEBOOK => [
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_CPU_NB,
Attribute::ATTRIBUTE_ID_RAM_NB,
Attribute::ATTRIBUTE_ID_SSD,
Attribute::ATTRIBUTE_ID_SSHD35,
Attribute::ATTRIBUTE_ID_HDD_25,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_VGA,
Attribute::ATTRIBUTE_ID_WEBCAM,
Attribute::ATTRIBUTE_ID_EXTERNAL_CONNECTORS,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC => [
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,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_PC_SET => [
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,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_ALL_IN_ONE => [
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,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
],
ProductType::PRODUCT_TYPE_ID_SMARTPHONE => [
Attribute::ATTRIBUTE_ID_QUALITY,
Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM,
Attribute::ATTRIBUTE_ID_SCREEN_SIZE,
Attribute::ATTRIBUTE_ID_MAXIMUM_RESOLUTION,
Attribute::ATTRIBUTE_ID_CPU_PHONE,
Attribute::ATTRIBUTE_ID_DISPLAY,
Attribute::ATTRIBUTE_ID_RAM,
],
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_CPU => [
Attribute::ATTRIBUTE_ID_CPU_PC_FAMILY,
Attribute::ATTRIBUTE_ID_CPU_GENERATION,
Attribute::ATTRIBUTE_ID_CLOCKSPEED,
Attribute::ATTRIBUTE_ID_CPU_SOCKET,
],
ProductType::PRODUCT_TYPE_ID_RAM_PC => [
Attribute::ATTRIBUTE_ID_MEMORY_TYPE,
Attribute::ATTRIBUTE_ID_MEMORY_SIZE,
Attribute::ATTRIBUTE_ID_MEMORY_FREQUENCY,
],
];
$product = $this->getEntityManager()->getRepository(Product::class)->findOneById($id);
if ($product) {
$productHelper = $this->getProductHelper($request);
$multistoreHelper = $this->getMultiStoreHelper($request);
$domain = $multistoreHelper->getDomain();
$currency = $domain->getCurrency();
$productData = $productHelper->getStructuredDataForProduct($product);
$labelAttributes = [];
foreach ($labelsWanted[$productData['productTypeId']] as $labelWantedKey) {
foreach ($productData['attributes'] as $attributeKey => $attribute) {
if ($labelWantedKey == $attributeKey) {
$labelAttributes[$attributeKey]['title'] = $attribute['title'];
foreach ($attribute['options'] as $option) {
if (isset($labelAttributes[$attributeKey]['value'])) {
$labelAttributes[$labelWantedKey]['value'] .= ', ';
} else {
$labelAttributes[$labelWantedKey]['value'] = '';
}
$labelAttributes[$labelWantedKey]['value'] .= ($option['multiplier'] > 0 ? $option['multiplier'] . ' x ' : '') . $option['title'];
}
}
}
}
$productData['warrantyYear'] = $this->getWarrantyForProductType($domain->getId(), $productData['productTypeId'])['year'];
$html = $this->getTwig()->render('AtechNetCoreBundle/PDF/productLabel.html.twig', [
'product' => $productData,
'currency' => $currency,
'labelAttributes' => $labelAttributes,
'priceOnLabel' => $priceOnLabel,
]);
$defaultConfig = (new ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = (new FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$pdf = new Mpdf([
'mode' => 'utf-8',
'format' => 'A6',
'default_font_size' => 9,
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/../Resources/public/fonts',
]),
'fontdata' => $fontData + [
'montserrat-normal' => [
'R' => 'Montserrat-Regular.ttf',
],
'montserrat-bold' => [
'R' => 'Montserrat-ExtraBold.ttf',
],
],
'default_font' => 'montserrat-normal',
]);
$pdf->shrink_tables_to_fit = true;
$pdf->WriteHTML($html);
return new Response(
$pdf->output(
$product->getCode() . '_' . (new \DateTime())->format('YmdHi') . '.pdf',
'I'
),
Response::HTTP_OK,
[
'content-type' => 'application/pdf',
]
);
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/prislusenstvo", name="product_accessories_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/prislusenstvo", name="product_accessories_sk_locale", defaults={"_locale":""})
* @Route("/kiegeszitok", name="product_accessories_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/kiegeszitok", name="product_accessories_hu_locale", defaults={"_locale":""})
* @Route("/prislusenstvi", name="product_accessories_cz", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/prislusenstvi", name="product_accessories_cz_locale", defaults={"_locale":""})
* @Route("/accessories", name="product_accessories_en", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/accessories", name="product_accessories_en_locale", defaults={"_locale":""})
* @Route("/pislusenstvi", name="product_accessories_cz_to_redirect", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function accessoriesAction(Request $request): Response
{
$data = [];
$translator = $this->getTranslator();
if ($request->get('_route') == 'product_accessories_cz_to_redirect') {
return $this->redirectToRoute('product_accessories_cz', [], 301);
}
$multiStore = $this->getMultiStoreHelper($request);
$domain = $multiStore->getDomain();
$cache = $this->cache;
$cacheKey = 'accessories.page.v6.' . $domain->getId() . '.' . $request->getLocale();
$cacheItem = $cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
$data['sections'] = $cacheItem->get();
} else {
$entityManager = $this->getEntityManager();
$productRepo = $entityManager->getRepository(Product::class);
$seoUrlHelper = $this->getSeoUrlHelper($request);
$productHelper = $this->getProductHelper($request);
$data['sections'] = $productRepo->getAccessoriesSections($domain, $seoUrlHelper, $productHelper, $multiStore);
$cacheItem->set($data['sections']);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_4_HOUR);
$cache->save($cacheItem);
}
if (!empty($data['sections'])) {
$data['seoTitle'] = $translator->trans('Accessories SEO title');
$data['seoDescription'] = $translator->trans('Accessories SEO description');
$data['canonical_link'] = '';
$data['breadcrumbs'] = [
$this->getBreadCrumbsBase($request),
[
'text' => $translator->trans('Accessories'),
'href' => '',
],
];
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
return $this->render('AtechNetCoreBundle/Product/parts.html.twig', $data);
}
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
/**
* @Route("/egyeb-eszkozok", name="product_other_categories_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/egyeb-eszkozok", name="product_other_categories_hu_locale", defaults={"_locale":""})
* @Route("/dalsie-kategorie", name="product_other_categories_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/dalsie-kategorie", name="product_other_categories_sk_locale", defaults={"_locale":""})
* @Route("/dalsi-kategorie", name="product_other_categories_cz", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/dalsi-kategorie", name="product_other_categories_cz_locale", defaults={"_locale":""})
* @Route("/other-categories", name="product_other_categories_en", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/other-categories", name="product_other_categories_en_locale", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function otherCategoriesAction(Request $request): Response
{
$data = [];
$translator = $this->getTranslator();
$multiStore = $this->getMultiStoreHelper($request);
$domain = $multiStore->getDomain();
$cache = $this->cache;
$cacheKey = 'other.categories.page.v1.' . $domain->getId() . '.' . $request->getLocale();
$cacheItem = $cache->getItem($cacheKey);
if ($request->get('_route') == 'product_other_categories_sk' && $domain->getLanguage()->getCode() == 'cz') {
return $this->redirectToRoute('product_other_categories_cz', [], 301);
} elseif ($request->get('_route') == 'product_other_categories_cz' && $domain->getLanguage()->getCode() == 'sk') {
return $this->redirectToRoute('product_other_categories_sk', [], 301);
} elseif ($request->get('_route') == 'product_other_categories_sk_locale' && $domain->getLanguage()->getCode() == 'cz') {
return $this->redirectToRoute('product_other_categories_cz_locale');
} elseif ($request->get('_route') == 'product_other_categories_cz_locale' && $domain->getLanguage()->getCode() == 'sk') {
return $this->redirectToRoute('product_other_categories_sk_locale');
}
if ($cacheItem->isHit()) {
$data['sections'] = $cacheItem->get();
} else {
$entityManager = $this->getEntityManager();
$productRepo = $entityManager->getRepository(Product::class);
$seoUrlHelper = $this->getSeoUrlHelper($request);
$productHelper = $this->getProductHelper($request);
$data['sections'] = $productRepo->getOtherProductsSection($domain, $seoUrlHelper, $productHelper, $multiStore);
$cacheItem->set($data['sections']);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_4_HOUR);
$cache->save($cacheItem);
}
if (!empty($data['sections'])) {
$data['seoTitle'] = $translator->trans('Other categories title');
$data['seoDescription'] = $translator->trans('Other categories description');
$data['canonical_link'] = '';
$data['breadcrumbs'] = [
$this->getBreadCrumbsBase($request),
[
'text' => $translator->trans('Other categories title'),
'href' => '',
],
];
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
return $this->render('AtechNetCoreBundle/Product/parts.html.twig', $data);
}
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
/**
* @Route("/zsakbamacska", name="product_zsakbamacska_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/zsakbamacska", name="product_zsakbamacska_hu_locale", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function zsakbamacskaAction(Request $request): Response
{
$multiStore = $this->getMultiStoreHelper($request);
$productHelper = $this->getProductHelper($request);
$domain = $multiStore->getDomain();
$domainId = $domain->getId();
// Default Locale
$defaultLocale = $multiStore->getDefaultLocale();
$data = [];
$data['warrantyYear'] = $this->getWarrantyForNonProductText($domainId);
$data['priceWarrantyDay'] = $this->getWarrantyForNonProductText($domainId, 'priceWarrantyDay');
$translator = $this->getTranslator();
$data['seoTitle'] = $translator->trans('Parts SEO title');
$data['seoDescription'] = $translator->trans('Furbicat description');
$data['canonical_link'] = '';
$data['breadcrumbs'] = [
$this->getBreadCrumbsBase($request),
[
'text' => $translator->trans('Furbify zsakbamacska title'),
'href' => '',
],
];
$data['services_link'] = $this->url($request)->link('page', [
'static_id' => $this->getServicesPageLink($defaultLocale),
]);
$data['free_ship_limit'] = $productHelper::getFreeShipLimits()[$domainId]['freeShipLimit'];
$deliveryDate = (new DeliveryDate())->getEstimatedDeliveryDate($domainId, false, false);
$day = $deliveryDate->format('d.m.Y') . ', ' . $this->getTranslator()->trans($deliveryDate->format('l'));
$data['estimated_deliver_date'] = $this->getTranslator()->trans('Estimated deliver is {day}', [
'day' => $day,
]);
$data['heading_title'] = $data['h1_title'] = $translator->trans('Furbify zsakbamacska title');
$data['webshop_phone_number'] = $this->getContactInfos()['phone.webshop.' . $domain->getLanguage()->getCode() . '.' . $domain->getType()];
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
return $this->render('AtechNetCoreBundle/Product/zsakbamacska.html.twig', $data);
}
/**
* @Route("/komponenty", name="product_parts_sk", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/komponenty", name="product_parts_sk_locale", defaults={"_locale":""})
* @Route("/alkatreszek", name="product_parts_hu", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/alkatreszek", name="product_parts_hu_locale", defaults={"_locale":""})
* @Route("/komponenty", name="product_parts_cz", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/komponenty", name="product_parts_cz_locale", defaults={"_locale":""})
* @Route("/components", name="product_parts_en", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/components", name="product_parts_en_locale", defaults={"_locale":""})
* @param Request $request
* @return Response
* @throws \Exception
*/
public function partsAction(Request $request): Response
{
$data = [];
$translator = $this->getTranslator();
$multiStore = $this->getMultiStoreHelper($request);
$domain = $multiStore->getDomain();
$cache = $this->cache;
$cacheKey = 'parts.page.v2.' . $domain->getId() . '.' . $request->getLocale();
$cacheItem = $cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
$data['sections'] = $cacheItem->get();
} else {
$entityManager = $this->getEntityManager();
$productRepo = $entityManager->getRepository(Product::class);
$seoUrlHelper = $this->getSeoUrlHelper($request);
$productHelper = $this->getProductHelper($request);
$data['sections'] = $productRepo->getPartsSections($domain, $seoUrlHelper, $productHelper, $multiStore);
$cacheItem->set($data['sections']);
$cacheItem->expiresAfter(self::CACHE_LIFETIME_4_HOUR);
$cache->save($cacheItem);
}
if (!empty($data['sections'])) {
$data['seoTitle'] = $translator->trans('Parts SEO title');
$data['seoDescription'] = $translator->trans('Parts SEO description');
$data['canonical_link'] = '';
$data['breadcrumbs'] = [
$this->getBreadCrumbsBase($request),
[
'text' => $translator->trans('Parts title'),
'href' => '',
],
];
$data['partnerLoginRedirect'] = false;
if (!is_null($request->query->get('partner-link')) && $request->query->get('partner-link') == 1 && !$this->getLoginHelper($request)->isLoggedIn()) {
$data['partnerLoginRedirectRoute'] = $this->generateUrl('partner_login');
$data['partnerLoginRedirect'] = true;
}
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
return $this->render('AtechNetCoreBundle/Product/parts.html.twig', $data);
}
return $this->forward('App\AtechNet\CoreBundle\Controller\DefaultController::notFoundAction');
}
/**
* @Route("/product/price-monitor/add", name="product_price_monitor", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/price-monitor/add", name="product_price_monitor_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function addProductPriceMonitorAction(Request $request): JsonResponse
{
$json = [];
$translator = $this->getTranslator();
$email = $request->request->get('email');
if (empty($email)) {
$json['error'] = $translator->trans('E-Mail address required');
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) || !checkdnsrr(substr($email, strpos($email, "@") + 1))) {
$json['error'] = $translator->trans('E-Mail address does not appear to be valid');
}
if (empty($request->request->get('name'))) {
$json['error'] = $translator->trans('Name required');
}
if (empty($request->request->get('price'))) {
$json['error'] = $translator->trans('Price required');
} else {
$price = preg_replace("/[^0-9.]/", '', $request->request->get('price'));
if ((float)$price <= 0) {
$json['error'] = $translator->trans('Invalid price');
}
}
if (empty($request->request->get('sourcePrice'))) {
$json['error'] = $translator->trans('Source price required');
}
if (empty($request->request->get('productId'))) {
$json['error'] = $translator->trans('Product not found');
}
$entityManager = $this->getEntityManager();
if (empty($json)) {
// Product
$product = $entityManager->getRepository(Product::class)->findOneById($request->request->get('productId'));
if ($product) {
$multiStore = $this->getMultiStoreHelper($request);
// Price Check
$priceMeta = $product->getDomainMeta($multiStore->getDomain());
$productPrice = $priceMeta->getDomainVatPrice();
$productSpecialPrice = 0;
if ($priceMeta->isDiscounted()) {
$productSpecialPrice = $priceMeta->getDomainVatDiscount();
}
if (($productSpecialPrice > 0 && (float)$price > $productSpecialPrice) || ($productSpecialPrice == 0 && (float)$price > $productPrice)) {
$json['error'] = $translator->trans('Price must be lower than current price');
} else {
// Notification Details
$customerNotification = new CustomerNotification();
// Domain
$domain = $multiStore->getDomain();
$customerNotification->setDomain($domain);
// Product
$customerNotification->setProduct($product);
// Customer
$loggedInCustomerId = $request->getSession()->get('customerId');
if (is_numeric($loggedInCustomerId)) {
$customer = $entityManager->getRepository(Customer::class)->findOneById($loggedInCustomerId);
if ($customer) {
$customerNotification->setCustomer($customer);
}
}
// Visitor
$identifier = null;
if (is_null($customerNotification->getCustomer())) {
$identifier = hash('sha512', $request->getClientIp() . $request->server->get('HTTP_USER_AGENT'), false);
$customerNotification->setVisitor($identifier);
}
// Type
$customerNotification->setType(CustomerNotification::TYPE_PRICE_MONITOR);
// E-mail
$customerNotification->setEmail($request->request->get('email'));
// Name
$customerNotification->setName($request->request->get('name'));
// Price
$customerNotification->setPrice((float)$request->request->get('price'));
// SourcePrice
$customerNotification->setSourcePrice((float)$request->request->get('sourcePrice'));
// Unsubscribe Key
$customerNotification->setUnsubscribeKey(bin2hex(random_bytes(16)));
// Check duplicity
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder
->select('cn')
->from('AtechNetCoreBundle:CustomerNotification', 'cn')
->where('cn.product = :product')->setParameter(':product', $product)
->andWhere('cn.domain = :domain')->setParameter(':domain', $domain);
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('cn.customer', ':customer'),
$queryBuilder->expr()->eq('cn.email', ':email')
)
)
->setParameter(':customer', $customerNotification->getCustomer())
->setParameter(':email', $customerNotification->getEmail());
if (!is_null($identifier)) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('cn.visitor', ':visitor')
)
)
->setParameter(':visitor', $identifier);
}
$query = $queryBuilder->setMaxResults(1)->getQuery();
$exists = $query->getResult();
if (empty($exists)) {
$entityManager->persist($customerNotification);
$entityManager->flush();
if (!is_null($customerNotification->getCustomer()) && $customerNotification->getCustomer()->getDomain()->getId() == Domain::DOMAIN_ID_WS_HU) {
$notificationEmailAddress = '';
if ($this->getEnvironment() == 'prod') {
switch ($multiStore->getCustomerTypeId()) {
case MultiStore::CUSTOMER_TYPE_RETAIL:
$notificationEmailAddress = 'webshop@furbify.eu';
break;
case MultiStore::CUSTOMER_TYPE_WHOLESALE:
$notificationEmailAddress = $customerNotification->getCustomer()->getSalesManager()->getEmail();
break;
}
} else {
$notificationEmailAddress = 'YOUR_TEST_EMAIL_ADDRESS';
}
if ($notificationEmailAddress != '') {
$mailer = $this->getMailer();
$email = (new TemplatedEmail())
->subject('New price monitor setting: ' . $customerNotification->getName() . ' - ' . $product->getName())
->to($notificationEmailAddress)
->htmlTemplate('AtechNetCoreBundle/Email/priceMonitorCustomerServiceNotification.html.twig')
->context([
'customerName' => $customerNotification->getName(),
'productCode' => $product->getCode(),
'productTitle' => $product->getName(),
'wantedPrice' => $customerNotification->getPrice(),
'currentPrice' => $customerNotification->getSourcePrice(),
'currency' => $domain->getCurrency(),
]);
$mailer->send($email);
}
}
$json['success'] = true;
} else {
$json['error'] = $translator->trans('You have already set up price monitoring for this product');
}
}
} else {
$json['error'] = $translator->trans('Product not found');
}
}
return new JsonResponse($json);
}
/**
* @Route("/product/price-monitor/unsubscribe", name="product_price_monitor_remove", defaults={"_locale":""})
* @param Request $request
* @return RedirectResponse
*/
public function removeProductPriceMonitorAction(Request $request): RedirectResponse
{
$entityManager = $this->getEntityManager();
$multiStore = $this->getMultiStoreHelper($request);
$productId = $request->query->get('p');
$email = base64_decode($request->query->get('u'));
$unsubscribeKey = base64_decode($request->query->get('k'));
$domain = $multiStore->getDomain();
$customerNotifications = $entityManager->createQuery("SELECT cn FROM AtechNetCoreBundle:CustomerNotification cn WHERE cn.domain = :domain AND cn.product = :product AND cn.email = :email")
->setParameters([
'domain' => $domain,
'product' => $productId,
'email' => $email,
])
->getResult();
if ($customerNotifications) {
/** @var CustomerNotification $customerNotification */
foreach ($customerNotifications as $customerNotification) {
if (password_verify($email . 'fu' . $customerNotification->getUnsubscribeKey() . 'fy', $unsubscribeKey)) {
// Redirect Url
$seoUrl = $this->url($request);
$redirect = $seoUrl->link('product', [
'product_id' => $customerNotification->getProduct()->getId(),
'isBazaar' => $customerNotification->getProduct()->isBazaar()
]);
// Remove
$entityManager->remove($customerNotification);
$entityManager->flush();
return $this->redirect($redirect, 301);
}
}
}
return $this->redirectToRoute('not_found');
}
/**
* @Route("/product/stock-monitor/add", name="product_stock_monitor")
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function addProductStockMonitorAction(Request $request): JsonResponse
{
$json = [];
$translator = $this->getTranslator();
$email = $request->request->get('email');
if (empty($email)) {
$json['error'] = $translator->trans('E-Mail address required');
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) || !checkdnsrr(substr($email, strpos($email, "@") + 1))) {
$json['error'] = $translator->trans('E-Mail address does not appear to be valid');
}
if (empty($request->request->get('name'))) {
$json['error'] = $translator->trans('Name required');
}
if (empty($request->request->get('productId'))) {
$json['error'] = $translator->trans('Product not found');
}
if (!empty($json)) {
return new JsonResponse($json);
}
$entityManager = $this->getEntityManager();
// Product
$product = $entityManager->getRepository(Product::class)->findOneById($request->request->get('productId'));
if (!$product) {
$json['error'] = $translator->trans('Product not found');
return new JsonResponse($json);
}
// Notification Details
$customerNotification = new CustomerNotification();
$multiStore = $this->getMultiStoreHelper($request);
// Domain
$domain = $multiStore->getDomain();
$customerNotification->setDomain($domain);
// Product
$customerNotification->setProduct($product);
// Customer
$loggedInCustomerId = $request->getSession()->get('customerId');
if (is_numeric($loggedInCustomerId)) {
$customer = $entityManager->getRepository(Customer::class)->findOneById($loggedInCustomerId);
if ($customer) {
$customerNotification->setCustomer($customer);
}
}
// Visitor
$identifier = null;
if (is_null($customerNotification->getCustomer())) {
$identifier = hash('sha512', $request->getClientIp() . $request->server->get('HTTP_USER_AGENT'), false);
$customerNotification->setVisitor($identifier);
}
// Type
$customerNotification->setType(CustomerNotification::TYPE_STOCK_MONITOR);
// E-mail
$customerNotification->setEmail($request->request->get('email'));
// Name
$customerNotification->setName($request->request->get('name'));
// Unsubscribe Key
$customerNotification->setUnsubscribeKey(bin2hex(random_bytes(16)));
// Check duplicity
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder
->select('cn')
->from('AtechNetCoreBundle:CustomerNotification', 'cn')
->where('cn.product = :product')->setParameter(':product', $product)
->andWhere('cn.domain = :domain')->setParameter(':domain', $domain);
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('cn.customer', ':customer'),
$queryBuilder->expr()->eq('cn.email', ':email')
)
)
->setParameter(':customer', $customerNotification->getCustomer())
->setParameter(':email', $customerNotification->getEmail());
if (!is_null($identifier)) {
$queryBuilder
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('cn.visitor', ':visitor')
)
)
->setParameter(':visitor', $identifier);
}
$query = $queryBuilder->setMaxResults(1)->getQuery();
$exists = $query->getResult();
if (!empty($exists)) {
$json['error'] = $translator->trans('You have already set up stock monitoring for this product');
return new JsonResponse($json);
}
$entityManager->persist($customerNotification);
$entityManager->flush();
if (!is_null($customerNotification->getCustomer()) && $customerNotification->getCustomer()->getDomain()->getId() == Domain::DOMAIN_ID_WS_HU) {
$notificationEmailAddress = '';
if ($this->getEnvironment() == 'prod') {
switch ($multiStore->getCustomerTypeId()) {
case MultiStore::CUSTOMER_TYPE_RETAIL:
$notificationEmailAddress = 'webshop@furbify.eu';
break;
case MultiStore::CUSTOMER_TYPE_WHOLESALE:
$notificationEmailAddress = $customerNotification->getCustomer()->getSalesManager()->getEmail();
break;
}
} else {
$notificationEmailAddress = 'lakasand@gmail.com';
}
if ($notificationEmailAddress != '') {
$mailer = $this->getMailer();
$email = (new TemplatedEmail())
->subject("New price monitor setting: {$customerNotification->getName()} - {$product->getName()}")
->to($notificationEmailAddress)
->htmlTemplate('AtechNetCoreBundle/Email/priceMonitorCustomerServiceNotification.html.twig')
->context([
'customerName' => $customerNotification->getName(),
'productCode' => $product->getCode(),
'productTitle' => $product->getName(),
'wantedPrice' => $customerNotification->getPrice(),
'currentPrice' => $customerNotification->getSourcePrice(),
'currency' => $domain->getCurrency(),
]);
$mailer->send($email);
}
}
$json['success'] = true;
return new JsonResponse($json);
}
/**
* @Route("/product/get/admin-login-panel-data", name="product_admin_login_data_ajax", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/admin-login-panel-data", name="product_admin_login_data_ajax_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
*/
public function getDataForAdminLoginPanelAjaxAction(Request $request): JsonResponse
{
$productId = $request->get('productId') ?? false;
$entityManager = $this->getEntityManager();
$productRepo = $entityManager->getRepository(Product::class);
$product = $productRepo->findOneById($productId);
$data = [
'avaragePurchasePrie' => $product->getAvgPrice(),
'lastPurchasePrice' => $product->getLastPrice(),
'inStock' => $product->getInStock(),
'available' => $product->getAvailable(),
];
return new JsonResponse($data);
}
/**
* @Route("/product/get/stock-item-albums", name="product_stock_item_albums_ajax", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/stock-item-albums", name="product_stock_item_albums_ajax_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
*/
public function getStockItemAlbumsAjaxAction(Request $request): JsonResponse
{
$productId = $request->get('productId') ?? false;
$entityManager = $this->getEntityManager();
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
$albums = $entityManager->getRepository(Product::class)->getStockItemAlbums(
$productId,
$product->isContainer(),
);
$selectedStockItems = $request->getSession()->get('stockItemCodes')[$productId] ?? false;
if ($selectedStockItems) {
foreach ($selectedStockItems as $stockItemCode) {
foreach ($albums as $key => $album) {
if ($album['aikenCode'] == $stockItemCode) {
$albums[$key]['selected'] = true;
}
}
}
}
return new JsonResponse($albums);
}
/**
* @Route("/product/get/album-images", name="product_album_images_ajax", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/album-images", name="product_album_images_ajax_locale", defaults={"_locale":""})
* @param Request $request
* @return JsonResponse
* @throws \Exception
*/
public function getAlbumImagesAjaxAction(Request $request): JsonResponse
{
$albumId = $request->get('albumId') ?? false;
$productHelper = $this->getProductHelper($request);
$images = $productHelper->getAlbumImages($albumId);
return new JsonResponse($images);
}
/**
* @Route("/product/get/error-codes", name="product_error_codes_ajax", defaults={"_locale":""})
* @Route("/{_locale<%supported_locales%>?}/product/get/error-codes", name="product_error_codes_ajax_locale", defaults={"_locale":""})
*/
public function getErrorCodesForStockItemAjaxAction(Request $request): JsonResponse
{
$aikenCode = $request->get('aikenCode') ?? false;
$languageCode = $this->getMultiStoreHelper($request)->getDomain()->getLanguage()->getCode();
$si = $this->getEntityManager()->getRepository(StockItem::class)->findOneBy(['aikenCode' => $aikenCode]);
$errors = $this->getEntityManager()->getRepository(Product::class)->getVisibleErrorCodes($si);
return new JsonResponse(
array_map(fn(ErrorCode $ec) => $ec->getTextForLanguage($languageCode), $errors)
);
}
/**
* @Route("/porovnanie", name="product_compare_sk")
* @Route("/osszehasonlitas", name="product_compare_hu")
* @Route("/porovnani", name="product_compare_cz")
* @Route("/compare", name="product_compare_en")
* @param Request $request
* @return Response
*/
public function compareAction(Request $request): Response
{
$data = [];
// Entity Manager
$entityManager = $this->getEntityManager();
// Multi-store
$multiStore = $this->getMultiStoreHelper($request);
// Translator (database)
$databaseTranslator = $this->getDatabaseTranslator($request);
// Translator
$translator = $this->getTranslator();
// Session
$session = $request->getSession();
// Domain
$domain = $multiStore->getDomain();
// Collection
if ($session->has('productCompare')) {
$collection = $session->get('productCompare');
} else {
$collection = [];
}
// Reverse Order
$collection = array_reverse($collection);
// Placeholder
$placeholder = $image = $this->getImage('placeholder.jpg', '')->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
// Specification Attributes
$specificationAttributes = [];
// Products
$products = [];
foreach ($collection as $productId) {
/** @var Product $product */
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
if ($product) {
// Meta
$priceMeta = $product->getDomainMeta($domain);
// Product Image
if ($product->getAlbum() && $product->getAlbum()->getPhotos()->count() > 0) {
$image = $this->getImage($product->getAlbum()->getPhotos()->first(), 'product/' . $product->getCode())->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
} else {
$image = $placeholder;
}
// Product Price
if ($priceMeta->isDiscounted()) {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatDiscount() : $priceMeta->getDomainDiscount();
} else {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatPrice() : $priceMeta->getDomainPrice();
}
// WebCam Included
$isWebcamIncluded = false;
// Specification
$specification = [];
foreach ($product->getSpecificationProductAttributeOptions() as $spec) {
$option = $spec->getOption();
$attribute = $option->getAttribute();
$attributeId = $attribute->getId();
if ($attributeId == Attribute::ATTRIBUTE_ID_QUALITY || ($attributeId == Attribute::ATTRIBUTE_ID_OPERATING_SYSTEM && in_array($domain->getId(), [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]))) {
continue;
}
// Specification Attribute
if (!isset($specificationAttributes[$attributeId])) {
$specificationAttributes[$attributeId] = [
'id' => $attributeId,
'title' => $attribute->getTitle($databaseTranslator),
'sortIndex' => $attribute->getSortIndex(),
];
}
// Specfication
if (!isset($specification[$attributeId])) {
$specification[$attributeId] = [];
if ($attributeId == Attribute::ATTRIBUTE_ID_WEBCAM) {
$isWebcamIncluded = true;
}
}
$title = $option->getLongTitle($databaseTranslator);
if (empty($title)) {
$title = $option->getTitle($databaseTranslator);
}
$specification[$attributeId][$spec->getId()] = [
'id' => $spec->getId(),
'attributeOptionId' => $option->getId(),
'title' => $title,
'shortTitle' => $option->getTitle($databaseTranslator),
'multiplier' => $spec->getMultiplier(),
];
}
// WebCam
if (!$isWebcamIncluded && $product->getType()->getId() == ProductType::PRODUCT_TYPE_ID_NOTEBOOK) {
// Attribute
$attribute = $entityManager->getRepository(Attribute::class)->findOneById(Attribute::ATTRIBUTE_ID_WEBCAM);
if ($attribute) {
// Specification Attribute
if (!isset($specificationAttributes[Attribute::ATTRIBUTE_ID_WEBCAM])) {
$specificationAttributes[Attribute::ATTRIBUTE_ID_WEBCAM] = [
'id' => Attribute::ATTRIBUTE_ID_WEBCAM,
'title' => $attribute->getTitle($databaseTranslator),
'sortIndex' => $attribute->getSortIndex(),
];
}
// Specification
$specification[Attribute::ATTRIBUTE_ID_WEBCAM][1773] = [
'id' => 1773,
'title' => $translator->trans('No'),
'shortTitle' => $translator->trans('No'),
'multiplier' => 0,
];
}
}
if ($priceMeta->isReady() && $priceMeta->isActive() && $product->isReservable()) {
$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;
}
// Weight
$weight = ($product->getWeight() != 0 ? number_format($product->getWeight() / 1000, 1, ',', ' ') . ' kg' : '');
// Dimensions
$dimensions = [];
if ($product->getWidth() != 0) {
$dimensions[] = $product->getWidth() . ' mm';
}
if ($product->getLength() != 0) {
$dimensions[] = $product->getLength() . ' mm';
}
if ($product->getHeight() != 0) {
$dimensions[] = $product->getHeight() . ' mm';
}
$dimensions = !empty($dimensions) ? implode(' x ', $dimensions) : '';
// Product Data
$products[] = [
'id' => $product->getId(),
'href' => $this->url($request)->link('product', [
'product_id' => $product->getId(),
'isBazaar' => $product->isBazaar()
]),
'name' => $product->getFullTitle($databaseTranslator),
'image' => $image,
'price' => $price,
'brand' => $product->getVendor()->getName(),
'model' => in_array($domain->getId(), [Domain::DOMAIN_ID_RT_EU, Domain::DOMAIN_ID_WS_EU]) ? str_replace([' (Quality: Bazar)', ' (Quality: Bazár)', ' (Quality: Bazár, '], ['', '', ' ('], $product->getName()) : $product->getName(),
'code' => $product->getCode(),
'available' => $product->getAvailable(),
'orderWaitingDays' => $orderWaitingDays,
'quality' => $product->getQualityStatusTitle($product->getQualityStatus()),
'specification' => $specification,
'dimensions' => $dimensions,
'weight' => $weight,
];
}
}
$data['products'] = $products;
// Sort Order Specification Attributes
$sortOrder = [];
foreach ($specificationAttributes as $key => $value) {
$sortOrder[$key] = (int)$value['sortIndex'];
}
array_multisort($sortOrder, SORT_ASC, SORT_NUMERIC, $specificationAttributes);
$data['attributes'] = $specificationAttributes;
// Currency
$data['currency'] = $domain->getCurrency();
$data['precision'] = $domain->getPricePrecision();
// Common
$data['header'] = $this->getHeader($request);
$data['footer'] = $this->getFooter($request);
$data['contentBottom'] = $this->getContentBottom($request);
return $this->render('AtechNetCoreBundle/Product/compare.html.twig', $data);
}
/**
* @Route("/compare/add", name="product_compare_add")
* @param Request $request
* @return JsonResponse
*/
public function compareAddAction(Request $request): JsonResponse
{
$json = [];
// Entity Manager
$entityManager = $this->getEntityManager();
// Multi-store
$multiStore = $this->getMultiStoreHelper($request);
// Translator
$databaseTranslator = $this->getDatabaseTranslator($request);
// Session
$session = $request->getSession();
// Domain
$domain = $multiStore->getDomain();
// Collection
if ($session->has('productCompare')) {
$collection = $session->get('productCompare');
} else {
$collection = [];
}
// Product Id
if ($request->request->has('productId')) {
$productId = $request->request->get('productId');
} else {
$productId = 0;
}
// Product Info
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
if ($product) {
// If already in array remove the product id so it will be added to the back of the array
$key = array_search($productId, $collection);
if ($key !== false) {
unset($collection[$key]);
}
// If we count a numeric value that is greater than 4 products, we remove the first one
if (count($collection) >= 4) {
array_shift($collection);
}
// Check product types
if (count($collection) > 0) {
/**
* @var Product $productInCollection
*/
$productInCollection = $entityManager->getRepository(Product::class)->findOneById($collection[0]);
if ($productInCollection->getType()->getId() != $product->getType()->getId()) {
return new JsonResponse([
'message' => 'Different product type added',
]);
}
}
// Push to Collection
$collection[] = $productId;
// Save to Session
$session->set('productCompare', $collection);
// Placeholder
$placeholder = $image = $this->getImage('placeholder.jpg', '')->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
// Compared Products
$json['product'] = [];
foreach ($collection as $productId) {
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
if ($product) {
// Meta
$priceMeta = $product->getDomainMeta($domain);
// Product Image
if ($product->getAlbum() && $product->getAlbum()->getPhotos()->count() > 0) {
$image = $this->getImage($product->getAlbum()->getPhotos()->first(), 'product/' . $product->getCode())->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
} else {
$image = $placeholder;
}
// Product Price
if ($priceMeta->isDiscounted()) {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatDiscount() : $priceMeta->getDomainDiscount();
} else {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatPrice() : $priceMeta->getDomainPrice();
}
// Product Data
$json['product'][] = [
'id' => $product->getId(),
'name' => $product->getFullTitle($databaseTranslator),
'image' => $image,
'price' => $price,
];
}
}
}
return new JsonResponse($json);
}
/**
* @Route("/compare/remove", name="product_compare_remove")
* @param Request $request
* @return JsonResponse
*/
public function compareRemoveAction(Request $request): JsonResponse
{
$json = [];
// Entity Manager
$entityManager = $this->getEntityManager();
// Multi-store
$multiStore = $this->getMultiStoreHelper($request);
// Translator
$databaseTranslator = $this->getDatabaseTranslator($request);
// Session
$session = $request->getSession();
// Domain
$domain = $multiStore->getDomain();
// Collection
if ($session->has('productCompare')) {
$collection = $session->get('productCompare');
} else {
$collection = [];
}
// Product Id
if ($request->request->has('productId')) {
$productId = $request->request->get('productId');
} else {
$productId = 0;
}
// Remove the product id
$key = array_search($productId, $collection);
if ($key !== false) {
unset($collection[$key]);
}
// If we count a numeric value that is greater than 4 products, we remove the first one
if (count($collection) > 4) {
array_shift($collection);
}
// Save to Session
$session->set('productCompare', $collection);
// Placeholder
$placeholder = $image = $this->getImage('placeholder.jpg', '')->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
// Compared Products
$json['product'] = [];
foreach ($collection as $productId) {
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
if ($product) {
// Meta
$priceMeta = $product->getDomainMeta($domain);
// Product Image
if ($product->getAlbum() && $product->getAlbum()->getPhotos()->count() > 0) {
$image = $this->getImage($product->getAlbum()->getPhotos()->first(), 'product/' . $product->getCode())->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
} else {
$image = $placeholder;
}
// Product Price
if ($priceMeta->isDiscounted()) {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatDiscount() : $priceMeta->getDomainDiscount();
} else {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatPrice() : $priceMeta->getDomainPrice();
}
// Product Data
$json['product'][] = [
'id' => $product->getId(),
'name' => $product->getFullTitle($databaseTranslator),
'image' => $image,
'price' => $price,
];
}
}
return new JsonResponse($json);
}
/**
* @Route("/compare/fetch", name="product_compare_fetch")
* @param Request $request
* @return JsonResponse
*/
public function compareFetchAction(Request $request): JsonResponse
{
$json = [];
// Entity Manager
$entityManager = $this->getEntityManager();
// Multi-store
$multiStore = $this->getMultiStoreHelper($request);
// Translator
$databaseTranslator = $this->getDatabaseTranslator($request);
// Session
$session = $request->getSession();
// Domain
$domain = $multiStore->getDomain();
// Collection
if ($session->has('productCompare')) {
$collection = $session->get('productCompare');
} else {
$collection = [];
}
// If we count a numeric value that is greater than 4 products, we remove the first one
if (count($collection) > 4) {
array_shift($collection);
}
// Save to Session
$session->set('productCompare', $collection);
// Placeholder
$placeholder = $image = $this->getImage('placeholder.jpg', '')->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
// Compared Products
$json['product'] = [];
foreach ($collection as $productId) {
$product = $entityManager->getRepository(Product::class)->findOneById($productId);
if ($product) {
// Meta
$priceMeta = $product->getDomainMeta($domain);
// Product Image
if ($product->getAlbum() && $product->getAlbum()->getPhotos()->count() > 0) {
$image = $this->getImage($product->getAlbum()->getPhotos()->first(), 'product/' . $product->getCode())->resize(Image::PRODUCT_VIEW_ADDITIONAL_WIDTH, Image::PRODUCT_VIEW_ADDITIONAL_HEIGHT);
} else {
$image = $placeholder;
}
// Product Price
if ($priceMeta->isDiscounted()) {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatDiscount() : $priceMeta->getDomainDiscount();
} else {
$price = $domain->getType() == Domain::TYPE_RETAIL ? $priceMeta->getDomainVatPrice() : $priceMeta->getDomainPrice();
}
// Product Data
$json['product'][] = [
'id' => $product->getId(),
'name' => $product->getFullTitle($databaseTranslator),
'image' => $image,
'price' => $price,
];
}
}
return new JsonResponse($json);
}
/**
* @param $value
* @return string
*/
private function removeSpecialCharacters($value): string
{
$table = [
' ' => '',
'Š' => 'S',
'š' => 's',
'Ð' => 'Dj',
'Ž' => 'Z',
'ž' => 'z',
'C' => 'C',
'c' => 'c',
'C' => 'C',
'c' => 'c',
'À' => 'A',
'Á' => 'A',
'Â' => 'A',
'Ã' => 'A',
'Ä' => 'A',
'Å' => 'A',
'Æ' => 'A',
'Ç' => 'C',
'È' => 'E',
'É' => 'E',
'Ê' => 'E',
'Ë' => 'E',
'Ì' => 'I',
'Í' => 'I',
'Î' => 'I',
'Ï' => 'I',
'Ñ' => 'N',
'Ò' => 'O',
'Ó' => 'O',
'Ô' => 'O',
'Õ' => 'O',
'Ö' => 'O',
'Ø' => 'O',
'Ù' => 'U',
'Ú' => 'U',
'Û' => 'U',
'Ü' => 'U',
'Ý' => 'Y',
'Þ' => 'B',
'ß' => 'Ss',
'à' => 'a',
'á' => 'a',
'â' => 'a',
'ã' => 'a',
'ä' => 'a',
'å' => 'a',
'æ' => 'a',
'ç' => 'c',
'è' => 'e',
'é' => 'e',
'ê' => 'e',
'ë' => 'e',
'ì' => 'i',
'í' => 'i',
'î' => 'i',
'ï' => 'i',
'ð' => 'o',
'ñ' => 'n',
'ò' => 'o',
'ó' => 'o',
'ô' => 'o',
'õ' => 'o',
'ö' => 'o',
'ø' => 'o',
'ù' => 'u',
'ú' => 'u',
'û' => 'u',
'ý' => 'y',
'ý' => 'y',
'þ' => 'b',
'ÿ' => 'y',
'R' => 'R',
'r' => 'r',
"'" => '',
'"' => '',
'(' => '',
')' => '',
',' => '',
'+' => '',
'–' => '',
'.' => '',
'-' => '',
'3' => 'Three',
'ü' => 'u',
'ű' => 'u',
'Ü' => 'U',
'Ű' => 'U',
'ő' => 'o',
'Ő' => 'O',
'ő' => 'o',
];
return strtr($value, $table);
}
}