<?php
namespace App\Controller;
use App\Entity\ActualitePage;
use App\Entity\Application;
use App\Entity\ApplicationParagraph;
use App\Entity\ApplicationProduct;
use App\Entity\ApplicationTranslation;
use App\Entity\Category;
use App\Entity\CategoryTranslation;
use App\Entity\Contact;
use App\Entity\Document;
use App\Entity\DocumentCategory;
use App\Entity\DocumentCategoryTranslation;
use App\Entity\FabricationParagraph;
use App\Entity\JobOffer;
use App\Entity\JobOfferParagraph;
use App\Entity\JobOfferTranslation;
use App\Entity\Member;
use App\Entity\Newsletter;
use App\Entity\Page;
use App\Entity\Paragraph;
use App\Entity\Partner;
use App\Entity\Post;
use App\Entity\PostDocument;
use App\Entity\PostMedia;
use App\Entity\PostTranslation;
use App\Entity\PresentationParagraph;
use App\Entity\Product;
use App\Entity\ProductDocument;
use App\Entity\ProductMedia;
use App\Entity\ProductProductTable;
use App\Entity\ProductTranslation;
use App\Entity\RelatedProduct;
use App\Entity\SubCategory;
use App\Entity\SubCategoryTranslation;
use App\Entity\SubSubCategory;
use App\Entity\SubSubCategoryTranslation;
use App\Entity\SubSubSubCategory;
use App\Entity\SubSubSubCategoryTranslation;
use App\Entity\Testimonial;
use App\Form\ContactType;
use App\Form\NewsletterType;
use App\Form\ProductsFilterType;
use App\Repository\ActualitePageRepository;
use App\Repository\DocumentPageRepository;
use App\Repository\FabricationPageRepository;
use App\Repository\PresentationPageRepository;
use App\Service\AppService;
use Doctrine\Persistence\ManagerRegistry;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bridge\Twig\Mime\BodyRenderer;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Console\Application as FrameworkApplication;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Path;
/**
* @Route("/{_locale}", requirements={"_locale": "%managed_locales_routing%"})
*/
class FrontController extends AbstractController
{
/**
* @Route("/categorie/{slug}/{subCatSlug}/{subSubCatSlug}", name="front_category")
*/
public function category(ManagerRegistry $managerRegistry, AppService $appService, Request $request, CategoryTranslation $categoryTranslation, $subCatSlug = null, $subSubCatSlug = null)
{
$category = $categoryTranslation->getTranslatable();
$repoSubSubCategory = $managerRegistry->getRepository(SubSubCategory::class);
$subSubCategory = $repoSubSubCategory->search(["slug" => $subSubCatSlug, "limit" => 1]);
$repoSubCategory = $managerRegistry->getRepository(SubCategory::class);
$subCategory = $subSubCategory ? $subSubCategory->getSubCategory() : $repoSubCategory->search(["slug" => $subCatSlug, "limit" => 1]);
$value = $subSubSubCategory ?? ($subSubCategory ?? ($subCategory ?? $category));
if ($subSubCategory && $subSubCategory->getSubSubSubCategories()->isEmpty()) {
return $this->redirectToRoute('front_products', [
"slug" => $category->getSlug(),
"subCatSlug" => $subSubCategory->getSubCategory()->getSlug(),
"subSubCatSlug" => $subSubCategory->getSlug(),
"subSubSubCatSlug" => null,
"listView" => null
]);
} elseif ($subCategory && $subCategory->getSubSubCategories()->isEmpty()) {
return $this->redirectToRoute('front_products', [
"slug" => $category->getSlug(),
"subCatSlug" => $subCategory->getSlug(),
"subSubCatSlug" => null,
"subSubSubCatSlug" => null,
"listView" => null
]);
}
return $this->render('front/category.html.twig', array(
"category" => $category,
"subCategory" => $subCategory,
"subSubCategory" => $subSubCategory,
"value" => $value
));
}
/**
* @Route("/changer-la-langue/{locale}/{routeName}/{routeParams}", name="front_change_language", requirements={"routeParams"=".+"})
*/
public function changeLanguage(Request $request, SessionInterface $session, $locale, $routeName, $routeParams = null)
{
$routeParams = array_merge(["_locale" => $locale], $_GET);
return $this->redirectToRoute($routeName, $routeParams);
}
/**
* @Route("/presentation", name="front_presentation")
*/
public function presentation(ManagerRegistry $managerRegistry, Request $request, PresentationPageRepository $presentationPageRepository)
{
$repoPresentationParagraph = $managerRegistry->getRepository(PresentationParagraph::class);
$bandeau = $presentationPageRepository->findAll()[0];
$presentationParagraphs = $repoPresentationParagraph->findBy([], ["position" => "asc"]);
return $this->render('front/presentation.html.twig', array(
"presentationParagraphs" => $presentationParagraphs,
'bandeau' => $bandeau
));
}
/**
* @Route("/fabrication-sur-mesure", name="front_fabrication")
*/
public function fabrication(ManagerRegistry $managerRegistry, Request $request, FabricationPageRepository $fabricationPageRepository)
{
$repoFabricationParagraph = $managerRegistry->getRepository(FabricationParagraph::class);
$page = $fabricationPageRepository->findAll()[0];
$fabricationParagraphs = $repoFabricationParagraph->findBy([], ["position" => "asc"]);
$repoProduct = $managerRegistry->getRepository(Product::class);
$products = $repoProduct->findBy(["isCustom" => true], ["position" => "asc"]);
return $this->render('front/fabrication.html.twig', array(
"fabricationParagraphs" => $fabricationParagraphs,
"products" => $products,
'bandeau' => $page
));
}
/**
* @Route("/produits/{slug}/{subCatSlug}/{subSubCatSlug}/{subSubSubCatSlug}/{listView}", name="front_products", defaults={"slug":null})
*/
public function products(ManagerRegistry $managerRegistry, PaginatorInterface $paginator, Request $request, CategoryTranslation $categoryTranslation = null, $subCatSlug = null, $subSubCatSlug = null, $subSubSubCatSlug = null, $listView = null)
{
$category = $categoryTranslation ? $categoryTranslation->getTranslatable() : null;
$repoSubSubSubCategory = $managerRegistry->getRepository(SubSubSubCategory::class);
$subSubSubCategory = $repoSubSubSubCategory->search(["slug" => $subSubSubCatSlug, "limit" => 1]);
$repoSubSubCategory = $managerRegistry->getRepository(SubSubCategory::class);
$subSubCategory = $subSubSubCategory ? $subSubSubCategory->getSubSubCategory() : $repoSubSubCategory->search(["slug" => $subSubCatSlug, "limit" => 1]);
$repoSubCategory = $managerRegistry->getRepository(SubCategory::class);
$subCategory = $subSubCategory ? $subSubCategory->getSubCategory() : $repoSubCategory->search(["slug" => $subCatSlug, "limit" => 1]);
$data["limit"] = 12;
$data["hideBaseProduct"] = false;
$data["searchProducts"] = ["categories" => [], "subCategories" => [], "subSubCategories" => [], "subSubSubCategories" => []];
if (!$request->isXmlHttpRequest()) {
if ($subSubSubCategory) {
$data["searchProducts"]["subSubSubCategories"][] = $subSubSubCategory;
}
if ($subSubCategory) {
$data["searchProducts"]["subSubCategories"][] = $subSubCategory;
}
if ($subCategory) {
$data["searchProducts"]["subCategories"][] = $subCategory;
}
if ($category) {
$data["searchProducts"]["categories"][] = $category;
}
}
$data["orderBys"] = ["ptt.title" => "asc"];
$productsFilterForm = $this->createForm(ProductsFilterType::class);
$productsFilterForm->handleRequest($request);
if ($productsFilterForm->isSubmitted() && $productsFilterForm->isValid()) {
$data["searchProducts"]["offset"] = $productsFilterForm["offset"]->getData();
$data["orderBys"] = ($productsFilterForm["orderBy"]->getData() == "new" ? ["a.position" => "desc"] : ["ptt.title" => "asc"]);
}
$repoProduct = $managerRegistry->getRepository(Product::class);
$products = $repoProduct->search($data);
$products = (is_array($products) ? $products : ($products ? [$products] : []));
return $this->render('front/products.html.twig', array(
"slug" => $categoryTranslation ? $categoryTranslation->getSlug() : "0",
"subCatSlug" => $subCatSlug ?? "0",
"subSubCatSlug" => $subSubCatSlug ?? "0",
"subSubSubCatSlug" => $subSubSubCatSlug ?? "0",
"listView" => $listView,
'productsFilterForm' => $productsFilterForm->createView(),
"products" => $products,
"categoryActive" => $category,
"subCategoryActive" => $subCategory,
"subSubCategoryActive" => $subSubCategory,
"subSubSubCategoryActive" => $subSubSubCategory,
"value" => ($subSubSubCategory ?? $subSubCategory ?? $subCategory ?? $category),
"limit" => $data["limit"]
));
}
/**
* @Route("/produit/{catSlug}/{subCatSlug}/{subSubCatSlug}/{subSubSubCatSlug}/{slug}", name="front_product")
*/
public function product(ManagerRegistry $managerRegistry, Request $request, $catSlug, $subCatSlug, $subSubCatSlug, $subSubSubCatSlug, ProductTranslation $productTranslation)
{
$product = $productTranslation->getTranslatable();
$repoProductMedia = $managerRegistry->getRepository(ProductMedia::class);
$productPhotos = $repoProductMedia->findBy(["isSchema" => false, "product" => $product], ["position" => "asc"]);
$productSchemas = $repoProductMedia->findBy(["isSchema" => true, "product" => $product], ["position" => "asc"]);
$repoProductDocument = $managerRegistry->getRepository(ProductDocument::class);
$productDocuments = $repoProductDocument->findBy(["product" => $product], ["position" => "asc"]);
$repoProductProductTable = $managerRegistry->getRepository(ProductProductTable::class);
$productProductTables = $repoProductProductTable->findBy(["product" => $product], ["position" => "asc"]);
$repoRelatedProduct = $managerRegistry->getRepository(RelatedProduct::class);
$relatedProducts = $repoRelatedProduct->findBy(["product" => $product], ["position" => "asc"]);
return $this->render('front/product.html.twig', array(
"product" => $product,
"relatedProducts" => $relatedProducts,
"productDocuments" => $productDocuments,
"productSchemas" => $productSchemas,
"productPhotos" => $productPhotos
));
}
/**
* @Route("/a-propos", name="front_privacy_policy")
*/
public function privacyPolicy(ManagerRegistry $managerRegistry, Request $request)
{
return $this->render('front/privacyPolicy.html.twig', array());
}
/**
* @Route("/", name="front_landing")
*/
public function landing(Request $request, ManagerRegistry $managerRegistry): Response
{
$repoPartner = $managerRegistry->getRepository(Partner::class);
$partners = $repoPartner->findBy([], ["position" => "asc"]);
$repoPost = $managerRegistry->getRepository(Post::class);
$data["between"]["notStrict"]["a.date"]["max"] = new \DateTime();
$data["orderBy"] = ["a.date", "desc"];
$data["isPublished"] = true;
$data["limit"] = 3;
$posts = $repoPost->search($data);
$repoTestimonial = $managerRegistry->getRepository(Testimonial::class);
$testimonials = $repoTestimonial->findBy([], ["position" => "asc"]);
$repoProduct = $managerRegistry->getRepository(Product::class);
$products = $repoProduct->findBy(["displayOnLanding" => true], ["position" => "asc"]);
$repoApplication = $managerRegistry->getRepository(Application::class);
$applications = $repoApplication->findBy(["displayOnLanding" => true], ["position" => "asc"]);
return $this->render('front/landing.html.twig', [
"posts" => $posts,
"applications" => $applications,
"partners" => $partners,
"testimonials" => $testimonials,
"products" => $products,
]);
}
/**
* @Route("/application/{slug}", name="front_application")
*/
public function application(ManagerRegistry $managerRegistry, Request $request, ApplicationTranslation $applicationTranslation)
{
$application = $applicationTranslation->getTranslatable();
$repoApplicationParagraph = $managerRegistry->getRepository(ApplicationParagraph::class);
$applicationParagraphs = $repoApplicationParagraph->findBy(["application" => $application], ["position" => "asc"]);
$repoApplicationProduct = $managerRegistry->getRepository(ApplicationProduct::class);
$applicationProducts = $repoApplicationProduct->findBy(["application" => $application], ["position" => "asc"]);
return $this->render('front/application.html.twig', array(
"application" => $application,
"applicationProducts" => $applicationProducts,
"applicationParagraphs" => $applicationParagraphs
));
}
/**
* @Route("/offres-d-emploi", name="front_job_offers")
*/
public function jobOffers(ManagerRegistry $managerRegistry, Request $request)
{
$repoJobOffer = $managerRegistry->getRepository(JobOffer::class);
$jobOffers = $repoJobOffer->findBy([], ["position" => "asc"]);
return $this->render('front/jobOffers.html.twig', array(
"jobOffers" => $jobOffers
));
}
/**
* @Route("/offre-d-emploi/{slug}", name="front_job_offer")
*/
public function jobOffer(ManagerRegistry $managerRegistry, Request $request, JobOfferTranslation $jobOfferTranslation)
{
$jobOffer = $jobOfferTranslation->getTranslatable();
$repoJobOfferParagraph = $managerRegistry->getRepository(JobOfferParagraph::class);
$jobOfferParagraphs = $repoJobOfferParagraph->findBy(["jobOffer" => $jobOffer], ["position" => "asc"]);
return $this->render('front/jobOffer.html.twig', array(
"jobOffer" => $jobOffer,
"jobOfferParagraphs" => $jobOfferParagraphs,
));
}
public function sitemap(Request $request, Packages $packages)
{
$repoPage = $this->getDoctrine()->getRepository(Page::class);
$page = $repoPage->search(["notNull" => ["a.sitemapFileName"], "limit" => 1]);
if ($page and $page->getSitemapFileName()) {
return $this->redirect($packages->getUrl('upload/sitemap/' . $page->getSitemapFileName()));
} else {
return $this->redirectToRoute('front_landing');
}
}
/**
* @Route({
* "fr": "/contactez-nous/{slug}/{productSlug}/{fabrication}",
* "en": "/contact-us/{slug}/{productSlug}/{fabrication}",
* }, name="front_contact", defaults={"slug":null,"productSlug":null})
*/
public function contact(Request $request, ManagerRegistry $managerRegistry, TranslatorInterface $translator, ApplicationTranslation $applicationTranslation = null, $productSlug = null, $fabrication = null)
{
$repoProductTranslation = $managerRegistry->getRepository(ProductTranslation::class);
$productTranslation = $repoProductTranslation->findOneBy(["slug" => $productSlug]);
$product = $productTranslation ? $productTranslation->getTranslatable() : null;
$application = $applicationTranslation ? $applicationTranslation->getTranslatable() : null;
$contact = new Contact();
$contactForm = $this->createForm(ContactType::class, $contact, [
"application" => $application,
"fabrication" => $fabrication,
"product" => $product
]);
$contactForm->handleRequest($request);
if ($contactForm->isSubmitted() && $contactForm->isValid()) {
$recaptchaResponse = $request->request->get('g-recaptcha-response', null);
$isRecaptchaValid = false;
if ($recaptchaResponse) {
$paramsArr = array(
"response" => $recaptchaResponse,
"secret" => $this->getParameter('recaptchaSecret')
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramsArr));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$isRecaptchaValid = json_decode(curl_exec($ch))->success;
}
if (!$isRecaptchaValid) {
$this->addFlash("danger", "Veuillez recommencer en validant le captcha.");
} else {
$em = $managerRegistry->getManager();
$em->persist($contact);
$em->flush();
$this->addFlash("success", "Message envoyé.");
$transport = Transport::fromDsn($this->getParameter('mailer_dsn'));
$mailer = new Mailer($transport);
$email = (new TemplatedEmail())
->from($this->getParameter('mailer_user'))
->to($translator->trans("customer_email"))
->subject("Nouveau message")
// path of the Twig template to render
->htmlTemplate('mail/contact.html.twig')
// pass variables (name => value) to the template
->context(["contact" => $contact]);
if ($contact->getEmail()) {
$email
->replyTo($contact->getEmail());
}
foreach ($contact->getCustomFiles() as $key => $customFile) {
$email->attachFromPath(("upload/customFile/" . $customFile->getCustomFileFileName()));
}
$loader = new FilesystemLoader($this->getParameter('kernel.project_dir') . '/templates/');
$twigEnv = new Environment($loader);
$twigBodyRenderer = new BodyRenderer($twigEnv);
$twigBodyRenderer->render($email);
$mailer->send($email);
return $this->redirectToRoute('front_contact');
}
}
return $this->render('front/contact.html.twig', array(
'contactForm' => $contactForm->createView(),
));
}
/**
* @Route("/plan-du-site", name="front_sitemap_links")
*/
public function sitemapLinks(ManagerRegistry $managerRegistry, Request $request)
{
return $this->render('front/sitemapLinks.html.twig', array());
}
/**
* @Route("/notre-equipe", name="front_members")
*/
public function members(ManagerRegistry $managerRegistry, Request $request)
{
$repoMember = $managerRegistry->getRepository(Member::class);
$members = $repoMember->findBy([], ["position" => "asc"]);
return $this->render('front/members.html.twig', array(
"members" => $members
));
}
/**
* @Route("/actualites", name="front_posts")
*/
public function posts(Request $request, PaginatorInterface $paginator, ManagerRegistry $managerRegistry, ActualitePageRepository $actualitePageRepository)
{
$repoPost = $managerRegistry->getRepository(Post::class);
$data["between"]["notStrict"]["a.date"]["max"] = new \DateTime();
$data["orderBy"] = ["a.date", "desc"];
$data["isPublished"] = true;
$posts = $paginator->paginate(
$repoPost->search($data), $request->query->getInt('page', 1)/* page number */, 12/* limit per page */
);
$bandeau = $actualitePageRepository->findAll()[0];
return $this->render('front/posts.html.twig', array(
"posts" => $posts,
'bandeau' => $bandeau
));
}
/**
* @Route("/navbar-search", name="front_navbar_search")
*/
public function navbarSearch(ManagerRegistry $managerRegistry, Request $request)
{
$query = $request->query->get('nav-search');
$repoPost = $managerRegistry->getRepository(Post::class);
$data["search"] = $query;
$data["isPublished"] = true;
$data["orderBy"] = ["a.date", "asc"];
$posts = $repoPost->search($data);
$repoProduct = $managerRegistry->getRepository(Product::class);
$products = $repoProduct->search(["search" => $query, "orderBys" => ["a.position" => "asc"]]);
return $this->render('front/navbarSearch.html.twig', array(
"posts" => $posts,
"products" => $products,
"navSearchQuery" => $query
));
}
/**
* @Route("/telechargements/{slug}", name="front_documents", defaults={"slug":null})
*/
public function documents(ManagerRegistry $managerRegistry, Request $request, DocumentCategoryTranslation $documentCategoryTranslation = null, DocumentPageRepository $documentPageRepository)
{
$documentCategory = $documentCategoryTranslation ? $documentCategoryTranslation->getTranslatable() : null;
$repoDocument = $managerRegistry->getRepository(Document::class);
$data = [];
$repoDocumentCategory = $managerRegistry->getRepository(DocumentCategory::class);
$documentCategories = $repoDocumentCategory->findBy([], ["position" => "asc"]);
$documentCategory = $documentCategory ?? ($documentCategories ? reset($documentCategories) : null);
if ($documentCategory) {
$data["documentCategory"] = $documentCategory;
}
$documents = $repoDocument->findBy($data, ["position" => "asc"]);
$bandeau = $documentPageRepository->findAll()[0];
return $this->render('front/documents.html.twig', array(
"documents" => $documents,
"activeCategory" => $documentCategory,
"documentCategories" => $documentCategories,
'bandeau' => $bandeau
));
}
/**
* @Route("/actualite/{slug}", name="front_post")
*/
public function post(Request $request, ManagerRegistry $managerRegistry, string $slug)
{
$repoPostTranslation = $managerRegistry->getRepository(PostTranslation::class);
$postTranslation = $repoPostTranslation->findOneBy(["slug" => $slug]);
if ($postTranslation and $post = $postTranslation->getTranslatable()) {
if ($post->getIsPublished() or $this->isGranted("ROLE_ADMIN")) {
$repoParagraph = $managerRegistry->getRepository(Paragraph::class);
$paragraphs = $repoParagraph->findBy(["post" => $post], ["position" => "asc"]);
$repoPostMedia = $managerRegistry->getRepository(PostMedia::class);
$postMedias = $repoPostMedia->findBy(["post" => $post], ["position" => "asc"]);
$repoPostDocument = $managerRegistry->getRepository(PostDocument::class);
$postDocuments = $repoPostDocument->findBy(["post" => $post], ["position" => "asc"]);
$repoPost = $managerRegistry->getRepository(Post::class);
$data["between"]["notStrict"]["a.date"]["max"] = new \DateTime();
$data["orderBy"] = ["a.date", "desc"];
$data["isPublished"] = true;
$data["limit"] = 2;
$data["different"] = ["a.id" => $post->getId()];
$posts = $repoPost->search($data);
return $this->render('front/post.html.twig', array(
"post" => $post,
"posts" => $posts,
"postDocuments" => $postDocuments,
"paragraphs" => $paragraphs,
"postMedias" => $postMedias,
));
} else {
$this->addFlash("danger", "flash.not_allowed_post");
return $this->redirectToRoute('front_posts');
}
} else {
$this->addFlash("danger", "flash.post_not_found");
return $this->redirectToRoute('front_posts');
}
}
/**
* @Route("/inscription-newsletter", name="front_subscribe_newsletter")
*/
public function subscribeNewsletter(ManagerRegistry $managerRegistry, Request $request, AppService $appService)
{
$newsletter = new Newsletter();
$newsletterForm = $this->createForm(NewsletterType::class, $newsletter);
$newsletterForm->handleRequest($request);
$em = $managerRegistry->getManager();
if ($newsletterForm->isSubmitted() && $newsletterForm->isValid()) {
$appService->suscribeToList($newsletter->getEmail());
$em->persist($newsletter);
$em->flush();
$this->addFlash("success", "flash.newsletter.success");
return $this->redirectToRoute('front_landing');
}
return $this->render('form/newsletterForm.html.twig', array(
'newsletterForm' => $newsletterForm->createView(),
));
}
/**
* @Route("/admin/fsdhj78Hjkdfsb0920dfjdfhq87djhaoppsnv720", name="front_clear_cache")
*/
public function clearCache(Request $request, KernelInterface $kernel)
{
$application = new FrameworkApplication($kernel);
$application->setAutoExit(false);
$input = new ArrayInput([
'command' => 'cache:clear',
]);
// You can use NullOutput() if you don't need the output
$output = new NullOutput();
$application->run($input, $output);
$this->addFlash("success", "Le cache a bien été nettoyé, les traductions sont à jour !");
return $this->redirectToRoute('front_landing');
}
}