<?php
namespace App\Controller\Web;
use App\Controller\WebController;
use App\Entity\Application\Category;
use App\Entity\Application\CategoryTranslation;
use App\Entity\Application\Information;
use App\Entity\Application\Offer;
use App\Entity\Application\Store;
use App\Entity\Brand;
use App\Entity\Newsletter;
use App\Entity\Product;
use App\Entity\VIPaccount;
use App\Entity\Web\Career;
use App\Entity\Web\Modal;
use App\Entity\Web\News;
use App\Entity\Web\Site;
use App\Entity\Web\TopCategory;
use App\Fce\F_Ecomail;
use App\Form\Eshop\NewsletterType;
use App\Form\Web\ContactType;
use App\Form\Web\VIPaccountType;
use DateTime;
use Doctrine\ORM\Query\Expr\Join;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Locale;
use MobileDetectBundle\DeviceDetector\MobileDetectorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
class DefaultController extends WebController
{
/**
* @Route("/init", name="app_web_homepage_init")
*/
public function init(): Response
{
foreach ($this->em->getRepository(Store::class)->findAll() as $store) {
$store->setEditts(new DateTime());
$this->em->persist($store);
}
$this->em->flush();
die;
}
/**
* @Route("/at/{path}", name="app_web_homepage_at", host="%domain.web%")
*/
public function at(Request $request, ?string $path = ''): Response
{
return $this->redirect('https://' . $this->getParameter('domain.web_de') . '/' . $path, 301);
}
/**
* @Route({"cs":"/","en":"/","de":"/"}, name="app_web_homepage", host="%domain.web%")
*/
public function index(Request $request, MobileDetectorInterface $detector): Response
{
$request->getSession()->set('_currency', Locale::getDefault() === 'cs' ? 'CZK' : 'EUR');
return $this->render('web/default/index.html.twig', [
'slides' => $this->slideShowRepository->findForHomepage($detector->isMobile()),
'news' => $this->newsRepository->findForWeb(3),
'biggestDiscount' => $this->em->getRepository(Product::class)->biggestDiscount(Locale::getDefault() === 'cs' ? 'CZK' : 'EUR'),
'news_products' => $this->em->getRepository(Product::class)->newsProducts(Locale::getDefault() === 'cs' ? 'CZK' : 'EUR'),
'offers' => $this->em->getRepository(Offer::class)->createQueryBuilder('o')->select('o,ot')->leftJoin('o.translations', 'ot')->andWhere('o.isActive = TRUE AND o.isPublic = TRUE')->orderBy('o.id', 'DESC')->getQuery()->getResult(),
'curr' => Locale::getDefault() === 'cs' ? 'CZK' : 'EUR'
]);
}
/**
* @Route({
* "cs": "/kontakty",
* "en": "/contacts",
* "de": "/contakte"
* }, name="app_web_contact", host="%domain.web%")
*/
public function contact(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator): Response
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($this->isHoneypotFilled($form)) {
$this->addFlash('success', 'Žádost byla odeslána.');
return $this->redirectToRoute('app_web_contact');
}
if (isset($_POST['g-recaptcha-response'])) {
$captcha = $_POST['g-recaptcha-response'];
$secretKey = "6Lc9IQosAAAAAN1Oavyb1aiH10seSXD-0xUg05vO";
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) . '&response=' . urlencode($captcha);
$response = file_get_contents($url);
$responseKeys = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
if ($responseKeys["success"]) {
$message = (
new \Swift_Message($translator->trans('contact.form.subject2', [], 'web')))
->setFrom($this->getParameter('from_email_web'))
->setTo($this->getParameter('from_email_web'))
->setBcc($form->get('email')->getData())
->setBody($this->renderView('web/core/email.html.twig', [
'form' => $form
]), 'text/html');
$mailer->send($message);
} else {
$this->addFlash('danger', 'Žádost byla odeslána.');
}
}
$this->addFlash('success', 'Žádost byla odeslána.');
}
return $this->render('web/default/kontakt.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route({
* "cs": "/oteviraci-doba",
* "en": "/opening-hours",
* "de": "/offnungszeiten"
* }, name="app_web_opening")
*/
public function openingHours(): Response
{
return $this->render('web/default/opening-hours.html.twig');
}
/**
* @Route({
* "cs": "/kudy-k-nam",
* "en": "/how-to-find-us",
* "de": "/wie-kommen-sie-zu-uns"
* }, name="app_web_which")
*/
public function howToFindUs(): Response
{
return $this->render('web/default/which-way.html.twig');
}
/**
* @Route({
* "cs": "/o-freeportu",
* "en": "/about-freeport",
* "de": "/uber-freeport"
* }, name="app_web_about")
*/
public function about(): Response
{
return $this->render('web/default/about.html.twig');
}
/**
* @Route({
* "cs": "/kariera",
* "en": "/carrer",
* "de": "/werdegang"
* }, name="app_web_career")
*/
public function career(): Response
{
$careers = $this->em->getRepository(Career::class)->createQueryBuilder('c')->select('c,ct')->leftJoin('c.translations', 'ct')->where('c.isActive = TRUE')->orderBy('c.datePublic', 'DESC')->getQuery()->getResult();
return $this->render('web/default/career.html.twig', [
'careers' => $careers,
'categories' => $this->em->getRepository(Category::class)->createQueryBuilder('c')->select('c,ct')->leftJoin('c.translations', 'ct')->orderBy('c.orderBy', 'ASC')->getQuery()->getResult(),
]);
}
/**
* @Route({
* "cs": "/kariera-detail/{career}",
* "en": "/carrer-detail/{career}",
* "de": "/werdegang-detail/{career}"
* }, name="app_web_career_detail")
* @Entity("career", expr="repository.findOneBySlug(career, _locale)")
*/
public function careerDetail(Career $career): Response
{
return $this->render('web/default/career-detail.html.twig', [
'career' => $career,
]);
}
/**
* @Route({
* "cs": "/faq",
* "en": "/faq",
* "de": "/faq"
* }, name="app_web_faq")
*/
public function faq(): Response
{
return $this->render('web/default/faq.html.twig');
}
/**
* @Route({
* "cs": "/znacky",
* "en": "/brands",
* "de": "/marken"
* }, name="app_web_brands")
*/
public function brands(): Response
{
$brands = $this->em->getRepository(Brand::class)->createQueryBuilder('b')->select('b,s')->innerJoin('b.stores', 's', Join::WITH, 's.isActive = TRUE')->orderBy('b.name')->getQuery()->getResult();
$out = [];
/** @var Brand $brand */
foreach ($brands as $brand) {
if (!isset($out[mb_strtoupper(substr($brand->getName(), 0, 1))])) {
$out[mb_strtoupper(substr($brand->getName(), 0, 1))] = [];
}
$out[mb_strtoupper(substr($brand->getName(), 0, 1))][] = $brand;
}
return $this->render('web/default/brands.html.twig', [
'brands' => $out
]);
}
/**
* @Route({
* "cs": "/page/{site}",
* "en": "/page/{site}",
* "de": "/page/{site}"
* }, name="app_web_page")
* @Entity("site", expr="repository.findOneBySlug(site, _locale)")
*/
public function page(Site $site): Response
{
return $this->render('web/default/page.html.twig', [
'site' => $site
]);
}
/**
* @Route({
* "cs": "/novinky",
* "en": "/news",
* "de": "/nachrichten"
* }, name="app_web_news")
*/
public function news(): Response
{
return $this->render('web/default/news.html.twig', [
'news' => $this->newsRepository->findForWeb(3)
]);
}
/**
* @Route({
* "cs": "/novinky-detail/{news}",
* "en": "/news-detail/{news}",
* "de": "/nachrichten-detail/{news}"
* }, name="app_web_news_detail")
* @Entity("news", expr="repository.findOneBySlug(news, _locale)")
*/
public function newsDetail(News $news): Response
{
return $this->render('web/default/news-detail.html.twig', [
'new' => $news
]);
}
/**
* @Route({
* "cs": "/newsletter-add",
* "en": "/newsletter-add",
* "de": "/newsletter-add"
* }, name="app_web_newsletter_add")
*/
public function newsletterAdd(Request $request): Response
{
$entity = new Newsletter();
$entity->setLocale(Locale::getDefault());
$form = $this->createForm(NewsletterType::class, $entity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entity->setCreatets(new DateTime());
$entity->setIp($_SERVER['REMOTE_ADDR']);
$this->em->persist($entity);
$this->em->flush();
F_Ecomail::addSubscriberFromEntity($entity);
}
$this->addFlash('success', 'Byl/a jste zařazen/a do odběru newsletterů.');
return $this->redirectToRoute('app_web_homepage');
}
/**
* @Route({
* "cs": "/darkovy-poukaz",
* "en": "/gift-card",
* "de": "/geschenkgutschein"
* }, name="app_web_gift-card")
*/
public function giftCard(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator): Response
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($this->isHoneypotFilled($form)) {
$this->addFlash('success', 'Žádost byla odeslána.');
return $this->redirectToRoute('app_web_gift-card');
}
if (isset($_POST['g-recaptcha-response'])) {
$captcha = $_POST['g-recaptcha-response'];
$secretKey = "6LceJF4sAAAAAFYLkVpRmpXPqPhTPXDkg79Zn6y1";
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) . '&response=' . urlencode($captcha);
$response = file_get_contents($url);
$responseKeys = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
// should return JSON with success as true
if ($responseKeys["success"]) {
$message = (
new \Swift_Message($translator->trans('contact.form.subject', [], 'web')))
->setFrom($this->getParameter('from_email_web'))
->setTo($this->getParameter('from_email_web'))
->setBcc($form->get('email')->getData())
->setBody($this->renderView('web/core/email.html.twig', [
'form' => $form
]), 'text/html');
$mailer->send($message);
} else {
$this->addFlash('danger', 'Žádost byla odeslána.');
}
}
$this->addFlash('success', 'Žádost byla odeslána.');
}
return $this->render('web/default/gift-card.html.twig', [
'info' => $this->em->getRepository(Information::class)->find(1),
'form' => $form->createView()
]);
}
private function isHoneypotFilled(FormInterface $form): bool
{
return $form->has('website') && trim((string) $form->get('website')->getData()) !== '';
}
/**
* @Route({"cs": "/obchody", "en": "/shops", "de": "/geschafte"}, name="app_web_shops")
* @Route({"cs": "/obchody/{slug}", "en": "/shops/{slug}", "de": "/geschafte/{slug}"}, name="app_web_shops_categ")
*/
public function shops(?CategoryTranslation $category, CacheManager $cacheManager, UploaderHelper $uploaderHelper): Response
{
$stores = $this->em->getRepository(Store::class)->createQueryBuilder('s')->select('s,c')->leftJoin('s.category', 'c')->where('s.isActive = TRUE')->orderBy('s.name', 'ASC')->getQuery()->getResult();
$forMap = [];
/** @var Store $store */
foreach ($stores as $store) {
if (empty($store->getShopNumber())) {
continue;
}
foreach ($store->getShopNumber() as $k) {
$forMap[trim($k)] = [
'name' => $store->getName(),
'number' => implode(', ', $store->getShopNumber()),
'phone' => $store->getPhone(),
'vip' => $store->getVip(),
'email' => $store->getEmail(),
'open' => $store->getVirtualOpenHoursToday(),
'url' => $this->generateUrl('app_web_shop_detail', ['slug' => $store->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL),
'logo' => !empty($store->getLogo()) ? ($cacheManager->getBrowserPath($uploaderHelper->asset($store, 'logoFile'), 'thumb300')) : ''
];
}
}
return $this->render('web/default/shops.html.twig', [
'categories' => $this->em->getRepository(Category::class)->createQueryBuilder('c')->select('c,ct')->leftJoin('c.translations', 'ct')->orderBy('c.orderBy', 'ASC')->getQuery()->getResult(),
'stores' => $stores,
'forMap' => $forMap,
'categoryActive' => $category !== null ? $category->getTranslatable() : null
]);
}
/**
* @Route({
* "cs": "/top-akce",
* "en": "/top-actions",
* "de": "/top-aktionen"
* }, name="app_web_top-actions")
*/
public function topAction(): Response
{
$offers = $this->em->getRepository(Offer::class)->createQueryBuilder('o')->select('o,ot')->leftJoin('o.translations', 'ot')->andWhere('o.isActive = TRUE AND o.isPublic = TRUE AND o.dateTo >= :now')
->setParameter('now', (new \DateTime())->setTime(0, 10))
->orderBy('o.editts', 'DESC')->getQuery()->getResult();
$stores = array_map(static function ($o) {
return $o->getStore();
}, $offers);
$fin = [];
foreach ($stores as $store) {
$fin[$store->getId()] = $store;
}
usort($fin, function ($a, $b) {
return strcmp(trim($a->getSlug()), trim($b->getSlug()));
});
return $this->render('web/default/top-actions.html.twig', [
'categories' => $this->em->getRepository(TopCategory::class)->getActiveKategories(),
'offers' => $offers,
'stores' => $fin
]);
}
/**
* @Route({
* "cs": "/navstevni-rad",
* "en": "/visitation-order",
* "de": "/besuchsordnung"
* }, name="app_web_visitation-order")
*/
public function visitationOrder(): Response
{
return $this->render('web/default/visitation-order.twig');
}
/**
* @Route({
* "cs": "/gdpr",
* "en": "/gdpr",
* "de": "/gdpr"
* }, name="app_web_gdpr")
*/
public function gdpr(): Response
{
return $this->render('web/default/gdpr.html.twig');
}
/**
* @Route({
* "cs": "/obchod/{slug}",
* "en": "/shop/{slug}",
* "de": "/shop/{slug}"
* }, name="app_web_shop_detail")
*/
public function shopDetail(Store $store): Response
{
if (!$store->getisActive()) {
return $this->redirectToRoute('app_web_shops');
}
$info = $this->em->getRepository(Information::class)->find(1);
return $this->render('web/default/shop-detail.html.twig', [
'store' => $store,
'opening' => $info->getOpening(),
]);
}
/**
* @Route({
* "cs": "/vip-club",
* "en": "/vip-club",
* "de": "/vip-club"
* }, name="app_web_vip-club")
*/
public function vipClub(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator): Response
{
$vip = new VIPaccount();
$form = $this->createForm(VIPaccountType::class, $vip);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$message = (new \Swift_Message($translator->trans('vip.register.title', [], 'web')))
->setFrom($this->getParameter('from_email_web'))
->setTo($vip->getEmail())
->setBody($this->renderView('web/core/vip-email.html.twig'), 'text/html');
$mailer->send($message);
$new = new Newsletter();
$new->setEmail($vip->getEmail());
$new->setLocale($vip->getLanguage());
$new->setIsActive(true);
$new->setCreatets(new DateTime());
$new->setIp($_SERVER['REMOTE_ADDR']);
$new->setSource('website');
$this->em->persist($new);
F_Ecomail::addSubscriberFromEntity($new);
$this->em->persist($vip);
try {
$this->em->flush();
} catch (\Exception $e) {
}
return $this->redirectToRoute('app_web_vip-club-success');
}
return $this->render('web/default/vip-club.html.twig', [
'vips' => $this->em->getRepository(Store::class)->createQueryBuilder('s')->select('s,st')->leftJoin('s.translations', 'st')->andWhere('s.isActive = TRUE AND s.vip = TRUE')->orderBy('s.name', 'ASC')->getQuery()->getResult(),
'form' => $form->createView()
]);
}
/**
* @Route({
* "cs": "/vip-club-success",
* "en": "/vip-club-success",
* "de": "/vip-club-success"
* }, name="app_web_vip-club-success")
*/
public function vipClubSuccess(): Response
{
return $this->render('web/default/vip-club-success.html.twig');
}
public function opening(): Response
{
$data = $this->em->getRepository(Information::class)->find(1);
if (!$data instanceof Information) {
return $this->redirectToRoute('app_web_homepage');
}
return $this->render('web/core/opening.html.twig', [
'open' => $data->getOpening()
]);
}
public function menu(): Response
{
return $this->render('web/core/category.html.twig', [
'categories' => $this->em->getRepository(Category::class)->createQueryBuilder('c')->select('c,ct')->leftJoin('c.translations', 'ct')->orderBy('c.orderBy', 'ASC')->getQuery()->getResult()
]);
}
public function _modal(Request $request): Response
{
$cook = $request->cookies->all();
$in = [];
foreach ($cook as $k => $v) {
if (strpos($k, 'modal_') !== false) {
$in[] = (int)$v;
}
}
return $this->render('web/core/modal.html.twig', [
'modal' => $this->em->getRepository(Modal::class)->findActive($in, $request->getLocale())
]);
}
public function _giftCard(CacheManager $cacheManager, UploaderHelper $uploaderHelper, Request $request): Response
{
$data = $this->em->getRepository(Information::class)->find(1);
return new Response($cacheManager->getBrowserPath($uploaderHelper->asset($data->translate($request->getLocale()), 'imageFile'), 'coupon'), 200);
}
}