<?php
/**
* This file is part of Symfony Keen Template Project.
* (c) 2021 One AM SRL
*/
namespace App\Controller\Frontend;
use App\Entity\Article;
use App\Entity\CallToAction;
use App\Entity\Category;
use App\Entity\Component;
use App\Entity\Contact;
use App\Entity\Legal;
use App\Entity\Page;
use App\Entity\Product;
use App\Entity\Reseller;
use App\Repository\ArticleRepository;
use App\Repository\BrandRepository;
use App\Repository\CompanyRepository;
use App\Repository\ContactRepository;
use App\Repository\ResellerRepository;
use App\Twig\AppExtension;
use App\Twig\LegalExtension;
use App\WhiteRabbit\ApiClient;
use Doctrine\ORM\EntityManagerInterface;
use Keen\Attribute\Breadcrumb;
use Keen\Attribute\NavbarTag;
use Keen\Event\Listener\BreadcrumbAnnotationListener;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class IndexController extends AbstractController
{
#[Route(path: '/', name: 'frontend_index', methods: ['GET'])]
#[Breadcrumb('La piscina a 360°')]
#[NavbarTag('home')]
public function index(ArticleRepository $articleRepository, BrandRepository $brandRepository): Response
{
return $this->render('frontend/index.html.twig', [
'latestArticles' => $articleRepository->findBy(['visible' => true], ['id' => 'DESC'], 3),
'brands' => $brandRepository->findBy(['visible' => true]),
]);
}
#[Route(path: '/prodotti/{product}/{page}', name: 'frontend_product_page_index', requirements: ['page' => '.+'], methods: ['GET'])]
#[Entity('product', expr: 'repository.findOneBySlug(product)')]
#[Entity('page', expr: 'repository.findOneBySlug(page)')]
public function page(Product $product, Page $page, BreadcrumbAnnotationListener $annotationListener): Response
{
$annotationListener->addBreadcrumb(new Breadcrumb('Prodotti'));
$annotationListener->addBreadcrumb(new Breadcrumb($product->getName(), 'frontend_product_index', ['product' => $product->getSlug()]));
if ($page->getParent()) {
$annotationListener->addBreadcrumb(new Breadcrumb($page->getParent()->getName(), 'frontend_product_page_index', [
'product' => $product->getSlug(),
'page' => $page->getParent()->getSlug(),
]));
}
$annotationListener->addBreadcrumb(new Breadcrumb($page->getName()));
return $this->render('frontend/product/page/index.html.twig', [
'product' => $product,
'page' => $page,
]);
}
#[Route(path: '/prodotti/{product}', name: 'frontend_product_index', methods: ['GET'])]
#[Entity('product', expr: 'repository.findOneBySlug(product)')]
public function product(Product $product, BreadcrumbAnnotationListener $annotationListener): Response
{
$annotationListener->addBreadcrumb(new Breadcrumb('Prodotti'));
$annotationListener->addBreadcrumb(new Breadcrumb($product->getName()));
return $this->render('frontend/product/index.html.twig', [
'product' => $product,
]);
}
#[Route(path: '/chi-siamo', name: 'frontend_about', methods: ['GET'])]
#[Breadcrumb('Chi siamo')]
#[NavbarTag('about')]
public function about(CompanyRepository $companyRepository, AppExtension $appExtension): Response
{
return $this->render('frontend/about.html.twig', [
'companies' => $companyRepository->findAll(),
'aboutConfiguration' => $appExtension->aboutConfiguration(),
]);
}
#[Route(path: '/configuratore-piscine', name: 'frontend_configurator', methods: ['GET'])]
#[Breadcrumb('Configuratore piscine')]
#[NavbarTag('configurator')]
public function configurator(): Response
{
return $this->render('frontend/configurator.html.twig');
}
#[Route(path: '/comparatore-consumo-energetico-pompe', name: 'frontend_variable_speed_pump_configurator', methods: ['GET'])]
#[Breadcrumb('Comparatore consumo energetico pompe')]
#[NavbarTag('configurator')]
public function variableSpeedPumpConfigurator(): Response
{
return $this->render('frontend/variable_speed_pump_configurator.html.twig');
}
#[Route(path: '/rivenditori', name: 'frontend_resellers', methods: ['GET'])]
#[Breadcrumb('Rivenditori')]
#[NavbarTag('resellers')]
public function resellers(ResellerRepository $resellerRepository): Response
{
$resellers = $resellerRepository->createQueryBuilder('reseller')
->andWhere('reseller.type = :official OR reseller.type = :ePartner')
->setParameter('official', Reseller::TYPE_OFFICIAL_PARTNER)
->setParameter('ePartner', Reseller::TYPE_E_PARTNER)
->getQuery()->getResult();
return $this->render('frontend/resellers.html.twig', [
'resellers' => $resellers,
]);
}
#[Route(path: '/rivenditori-spa-professional', name: 'frontend_resellers_spa_professional', methods: ['GET'])]
#[Breadcrumb('Rivenditori SPA Professional')]
public function resellerSpaProfessional(ResellerRepository $resellerRepository): Response
{
$resellers = $resellerRepository->createQueryBuilder('reseller')
->andWhere('reseller.type = :spaProfessional')
->setParameter('spaProfessional', Reseller::SPA_PROFESSIONAL)
->getQuery()->getResult();
return $this->render('frontend/spa-professional.html.twig', [
'resellers' => $resellers,
]);
}
#[Route(path: '/contatti', name: 'frontend_contacts', methods: ['GET', 'POST'])]
#[Breadcrumb('Contatti')]
#[NavbarTag('contacts')]
public function contacts(Request $request, ApiClient $apiClient, ContactRepository $contactRepository, EntityManagerInterface $entityManager, MailerInterface $mailer, LoggerInterface $logger): Response
{
if (Request::METHOD_POST === $request->getMethod()) {
$name = $request->request->get('name');
$surname = $request->request->get('surname');
$email = $request->request->get('email');
$phone = $request->request->get('phone');
$city = $request->request->get('city');
$province = $request->request->get('province');
$hasPool = $request->request->get('hasPool');
$type = $request->request->get('type');
$contactField = $request->request->get('contact');
$message = $request->request->get('message');
$marketingConsent = 'on' === $request->request->get('marketingConsent');
if (!$name || !$surname || !$email || !$phone || !$city || !$province || !$hasPool || !$type || !$contactField) {
throw new BadRequestHttpException();
}
if (null === $contact = $contactRepository->findOneBy(['email' => $email])) {
$contact = new Contact();
$contact->setEmail($email);
}
$poolType = [
'Sì, interrata' => 'Newsletter Lead Piscina SI',
'Sì, fuori terra' => 'Newsletter Lead LAGHETTO',
'No' => 'Newsletter Lead Piscina NO',
][$hasPool];
$contact->setName($name);
$contact->setSurname($surname);
$contact->setPhone($phone);
$contact->setCity($city);
$contact->setProvince($province);
$contact->setHasPool($hasPool);
$contact->setContact($contactField);
$contact->setType($type);
$contact->setMessage($message);
$contact->setTags(array_unique(['Astralpool_form_contatti_ok', $poolType]));
$contact->setMarketingConsent($marketingConsent);
$entityManager->persist($contact);
$entityManager->flush();
if ($apiClient->createContact($contact)) {
$this->addFlash('contactSuccess', 'Richiesta inviata con successo!');
$email = (new TemplatedEmail())
->from(new Address('fluidraexperience@fluidra.it', 'astralpool.it'))
->to(
new Address('fluidraexperience@fluidra.it'),
new Address('marketing@fluidra.it'),
new Address('ctonghini@fluidra.it')
)
->replyTo($contact->getEmail())
->subject('Richiesta form contatti astralpool.it')
->htmlTemplate('emails/contact.html.twig')
->context([
'contact' => $contact,
])
;
try {
$mailer->send($email);
} catch (TransportExceptionInterface $e) {
$logger->error(sprintf('Unexpected error while sending confirmation token message: %s', $e->getMessage() ?: get_class($e)));
}
return $this->render('frontend/contacts.html.twig');
}
return $this->render('frontend/error.html.twig');
}
return $this->render('frontend/contacts.html.twig');
}
#[Route(path: '/newsletter', name: 'frontend_newsletter', methods: ['GET', 'POST'])]
#[Breadcrumb('Newsletter')]
#[NavbarTag('newsletter')]
public function newsletter(Request $request, ApiClient $apiClient, ContactRepository $contactRepository, EntityManagerInterface $entityManager): Response
{
if (Request::METHOD_POST === $request->getMethod()) {
$name = $request->request->get('name');
$surname = $request->request->get('surname');
$email = $request->request->get('email');
$phone = $request->request->get('phone');
$city = $request->request->get('city');
$province = $request->request->get('province');
$hasPool = $request->request->get('hasPool');
if (!$name || !$surname || !$email || !$phone || !$city || !$province || !$hasPool) {
throw new BadRequestHttpException();
}
if (null === $contact = $contactRepository->findOneBy(['email' => $email])) {
$contact = new Contact();
$contact->setEmail($email);
}
$poolType = [
'Sì, interrata' => 'Newsletter Lead Piscina SI',
'Sì, fuori terra' => 'Newsletter Lead LAGHETTO',
'No' => 'Newsletter Lead Piscina NO',
][$hasPool];
$contact->setName($name);
$contact->setSurname($surname);
$contact->setPhone($phone);
$contact->setCity($city);
$contact->setProvince($province);
$contact->setHasPool($hasPool);
$contact->setContact(null);
$contact->setType(null);
$contact->setTags(array_unique(['tag newsletter', 'Astralpool_form_contatti_ok', $poolType]));
$contact->setMarketingConsent(true);
$entityManager->persist($contact);
$entityManager->flush();
if ($apiClient->createContact($contact)) {
return $this->render('frontend/success.html.twig');
}
return $this->render('frontend/error.html.twig');
}
// TAG
return $this->render('frontend/newsletter.html.twig');
}
#[Route(path: '/sostenibilita', name: 'frontend_sustainability', methods: ['GET'])]
#[Breadcrumb('Sostenibilità')]
#[NavbarTag('sustainability')]
public function sustainability(): Response
{
return $this->render('frontend/sustainability.html.twig');
}
#[Route(path: '/download/{callToAction}', name: 'app_download', methods: ['GET', 'POST'])]
#[Breadcrumb('Scarica il documento')]
#[Entity('callToAction', expr: 'repository.findOneBySlug(callToAction)')]
public function download(
CallToAction $callToAction,
ApiClient $apiClient,
ContactRepository $contactRepository,
EntityManagerInterface $entityManager,
Request $request,
SessionInterface $session,
MailerInterface $mailer,
LoggerInterface $logger
): Response {
if (!$callToAction->isWhiteRabbit()) {
throw new BadRequestHttpException();
}
if (Request::METHOD_POST === $request->getMethod()) {
$name = $request->request->get('name');
$surname = $request->request->get('surname');
$email = $request->request->get('email');
$phone = $request->request->get('phone');
$city = $request->request->get('city');
$province = $request->request->get('province');
$hasPool = $request->request->get('hasPool');
$contactField = $request->request->get('contact');
$marketingConsent = 'on' === $request->request->get('marketingConsent');
if (!$name || !$surname || !$email || !$phone || !$city || !$province || !$hasPool || !$contactField) {
throw new BadRequestHttpException();
}
if (null === $contact = $contactRepository->findOneBy(['email' => $email])) {
$contact = new Contact();
$contact->setEmail($email);
}
$poolType = [
'Sì, interrata' => 'Newsletter Lead Piscina SI',
'Sì, fuori terra' => 'Newsletter Lead LAGHETTO',
'No' => 'Newsletter Lead Piscina NO',
][$hasPool];
$contact->setName($name);
$contact->setSurname($surname);
$contact->setPhone($phone);
$contact->setCity($city);
$contact->setProvince($province);
$contact->setHasPool($hasPool);
$contact->setContact($contactField);
$contact->setType(null);
$contact->setTags(array_unique([$callToAction->getTag(), $poolType]));
$contact->setMarketingConsent($marketingConsent);
$entityManager->persist($contact);
$entityManager->flush();
if ($apiClient->createContact($contact)) {
$session->set($callToAction->getTitle(), true);
$email = (new TemplatedEmail())
->from(new Address('fluidraexperience@fluidra.it', 'astralpool.it'))
->to(
new Address('fluidraexperience@fluidra.it'),
new Address('marketing@fluidra.it'),
)
->replyTo($contact->getEmail())
->subject('Richiesta form download astralpool.it')
->htmlTemplate('emails/contact.html.twig')
->context([
'contact' => $contact,
'callToAction' => $callToAction->getTitle(),
])
;
try {
$mailer->send($email);
} catch (TransportExceptionInterface $e) {
$logger->error(sprintf('Unexpected error while sending confirmation token message: %s', $e->getMessage() ?: get_class($e)));
}
return $this->redirectToRoute('app_download_success', ['callToAction' => $callToAction->getSlug()]);
}
return $this->render('frontend/error.html.twig');
}
return $this->render('frontend/download.html.twig', [
'callToAction' => $callToAction,
]);
}
#[Route(path: '/download/{callToAction}}/success', name: 'app_download_success', methods: ['GET', 'POST'])]
#[Breadcrumb('Scarica il documento')]
#[Entity('callToAction', expr: 'repository.findOneBySlug(callToAction)')]
public function downloadSuccess(CallToAction $callToAction, SessionInterface $session): Response
{
$session->remove($callToAction->getTitle());
return $this->render('frontend/download_success.html.twig', [
'callToAction' => $callToAction,
]);
}
#[Route(path: '/{type}', name: 'app_legal', requirements: ['type' => 'cookie-policy|legal-notice|privacy-newsletter|privacy-policy'], methods: ['GET'])]
public function legal(string $type, LegalExtension $legalExtension, BreadcrumbAnnotationListener $breadcrumbAnnotationListener, TranslatorInterface $translator): Response
{
$legal = [
Legal::PRIVACY_POLICY => $legalExtension->privacyPolicy(),
Legal::PRIVACY_NEWSLETTER => $legalExtension->privacyNewsletter(),
Legal::LEGAL_NOTICE => $legalExtension->legalNotice(),
Legal::COOKIE_POLICY => $legalExtension->cookiePolicy(),
][$type];
$breadcrumbAnnotationListener->addBreadcrumb(new Breadcrumb($translator->trans($type)));
return $this->render('frontend/legal.html.twig', [
'legal' => $legal,
]);
}
#[Route(path: '/sitemap.xml', name: 'app_sitemap', methods: ['GET'])]
public function sitemap(Request $request, UrlGeneratorInterface $urlGenerator, EntityManagerInterface $entityManager): Response
{
$urls = [];
$hostname = $request->getHost();
$urls[] = ['loc' => $urlGenerator->generate('frontend_index'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_about'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_sustainability'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_talk_about_us_list'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_blog'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_resellers'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_resellers_spa_professional'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_configurator'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_contacts'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_newsletter'), 'changefreq' => 'monthly', 'priority' => '1.0'];
$urls[] = ['loc' => $urlGenerator->generate('frontend_component_list'), 'changefreq' => 'monthly', 'priority' => '1.0'];
foreach ($entityManager->getRepository(Component::class)->findBy(['visible' => true]) as $component) {
$urls[] = ['loc' => $urlGenerator->generate('frontend_component_index', ['component' => $component->getSlug()]), 'changefreq' => 'monthly', 'priority' => '1.0'];
}
foreach ($entityManager->getRepository(Page::class)->findBy(['visible' => true]) as $page) {
$urls[] = ['loc' => $urlGenerator->generate('frontend_product_page_index', ['product' => $page->getProduct()->getSlug(), 'page' => $page->getSlug()]), 'changefreq' => 'monthly', 'priority' => '1.0'];
}
foreach ($entityManager->getRepository(Product::class)->findBy(['visible' => true]) as $product) {
$urls[] = ['loc' => $urlGenerator->generate('frontend_product_index', ['product' => $product->getSlug()]), 'changefreq' => 'monthly', 'priority' => '1.0'];
}
foreach ($entityManager->getRepository(Category::class)->findAll() as $category) {
$urls[] = ['loc' => $urlGenerator->generate('frontend_blog', ['slug' => $category->getSlug()]), 'changefreq' => 'monthly', 'priority' => '1.0'];
}
foreach ($entityManager->getRepository(Article::class)->findAll() as $article) {
$urls[] = ['loc' => $urlGenerator->generate('frontend_blog_article_read', ['slug' => $article->getSlug()]), 'changefreq' => 'monthly', 'priority' => '1.0'];
}
$response = new Response();
$response->headers->set('Content-Type', 'text/xml');
return $this->render('frontend/sitemap.xml.twig', [
'urls' => $urls,
'hostname' => $hostname,
], $response);
}
}