<?php
namespace App\Controller;
use App\Entity\Application;
use App\Entity\ApplicationParagraph;
use App\Entity\ApplicationProduct;
use App\Entity\ApplicationTranslation;
use App\Entity\Category;
use App\Entity\Contact;
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\PostMedia;
use App\Entity\PostTranslation;
use App\Entity\PresentationParagraph;
use App\Entity\Product;
use App\Entity\ProductMedia;
use App\Entity\ProductTranslation;
use App\Entity\RelatedProduct;
use App\Entity\SubCategory;
use App\Entity\Testimonial;
use App\Form\ContactType;
use App\Form\NewsletterType;
use App\Form\ProductsFilterType;
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
{
public static $LIMIT_PRODUCTS = 9;
/**
* @Route({
* "fr": "/changer-la-langue/{locale}/{routeName}/{routeParams}",
* "en": "/change-language/{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({
* "fr": "/application/{slug}",
* "en": "/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([], ["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({
* "fr": "/presentation",
* "en": "/presentation"
* }, name="front_presentation")
*/
public function presentation(ManagerRegistry $managerRegistry, Request $request)
{
$repoPresentationParagraph = $managerRegistry->getRepository(PresentationParagraph::class);
$presentationParagraphs = $repoPresentationParagraph->findBy(["isOther" => false], ["position" => "asc"]);
$otherPresentationParagraphs = $repoPresentationParagraph->findBy(["isOther" => true], ["position" => "asc"]);
return $this->render('front/presentation.html.twig', array(
"presentationParagraphs" => $presentationParagraphs,
"otherPresentationParagraphs" => $otherPresentationParagraphs,
));
}
/**
* @Route({
* "fr": "/produits/{catSlug}/{subCatSlug}",
* "en": "/products/{catSlug}/{subCatSlug}"
* }, name="front_products")
*/
public function products(ManagerRegistry $managerRegistry, PaginatorInterface $paginator, Request $request, $catSlug, $subCatSlug = null)
{
$repoSubCategory = $managerRegistry->getRepository(SubCategory::class);
$subCategory = $repoSubCategory->search(["slug" => $subCatSlug, "limit" => 1]);
$repoCategory = $managerRegistry->getRepository(Category::class);
$category = $subCategory ? $subCategory->getCategory() : $repoCategory->search(["slug" => $catSlug, "limit" => 1]);
$data["orderBy"] = ["a.position", "asc"];
$data["limit"] = self::$LIMIT_PRODUCTS;
$data["hide"] = false;
$data["searchProducts"] = ["categories" => [], "subCategories" => []];
if (!$request->isXmlHttpRequest()) {
if ($subCategory) {
$data["searchProducts"]["subCategories"][] = $subCategory;
}
if ($category) {
$data["searchProducts"]["categories"][] = $category;
}
}
$productsFilterForm = $this->createForm(ProductsFilterType::class);
$productsFilterForm->handleRequest($request);
if ($productsFilterForm->isSubmitted() && $productsFilterForm->isValid()) {
$data["searchProducts"] = $productsFilterForm->getData();
}
$repoProduct = $managerRegistry->getRepository(Product::class);
$products = $repoProduct->search($data);
$data['count'] = true;
unset($data['offset']);
unset($data['limit']);
unset($data['orderBy']);
$nbProducts = $repoProduct->search($data);
$nbProducts = count($nbProducts);
$products = (is_array($products) ? $products : ($products ? [$products] : []));
$otherCategories = $repoCategory->search(["different" => ["a.id" => $category->getId()], "isChaine" => false]);
$otherSubCategories = $subCategory ? $repoSubCategory->search(["different" => ["a.id" => $subCategory->getId()], "category" => $category]) : [];
return $this->render('front/products.html.twig', array(
'productsFilterForm' => $productsFilterForm->createView(),
"products" => $products,
'limit' => self::$LIMIT_PRODUCTS,
'total' => $nbProducts,
"categoryActive" => $category,
"subCategoryActive" => $subCategory,
"otherCategories" => $otherCategories,
"otherSubCategories" => $otherSubCategories
));
}
/**
* @Route({
* "fr": "/produit/{catSlug}/{subCatSlug}/{slug}",
* "en": "/product/{catSlug}/{subCatSlug}/{slug}",
* }, name="front_product")
*/
public function product(ManagerRegistry $managerRegistry, Request $request, $catSlug, $subCatSlug, ProductTranslation $productTranslation)
{
$product = $productTranslation->getTranslatable();
$repoRelatedProduct = $managerRegistry->getRepository(RelatedProduct::class);
$relatedProducts = $repoRelatedProduct->findBy(["product" => $product], ["position" => "asc"]);
$repoProductMedia = $managerRegistry->getRepository(ProductMedia::class);
$productMedias = $repoProductMedia->findBy(["product" => $product], ["position" => "asc"]);
return $this->render('front/product.html.twig', array(
"relatedProducts" => $relatedProducts,
"productMedias" => $productMedias,
"product" => $product
));
}
/**
* @Route({
* "fr": "/mentions-legales",
* "en": "/legal-terms",
* }, name="front_privacy_policy")
*/
public function privacyPolicy(ManagerRegistry $managerRegistry, Request $request)
{
return $this->render('front/privacyPolicy.html.twig', array());
}
/**
* @Route({
* "fr": "/",
* "en": "/",
* }, 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"]);
$repoApplication = $managerRegistry->getRepository(Application::class);
$applications = $repoApplication->findBy(["displayOnLanding" => true], ["position" => "asc"]);
return $this->render('front/landing.html.twig', [
"applications" => $applications,
"posts" => $posts,
"partners" => $partners,
"testimonials" => $testimonials,
]);
}
/**
* @Route({
* "fr": "/offres-d-emploi",
* "en": "/job-offers",
* }, 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({
* "fr": "/offre-d-emploi/{slug}",
* "en": "/job-offer/{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}",
* "en": "/contact-us/{slug}",
* }, name="front_contact", defaults={"slug":null})
*/
public function contact(Request $request, ManagerRegistry $managerRegistry, TranslatorInterface $translator, $slug = null)
{
$repoProduct = $managerRegistry->getRepository(Product::class);
$product = $slug ? $repoProduct->search(["slug" => $slug, "limit" => 1]) : null;
$contact = new Contact();
$contactForm = $this->createForm(ContactType::class, $contact, [
"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);
$subject = ("Nouveau message : " . $contact->getSubject() . " " . $contact->getCity());
$email = (new TemplatedEmail())
->from($this->getParameter('mailer_user'))
->to("facomia.sarl@facomia.com")
->subject($subject)
// 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({
* "fr": "/plan-du-site",
* "en": "/sitemap",
* }, name="front_sitemap_links")
*/
public function sitemapLinks(ManagerRegistry $managerRegistry, Request $request)
{
return $this->render('front/sitemapLinks.html.twig', array());
}
/**
* @Route({
* "fr": "/notre-equipe",
* "en": "/our-team",
* }, 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({
* "fr": "/actualites",
* "en": "/news",
* }, name="front_posts")
*/
public function posts(Request $request, PaginatorInterface $paginator, ManagerRegistry $managerRegistry)
{
$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 */
);
return $this->render('front/posts.html.twig', array(
"posts" => $posts
));
}
/**
* @Route({
* "fr": "/navbar-search",
* "en": "/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);
return $this->render('front/navbarSearch.html.twig', array(
"posts" => $posts,
"navSearchQuery" => $query
));
}
/**
* @Route({
* "fr": "/actualite/{slug}",
* "en": "/news/{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"]);
$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(
"posts" => $posts,
"post" => $post,
"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({
* "fr": "/inscription-newsletter",
* "en": "/newsletter-register",
* }, 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({
* "fr": "/admin/fsdhj78Hjkdfsb0920dfjdfhq87djhaoppsnv720",
* "en": "/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');
}
}