<?php
namespace App\Controller;
use App\Entity\Category;
use App\Entity\CompareParameterValue;
use App\Entity\CompareProduct;
use App\Entity\Language;
use App\Entity\Product;
use App\Entity\ProductLangParam;
use App\Entity\ProductParameterValue;
use App\Entity\ProductParameterValueGroup;
use App\Entity\ProductPrice;
use App\Entity\ProductPriceVariants;
use App\Form\Type\ProductSearchFiltersType;
use App\Form\Type\SampleOrderType;
use App\Helper\VeltisControllerTrait;
use App\Repository\ArticleRepository;
use App\Repository\AvailabilityRepository;
use App\Repository\BannerRepository;
use App\Repository\CategoryRepository;
use App\Repository\FurnitureTypeRepository;
use App\Repository\HelplineHoursRepository;
use App\Repository\NewsRepository;
use App\Repository\ProductCommentRepository;
use App\Repository\ProductParameterRepository;
use App\Repository\ProductParameterValueGroupRepository;
use App\Repository\ProductParameterValueRepository;
use App\Repository\ProductPriceVariantsRepository;
use App\Repository\ProductRepository;
use App\Repository\WorkingHoursRepository;
use App\Services\CompareManager;
use App\Services\FacebookApiConversion;
use App\Services\PasswordProtectedService;
use App\Services\ProductCommentManager;
use App\Services\ProductManager;
use Doctrine\ORM\NoResultException;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Translation\TranslatorInterface;
class ProductController extends AbstractController
{
use VeltisControllerTrait;
/**
* @Route("/{slug}/{id}/p/{sub}", name="product", defaults={"sub"=null})
*/
public function indexAction(Request $request, HelplineHoursRepository $helpLineHoursRepository, ProductRepository $productRepository, ProductManager $productManager, ProductPriceVariantsRepository $productPriceVariantsRepository, TranslatorInterface $translator, ProductParameterValueRepository $productParameterValueRepository, CompareManager $compareManager, PasswordProtectedService $passwordProtectedService, ProductCommentManager $productCommentManager, FacebookApiConversion $facebookApiConversion)
{
if ($passwordProtectedService->isPasswordProtected()) {
return $this->redirectToRoute('password_protected');
}
try {
$product = $productRepository->getSingle($request->attributes->get('id'), $request->getLocale())->getQuery()->getSingleResult();
} catch (\Exception $e) {
throw new NotFoundHttpException();
}
$helplineHours = $helpLineHoursRepository->getForCurrentDay($request->getLocale())->getQuery()->getOneOrNullResult();
$language = $this->resolveLanguage($request->getLocale());
/** @var $productEntity Product */
$productEntity = $this->em()->getRepository('App:Product')->find($request->attributes->get('id'));
if ($productEntity->getDeletedBy()) {
throw new NotFoundHttpException();
}
if ($request->attributes->get('slug') !== $productEntity->translate($request->getLocale())->getSlug()) {
return $this->redirect($this->generateUrl('product', ['id'=>$productEntity->getId(), 'slug'=>$productEntity->translate($request->getLocale())->getSlug()]), 301);
}
$pricing = $productManager->generatePricing($productEntity, $request->getLocale());
$priceVariants = $productPriceVariantsRepository->getGroupVariantsForProduct($productEntity, $request->getLocale())->getQuery()->getResult();
$family = [];
if ($product[0]->getProductFamily()) {
$family = $productRepository->getProductFamily($product[0], $request->getLocale())->getQuery()->getResult();
}
$recommendations = $productRepository->searchStore(['prodIds'=>$productEntity->getRecommendationsIds($request->getLocale()), 'locale'=>$request->getLocale()])->getQuery()->getResult();
$similarColors = $productRepository->searchStore(['prodIds'=>$productEntity->getSimilarColorsIds(), 'locale'=>$request->getLocale()])->getQuery()->getResult();
$variantsArray = [];
$groupCounter = [];
/** @var $priceVariant ProductPriceVariants */
foreach ($priceVariants as $priceVariant) {
if ($priceVariant->getProductPrice() and $priceVariant->getProductPrice()->getActive() and $priceVariant->getProductPrice()->getLanguage()->getLocaleShort() == $request->getLocale()) {
$group = $priceVariant->getParameterValueGroup();
$pp = $priceVariant->getProductPrice();
if ($pp->getProduct()->getId() != $priceVariant->getProduct()->getId()) {
continue;
}
$idx = $group->getId();
$paramIdx = $group->getParameter()->getId();
$variantsArray[$idx]['parameter'] = $group->getParameter();
$variantsArray[$idx]['group'] = $group;
if (isset($groupCounter[$paramIdx])) {
$groupCounter[$paramIdx] = $groupCounter[$paramIdx] + 1;
} else {
$groupCounter[$paramIdx] = 1;
}
$variantsArray[$idx]['values'] = $productParameterValueRepository->getValuesForGroup($group, $request->getLocale())->getQuery()->getResult();
}
}
$productPrices = $this->em()->getRepository('App:ProductPrice')->findBy(['active'=>1, 'product'=>$productEntity, 'language'=>$language, 'deletedBy'=>null], ['price'=>'ASC']);
$firstParamValues = $productManager->findFirstParams($productPrices, $request->getLocale());
$parameterValues = $productManager->getParameterValues($productPrices, $request->getLocale());
$vat = $this->em()->getReference('App:ProductVat', $product['vatId']);
$productManager->addLastViewRecord($productEntity);
$images = [
'pl' => ['return14'=>'/images/ico/14_dni.svg', 'onMarket'=>'/images/ico/pl_15_lat.svg', 'freeDelivery'=>'/v2/ico/free_delivery_ico.png'],
'sk' => ['return14'=>'/images/ico/14_dni.svg', 'onMarket'=>'/images/ro/sk_17_rokov.svg', 'freeDelivery'=>'/images/icon_0eur.svg'],
'cz' => ['return14'=>'/images/ico/14_dni.svg', 'onMarket'=>'/images/ico/cz_5_let.svg', 'freeDelivery'=>'/images/icon_0kc.svg'],
'ro' => ['price' => '/images/ico/icon_cena.svg', 'return14'=>'/images/ico/14_dni.svg', 'onMarket'=>'/images/ro/ro_17_ani.svg', 'outlet'=>'/images/ro/box_outlet_ro.jpg', 'prod24h'=>'/images/ro/box_24h-01.jpg', 'szok'=>'/images/ro/oferta_speciale_box.jpg', 'freeDelivery'=>'/images/ro/icon_olei_ro.svg'],
];
$buyCheaperLP = $this->em()->getRepository('App:LandingPage')->findOneBy(['deletedBy'=>null, 'language'=>$language, 'specialForBuyCheaper'=>true]);
$minPrice = $productManager->getMinPrice($productEntity, $language);
$minPriceNet = $productManager->getMinPriceNetto($productEntity, $language);
/* RO constant marker */
$markerConstant = $this->em()->getRepository('App:Marker')->find(788);
$omnibus = $productManager->prepareOmnibusPrice($productEntity, $language, $minPriceNet);
if ($omnibus) {
$product['omnibusPrice'] = $omnibus;
}
if ($request->getLocale() != 'pl') {
$facebookApiConversion->createFbEvent('ViewContent');
}
$comments = $productCommentManager->getComments($productEntity, $language);
$rating = $productCommentManager->getAverageRating($productEntity, $language);
return $this->render('frontend/product/product.html.twig', [
'rating' => $rating,
'similarColors' => $similarColors,
'comments' => $comments,
'language' => $language,
'markerConstant' => $markerConstant,
'product' => $product[0],
'staticImages' => $images,
'buyCheaperLP' => $buyCheaperLP,
'locale'=>$request->getLocale(),
'compareIds' => $compareManager->getIdsCompareProducts(),
'pricing' => $pricing,
'groupCounter' => $groupCounter,
'firstParamValues' => $firstParamValues,
'minPrice'=>$minPrice,
'priceNetto' => $minPriceNet,
'parameterValues' => $parameterValues,
'versions' => json_encode($productManager->findVersionsForJson($firstParamValues, $translator, $request, $productPrices), JSON_HEX_QUOT),
'equipments' => $productManager->findEquipment($translator, $productEntity, $language),
'isEquipment' => count($productEntity->getActiveEquipment()),
'recommendations' => $recommendations,
'priceVariants' => $priceVariants,
'productPrices' => $productPrices,
'productEntity' => $productEntity,
'variantsArray' => $variantsArray,
'vat' => $vat,
'family' => $family,
'helplineHours' => $helplineHours,
'productData' => $product,
]);
}
/**
* @Route("/product/load-next-param/{id}", name="loadNextParam")
*/
public function ajaxLoadNextParamAction(Request $request, ProductRepository $productRepository, ProductManager $productManager, TranslatorInterface $translator, ProductPriceVariantsRepository $productPriceVariantsRepository) {
try {
$product = $productRepository->getSingle($request->attributes->get('id'), $request->getLocale())->getQuery()->getSingleResult();
} catch (\Exception $e) {
throw new NotFoundHttpException();
}
$language = $this->resolveLanguage($request->getLocale());
$productPrices = $this->em()->getRepository('App:ProductPrice')->findBy(['product'=>$product[0], 'language'=>$language, 'deletedBy'=>null, 'active'=>1]);
$allParameters = $productManager->getParameterValues($productPrices, $request->getLocale());
$nextParam = 0;
$params = $request->request->get('params');
//$params = [['param'=>8, 'value'=>2935], ['param'=>9, 'value'=>142], ['param'=>23, 'value'=>0], ['param'=>75, 'value'=>0]];
//$params = [['param'=>8, 'value'=>2935], ['param'=>9, 'value'=>0], ['param'=>55, 'value'=>0]];
$c = 0;
$chosenParams = [];
foreach ($params as $key => $row) {
$c = $c+1;
$chosenParams[] = ['parameterId'=>$row['param'], 'value'=>$row['value']];
if ($row['value'] == 0) { //if next value is zero -> then parameter is not set; so this is our next param to handle
$nextParam = $row['param'];
break;
}
}
$countChosenParams = 0;
foreach ($chosenParams as $chosenParam) {
if ($chosenParam['value'] > 0) {
$countChosenParams = $countChosenParams + 1;
}
}
$nextParameterEntity = false;
/**
* @var $key integer - id of the parameter
* @var $value
*/
foreach ($allParameters as $key => $value) {
if ($nextParam == $key) {
$nextParameterEntity = $value->getParameter();
}
}
$productPrices = $this->em()->getRepository('App:ProductPrice')->findBy(['active'=>1, 'product'=>$product[0], 'deletedBy'=>null], ['price'=>'ASC']);
$passedVariants = [];
/** @var $productPrice ProductPrice */
foreach ($productPrices as $productPrice) {
if ($productPrice->getLanguage()->getLocale() == $request->getLocale() and $productPrice->getDeletedBy() === null) {
$variantValues = [];
$variantValuesIds = [];
foreach ($productPrice->getVariants() as $variant) {
if ($variant->getParameterValue() and !in_array($variant->getParameterValue()->getId(), $variantValuesIds)) {
$variantValues[] = $variant->getParameterValue();
$variantValuesIds[] = $variant->getParameterValue()->getId();
}
if ($variant->getParameterValueGroup() && $variant->getParameterValueGroup()->getDeletedBy() === null) {
/** @var $variantValue ProductParameterValue */
foreach ($variant->getParameterValueGroup()->getVisibleValues() as $variantValue) {
if (!in_array($variantValue->getId(), $variantValuesIds)) {
$variantValues[] = $variantValue;
$variantValuesIds[] = $variantValue->getId();
}
}
}
}
$pass = 1;
foreach ($chosenParams as $chosenParam) {
if (!in_array($chosenParam['value'], $variantValuesIds) and $chosenParam['value'] > 0) {
$pass = 0;
break;
}
}
if ($pass) {
$passedVariants[] = $productPrice;
}
}
}
$showPrice = 1;
$returnVariant = 0;
if ($countChosenParams === count($allParameters)-1) {
$returnVariant = 1;
}
$return = [];
//$values = [];
//$values[] = ['id'=>1, 'src'=>'', 'desc'=>'', 'variant'=>''];
//$return[] = ['id'=>1, 'name'=>'--wybierz--', 'surcharge'=>' ', 'description'=>'', 'images'=>$values];
//now choose all values associated with next param - based on passed variants
/** @var $productPrice ProductPrice */
$variantGroupIds = [];
if ($nextParameterEntity === false) {
return new JsonResponse([]);
}
foreach ($passedVariants as $productPrice) {
$variantsQuery = $productPriceVariantsRepository->getByProductPrice($productPrice)->getQuery()->getResult();
/** @var $variant ProductPriceVariants */
foreach ($variantsQuery as $variant) {
if ($variant->getDeletedBy() === null and $variant->getParameterValueGroup() and $variant->getParameterValueGroup()->getDeletedBy() === null and $variant->getParameter()->getId() == $nextParameterEntity->getId() and !in_array($variant->getParameterValueGroup()->getId(), $variantGroupIds)) {
$values = [];
$values[] = ['id'=>0, 'src'=>0, 'desc'=>'', 'variant'=>''];
foreach ($variant->getParameterValueGroup()->getVisibleValues() as $value) {
if ($value->getDeletedBy() === null) {
$values[] = [
'id' => $value->getId(),
'src' => '/images/parameters/'.$value->getImageName(),
'desc' => $value->getName(),
'variant' => ($returnVariant) ? $variant->getId() : '',
];
}
}
/** @var $language Language */
$language = $productPrice->getProduct()->getLangParamByLocale($request->getLocale())->getLanguage();
$price = $productManager->getPrice($product[0], $language, $variant->getId());
$variantGroupIds[] = $variant->getParameterValueGroup()->getId();
$return[] = [
'id' => $variant->getParameterValueGroup()->getId(),
'name' => $variant->getParameterValueGroup()->getName(),
'surcharge' => str_replace(".", $variant->getProductPrice()->getCurrency()->getSeparator(), $price).' '.$variant->getProductPrice()->getCurrency()->getSign(),
'description' => $translator->trans('parameter_choose_helper', [], 'store', $request->getLocale()),
'images' => $values,
'currencySeparator'=>$variant->getProductPrice()->getCurrency()->getSeparator(),
'net' => $variant->getProductPrice()->getPrice()
];
}
}
}
$arr = $return;
if (empty($arr)) {
$values = [];
$values[] = ['id'=>1, 'src'=>'', 'desc'=>'', 'variant'=>''];
$return[] = ['id'=>1, 'currencySeparator'=>',', 'name'=>$translator->trans('choose', [], 'store', $request->getLocale()), 'net'=>' ', 'surcharge'=>' ', 'description'=>'', 'images'=>$values];
return new JsonResponse($return);
}
return new JsonResponse($arr);
}
/**
* @Route("/product/tkaninyOpisy/{id}", name="textileDescription")
*/
public function textileDescriptionAction(Request $request, ProductRepository $productRepository, PaginatorInterface $paginator)
{
/** @var $group ProductParameterValueGroup */
$group = $this->em()->getRepository('App:ProductParameterValueGroup')->find($request->attributes->get('id'));
if (!$group) {
return $this->redirectToRoute('homepage');
}
$products = $productRepository->getForParameterGroup($group, $request->getLocale())->getQuery()->getResult();
$pagination = $paginator->paginate($products, $request->query->getInt('page', 1)/*page number*/, 20, ['wrap-queries'=>true]);
return $this->render('frontend/product/textileDescription.html.twig', [
'group' => $group,
'language' => $this->resolveLanguage($request->getLocale()),
'products' => $pagination,
]);
}
public function getCompareManager() {
return $this->get('compare.manager');
}
/**
* @Route("/product/compare/add-to-compare", name="add_to_compare")
*/
public function addAction(Request $request, CompareManager $compareManager, SessionInterface $session) {
$product = $request->request->get('product');
$em = $this->getDoctrine()->getManager();
/** @var $productEntity Product */
$productEntity = $em->getRepository('App:Product')->find($product);
$cart_session = $session->get('cart_session');
$response = new Response(count($compareManager->getIdsCompareProducts()));
if (!$cart_session) {
$rand = substr(md5(uniqid(mt_rand(), true)) , 0, 36);
$response->headers->setCookie(new Cookie("cart_session", $rand, time()+14*24*60*60));
$this->get('session')->set('cart_session', $rand);
$this->get('session')->set('compare', $rand);
$cart_session = $rand;
$add = $compareManager->create();
$add->setProduct($productEntity);
$add->setSession($cart_session);
$response->setContent(count($compareManager->getIdsCompareProducts()));
return new $response;
}
$add = $compareManager->create();
$add->setProduct($productEntity);
$add->setSession($cart_session);
$compareManager->save($add);
return new Response(count($compareManager->getIdsCompareProducts()));
}
/**
* @Route("/product/compare/remove-from-compare", name="remove_compare")
*/
public function removeAction(Request $request, CompareManager $compareManager) {
$product = $request->request->get('product');
$productEntity = $this->em()->getRepository('App:Product')->find($product);
$cart_session = $request->getSession()->get('cart_session');
$find = $this->em()->getRepository('App:CompareProduct')->findOneBy(array('product'=>$productEntity, 'session'=>$cart_session));
$this->em()->remove($find);
$this->em()->flush();
return new Response(count($compareManager->getIdsCompareProducts()));
}
/**
* @Route("/product/compare/results", name="compare_products_summary")
*/
public function compareResultsAction(Request $request, CompareManager $compareManager, ProductRepository $productRepository) {
$compareProducts = $compareManager->getCompareProducts();
/** @var $compareProduct CompareProduct */
foreach ($compareProducts as $compareProduct) {
$product = $compareProduct->getProduct();
$compareProduct->details = $productRepository->getSingle([$product->getId()], $request->getLocale())->getQuery()->getResult();
#sprawdzamy czy wszystkie dodane parametry dla kategorii mają swoje odpowiedniki wartości (nawet puste) dla danego produktu
$parameters = $product->getMainCategory()->getCompareParameters();
/*
foreach ($parameters as $param) {
$check = $this->em()->getRepository('App:CompareParameterValue')->findOneBy(array('parameter'=>$param, 'category'=>$product->getMainCategory(), 'product'=>$product));
if (!is_object($check)) {
$add = new CompareParameterValue();
$add->setCategory($product->getMainCategory());
$add->setProduct($product);
$add->setParameter($param);
$this->em()->persist($add);
$this->em()->flush();
}
}
*/
}
return $this->render('frontend/product/compareResults.html.twig', array('locale'=>$request->getLocale(), 'language' => $this->resolveLanguage($request->getLocale()), 'compareProducts'=>$compareProducts));
}
/**
* @Route("/product/sample/order", name="sample_order")
*/
public function sampleOrderAction(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator) {
$form = $this->createForm(SampleOrderType::class);
$form->handleRequest($request);
$send = 0;
$title = $translator->trans('email_title_order_sample', [], 'store', $request->getLocale());
/** @var $language Language */
$language = $this->resolveLanguage($request->getLocale());
if ($form->isSubmitted()) {
if ($form->isValid()) {
$fromField = 'f';
if ($language->getId() == 2) {
$fromField = 'A';
}
if ($language->getId() == 3) {
$fromField = 'P';
}
if ($language->getId() == 4) {
$fromField = 'J';
}
$html = $this->renderView('frontend/email/sampleOrder.html.twig', ['formData' => $form->getData()]);
$recipients = ['to'=>['email'=>$language->getAdminStoreEmail()]];
//$recipients = ['to'=>['email'=>'krzysiek.gaudy@gmail.com']];
$content = [
'fromField'=>['fromFieldId'=>$fromField],
'subject'=>$title,
'content'=>['html'=>$html, 'plain'=>''],
'recipients'=>$recipients,
];
$ch = curl_init();
$body = json_encode($content);
curl_setopt($ch, CURLOPT_URL, "https://api3.getresponse360.pl/v3/transactional-emails");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Content-Type: application/json";
$headers[] = "X-Auth-Token: api-key gs478s9uv59n5ekulmpmgn5p0uqpepbn";
$headers[] = "X-Domain: echairs.eu";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close ($ch);
$json = json_decode($result, true);
$send = 1;
}
}
return $this->render('frontend/product/sampleOrder.html.twig', [
'language' => $this->resolveLanguage($request->getLocale()),
'send' => $send,
'form' => $form->createView(),
]);
}
/**
* @Route("/product/load-gallery/{id}", name="load_gallery_image")
*/
public function loadGalleryAction(Request $request) {
$photo = $this->em()->getRepository('App:ProductPhoto')->find($request->attributes->get('id'));
return $this->render('frontend/product/photoModal.html.twig', [
'photo' => $photo,
]);
}
}