src/Controller/Frontend/FrontendController.php line 910

  1. <?php
  2. namespace App\Controller\Frontend;
  3. use App\Traits\UrlTrait;
  4. use ReCaptcha\ReCaptcha;
  5. use Symfony\Component\Mime\Address;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Doctrine\ORM\Query\ResultSetMapping;
  8. use Webbamboo\SpinnersCommon\Entity\City;
  9. use Webbamboo\SpinnersCommon\Entity\Page;
  10. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  11. use Webbamboo\SpinnersCommon\Entity\Article;
  12. use Webbamboo\SpinnersCommon\Entity\Company;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\Mailer\MailerInterface;
  15. use Webbamboo\SpinnersCommon\Entity\Counties;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\Routing\Annotation\Route;
  18. use Symfony\Component\HttpKernel\KernelInterface;
  19. use Webbamboo\SpinnersCommon\Entity\Allpagesmeta;
  20. use Symfony\Component\HttpFoundation\RequestStack;
  21. use Webbamboo\SpinnersCommon\Entity\Generalsettings;
  22. use Webbamboo\SpinnersCommon\Manager\RedirectManager;
  23. use Symfony\Component\Form\Extension\Core\Type\TextType;
  24. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  25. use Webbamboo\SpinnersCommon\Repository\ArticleRepository;
  26. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  27. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  28. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  29. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  30. class FrontendController extends AbstractController
  31. {
  32.     use UrlTrait;
  33.     protected EntityManagerInterface $em;
  34.     protected SessionInterface $session;
  35.     protected MailerInterface $mailer;
  36.     protected CsrfTokenManagerInterface $csrfTokenManager;
  37.     protected ArticleRepository $articleRepository;
  38.     public function __construct(
  39.         EntityManagerInterface $em
  40.         RequestStack $requestStack
  41.         MailerInterface $mailer,
  42.         CsrfTokenManagerInterface $csrfTokenManager,
  43.         ArticleRepository $articleRepository
  44.     )
  45.     {
  46.         $this->em $em;    
  47.         $this->session $requestStack->getSession();
  48.         $this->mailer $mailer;
  49.         $this->csrfTokenManager $csrfTokenManager;
  50.         $this->articleRepository $articleRepository;
  51.     }
  52.     
  53.     protected $contactForm null;
  54.     protected $fields = array(
  55.         'name' => 'Namn',
  56.         'email' => 'Email',
  57.         'recaptcha' => 'ReCaptcha'
  58.     );
  59.     protected $submittedData = array();
  60.     protected $articlesDefaults null;
  61.     private function constructForm(Request $request)
  62.     {
  63.         $session $request->getSession();
  64.         $data $session->get('form-data') ? $session->get('form-data') : $this->submittedData;
  65.         $errors $session->get('form-errors') ? $session->get('form-errors') : array();
  66.         $token $this->csrfTokenManager->getToken('form_csrf');
  67.         $form $this->createFormBuilder($data)
  68.             ->add('name'TextType::class, array('required' => false'attr' => array('class' => in_array('Namn'$errors) ? 'form-control input-sm req-error' 'form-control input-sm')))
  69.             ->add('email'TextType::class, array('required' => false'attr' => array('class' => in_array('Email'$errors) ? 'form-control input-sm req-error' 'form-control input-sm')))
  70.             ->add('emailConfirmation'TextType::class, array('required' => false'attr' => array('class' => in_array('Email'$errors) ? 'form-control input-sm req-error' 'form-control input-sm')))
  71.             ->add('date'TextType::class, array('required' => false'attr' => array('class' => in_array('Datum'$errors) ? 'form-control input-sm req-error' 'form-control input-sm')))
  72.             ->add('sqfeet'TextType::class, array('required' => false'attr' => array('class' => in_array('Meter'$errors) ? 'form-control input-sm req-error' 'form-control input-sm')))
  73.             ->add('zip'TextType::class, array('required' => false'attr' => array('class' => in_array('Postnr'$errors) ? 'form-control input-sm req-error zipSelect2' 'form-control input-sm zipSelect2')))
  74.             ->add('other'TextareaType::class, array('required' => false))
  75.             ->add('token'HiddenType::class, array('data' => $token))
  76.             ->add('route'HiddenType::class)
  77.             ->add('routeparams'HiddenType::class)
  78.             ->add('siteVersion'HiddenType::class)
  79.             ->getForm();
  80.         $this->contactForm $form;
  81.         $session->set('form-errors', array());
  82.     }
  83.     private function getFormView(Request $request)
  84.     {
  85.         if (is_null($this->contactForm)) {
  86.             $this->constructForm($request);
  87.         }
  88.         return $this->contactForm->createView();
  89.     }
  90.     private function getForm(Request $request)
  91.     {
  92.         if (is_null($this->contactForm)) {
  93.             $this->constructForm($request);
  94.         }
  95.         return $this->contactForm;
  96.     }
  97.     private function validateEmail($email)
  98.     {
  99.         $email str_replace(" """$email);
  100.         if (
  101.             filter_var($emailFILTER_VALIDATE_EMAIL) && 
  102.             strpos($email"mail.ru") === false &&
  103.             strpos($email"enersets") === false &&
  104.             strpos($email"avalins") === false &&
  105.             strpos($email"efastes") === false &&
  106.             strpos($email"eric.jones.z.mail@gmail.com") === false
  107.         ) {
  108.             return true;
  109.         } else {
  110.             return false;
  111.         }
  112.     }
  113.     private function isSpamBody($string
  114.     {
  115.         $lowercasedContent strtolower($string);
  116.         $dictionary = ['viagra'];
  117.         $isInSpamDictionary = function() use($dictionary$lowercasedContent) {
  118.             foreach($dictionary as $word)
  119.             {
  120.                 if(strpos($lowercasedContent$word) !== false)
  121.                 {
  122.                     return true;
  123.                 }
  124.             }
  125.             return false;
  126.         };
  127.         $contains_cyrillic = (bool) preg_match('/[\p{Cyrillic}]/u'$lowercasedContent);
  128.         if($isInSpamDictionary() || $contains_cyrillic)
  129.         {
  130.             return true;
  131.         }
  132.         return false;
  133.     }
  134.     private function getErrorMessages($data = array())
  135.     {
  136.         //Run basic spam filtering
  137.         $fields $this->fields;
  138.         $errors = array();
  139.         foreach($data as $key => $value)
  140.         {
  141.             if(strpos($value'>>>_') !== false)
  142.             {
  143.                 $errors[] = 'Spam';
  144.             } elseif ($key == 'other') {
  145.                 if ($this->isSpamBody($value)) {
  146.                     $errors[] = 'Spam';
  147.                 }
  148.             }
  149.         }
  150.         //Validate required fields
  151.         foreach ($fields as $name => $string) {
  152.             if ($name == 'email') {
  153.                 if (!$this->validateEmail($data['email']) || $data['email'] !== $data['emailConfirmation']) {
  154.                     $errors[] = $string;
  155.                 }
  156.             } else {
  157.                 if (is_null($data[$name])) {
  158.                     $errors[] = $string;
  159.                 }
  160.             }
  161.         }
  162.         return array_unique($errors);
  163.     }
  164.     private function afterSuccessfulSubmit($data$sourceUrl$ip$userAgent)
  165.     {
  166.         $noSpaceMail str_replace(" """$data['email']);
  167.         $url 'https://stat.webbamboo.net/item';
  168.         $data = array(
  169.             'target' => $sourceUrl,
  170.             'name' => $data["name"],
  171.             'email' => $noSpaceMail,
  172.             'data' => $data,
  173.             'ip' => $ip,
  174.             'user_agent' => $userAgent
  175.         );
  176.         // use key 'http' even if you send the request to https://...
  177.         $options = array(
  178.             'http' => array(
  179.                 'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
  180.                 'method'  => 'POST',
  181.                 'content' => http_build_query($data)
  182.             )
  183.         );
  184.         $context  stream_context_create($options);
  185.         $result file_get_contents($urlfalse$context);
  186.     }
  187.     private function sendConfirmation($data)
  188.     {
  189.         $fromEmail "kundtjanst@flyttstadning-direkt.se";
  190.         $formName "www.Flyttstadning-Direkt.se";
  191.         $subject "Tack för att du har kontaktat Flyttstadning-Direkt kundservice";
  192.         $email = (new TemplatedEmail())
  193.             ->from(new Address($fromEmail$formName))
  194.             ->to(new Address($data['email'], $data['name']))
  195.             ->subject($subject)
  196.             // path of the Twig template to render
  197.             ->htmlTemplate('Frontend/confirmation.email.twig')
  198.             // pass variables (name => value) to the template
  199.             ->context([
  200.                 'data' => $data,
  201.                 'subject' => $subject
  202.             ])
  203.         ;
  204.         $email->getHeaders()->addTextHeader('X-MC-ReturnPathDomain''return-path.flyttstadning-direkt.se');
  205.         $this->mailer->send($email);
  206.     }
  207.     #[Route("/form/parse"name'spinner_form_parse'methods: ['POST'])]
  208.     public function parseformAction(Request $request)
  209.     {
  210.         $this->constructForm($request);
  211.         $form $this->contactForm;
  212.         $session $request->getSession();
  213.         if ($request->isMethod('POST')) {
  214.             $form->handleRequest($request);
  215.             $data $form->getData();
  216.             $noSpaceMail str_replace(" """$data['email']);
  217.             //var_dump($this->get('request')->request->get('g-recaptcha-response'));die();
  218.             $recaptchaResponse $request->request->get('g-recaptcha-response');
  219.             $recaptcha = new ReCaptcha('6LekmfwSAAAAAEczRJjfsornV2iFtgANNFocb7LV');
  220.             $resp $recaptcha->verify($recaptchaResponse);
  221.             if ($resp->isSuccess()) {
  222.                 // verified!
  223.                 $data['recaptcha'] = 'ReCaptcha';
  224.             } else {
  225.                 $data['recaptcha'] = null;
  226.                 //var_dump($errors = $resp->getErrorCodes());die();
  227.             }
  228.             $routeParameters = array();
  229.             parse_str($data['routeparams'], $routeParameters);
  230.             $errors $this->getErrorMessages($data);
  231.             if (empty($errors)) {
  232.                 $url = array(
  233.                     "%C3%85""%C3%A5",
  234.                     "%C3%84""%C3%A4",
  235.                     "%C3%96""%C3%B6",
  236.                 );
  237.                 $char = array(
  238.                     "Å""å",
  239.                     "Ä""ä",
  240.                     "Ö""ö",
  241.                 );
  242.                 $currentUrl 'http://flyttstadning-direkt.se' str_replace($url$char$this->generateUrl($data['route'], $routeParameters)) . '#contactForm';
  243.                 
  244.                 $cleanZip trim(str_replace(" """$data['zip']));
  245.                 $subject 'Offert - Flyttstädning: '.$data['name'].' - '.intval($cleanZip).' ()';
  246.                 
  247.                 $email = (new TemplatedEmail())
  248.                     ->from(new Address('form@flyttstadning-direkt.se''Flyttstadning-Direkt.se'))
  249.                     ->to('smoth3r3d@gmail.com''mats@alyhr.se''lokedesu@gmail.com''oskar@alyhr.se')
  250.                     ->replyTo(new Address($noSpaceMail$data['name']))
  251.                     ->subject($subject)
  252.                     // path of the Twig template to render
  253.                     ->htmlTemplate('Frontend/email.html.twig')
  254.                     // pass variables (name => value) to the template
  255.                     ->context([
  256.                         'data' => $data,
  257.                         'url' => $currentUrl,
  258.                         'ip' => $request->getClientIp(),
  259.                         'subject' => $subject
  260.                     ])
  261.                 ;
  262.                 $email->getHeaders()->addTextHeader('X-MC-ReturnPathDomain''return-path.flyttstadning-direkt.se');
  263.                 $this->mailer->send($email);
  264.                 //Success message in Flashbag
  265.                 //
  266.                 
  267.                 $session->set('form-errors', array());
  268.                 $session->set('form-data', array());
  269.                 $succString 'Flyttstadning Direkt tackar dig för ditt intresse!';
  270.                 $this->addFlash('form-success'$succString);
  271.                 try
  272.                 {
  273.                     $this->afterSuccessfulSubmit($data$currentUrl$request->getClientIp(), $request->headers->get('User-Agent'));
  274.                     $this->sendConfirmation($data);
  275.                 } catch (\Exception $ex) {
  276.                 }
  277.             } else {
  278.                 $session->set('form-errors'$errors);
  279.                 $session->set('form-data'$data);
  280.                 //Error messages in Flashbag
  281.                 $errString 'Vänligen fyll i dom obligatoriska fälten: ' implode(', '$errors);
  282.                 $this->addFlash('form-error'$errString);
  283.             }
  284.             //Render the controller
  285.             switch ($data['route']) {
  286.                 case 'spinner_front_city':
  287.                     $countypermalink $routeParameters['countypermalink'];
  288.                     $citypermalink $routeParameters['citypermalink'];
  289.                     return $this->redirect($this->generateUrl('spinner_front_city', array(
  290.                                         'citypermalink' => $citypermalink,
  291.                                         'countypermalink' => $countypermalink
  292.                                     )) . '#contactForm');
  293.                     break;
  294.                 case 'spinner_front_county':
  295.                     $countypermalink $routeParameters['countypermalink'];
  296.                     return $this->redirect($this->generateUrl('spinner_front_county', array(
  297.                                         'countypermalink' => $countypermalink
  298.                                     )) . '#contactForm');
  299.                     break;
  300.                 case 'spinner_front_company':
  301.                     $citypermalink $routeParameters['citypermalink'];
  302.                     $companypermalink $routeParameters['companypermalink'];
  303.                     return $this->redirect($this->generateUrl('spinner_front_company', array(
  304.                                         'citypermalink' => $citypermalink,
  305.                                         'companypermalink' => $companypermalink
  306.                                     )) . '#contactForm');
  307.                     break;
  308.                 case 'spinner_front_index':
  309.                     return $this->redirect($this->generateUrl('spinner_front_index', array()) . '#contactForm');
  310.                     break;
  311.                 case 'spinner_front_pages':
  312.                     $pagepermalink $routeParameters['pagepermalink'];
  313.                     return $this->redirect($this->generateUrl('spinner_front_pages', array('pagepermalink' => $pagepermalink)) . '#contactForm');
  314.                     break;
  315.                 case 'spinner_front_articles_single':
  316.                     return $this->redirect($this->generateUrl('spinner_front_articles_single', array('articlepermalink' => $routeParameters['articlepermalink'])) . '#contactForm');
  317.                     break;
  318.             }
  319.         }
  320.     }
  321.     //Common functions
  322.     private function distance($lat1$lon1$lat2$lon2$unit)
  323.     {
  324.         $theta $lon1 $lon2;
  325.         $dist sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
  326.         $dist acos($dist);
  327.         $dist rad2deg($dist);
  328.         $miles $dist 60 1.1515;
  329.         $unit strtoupper($unit);
  330.         if ($unit == "K") {
  331.             return ($miles 1.609344);
  332.         } elseif ($unit == "N") {
  333.             return ($miles 0.8684);
  334.         } else {
  335.             return $miles;
  336.         }
  337.     }
  338.     private function generatePermalink($text)
  339.     {
  340.         $t strtolower($text);
  341.         $url=array(
  342.             "%C3%85","%C3%A5",
  343.             "%C3%84","%C3%A4",
  344.             "%C3%96","%C3%B6",
  345.             "%E9","%E9"
  346.         );
  347.         $char=array(
  348.             "Å","å",
  349.             "Ä","ä",
  350.             "Ö","ö",
  351.             "é","é"
  352.         );
  353.         $str str_replace($char$url$t);
  354.         $str_new str_replace(array(" "","), ""$str);
  355.         return $str_new;
  356.     }
  357.     private function getMenuHeading()
  358.     {
  359.         return $this->em->getRepository(Generalsettings::class)->findOneBySetting('MenuHeading');
  360.     }
  361.     private function getAnalytics()
  362.     {
  363.         $AnalyticsCode $this->em->getRepository(Generalsettings::class)->findOneBySetting('Analytics');
  364.         return str_replace(array('<p>''</p>''<br />'), ''html_entity_decode($AnalyticsCode->getValueSanitized()));
  365.     }
  366.     private function getFormLabels()
  367.     {
  368.         $formData $this->em->getRepository(Generalsettings::class)->findOneBySetting('formData');
  369.         return unserialize($formData->getValue());
  370.     }
  371.     private function getCounties()
  372.     {
  373.         return $this->em->getRepository(Counties::class)->findAll();
  374.     }
  375.     private function getPages()
  376.     {
  377.         return $this->em->getRepository(Page::class)->findAll();
  378.     }
  379.     private function getHeaderAlt()
  380.     {
  381.         $HeaderAltObj $this->em->getRepository(Generalsettings::class)->findOneBySetting('HeaderAlt');
  382.         return str_replace(array('<p>''</p>''<br />'), ''html_entity_decode($HeaderAltObj->getValue()));
  383.     }
  384.     private function getCities($cid)
  385.     {
  386.         $query $this->em->createQuery("SELECT c FROM Webbamboo\SpinnersCommon\Entity\City c WHERE c.county = $cid ORDER BY c.name ASC");
  387.         return $query->getResult();
  388.     }
  389.     private function getMostPopulatedCities($county)
  390.     {
  391.         $cid $county->getId();
  392.         $query $this->em->createQuery("SELECT c FROM Webbamboo\SpinnersCommon\Entity\City c WHERE c.county = $cid ORDER BY c.population DESC")->setMaxResults(10);
  393.         return $query->getResult();
  394.     }
  395.     private function getClosestCities($city)
  396.     {
  397.         $ID $city->getId();
  398.         //var_dump($ID, $city->getName());die();
  399.         $latitude $city->getLatitude();
  400.         $longitude $city->getLongitude();
  401.         $cityResponse = array();
  402.         $limit 5;
  403.         ///Do the dew
  404.         $rsm = new ResultSetMapping();
  405.         // build rsm here
  406.         $sqlT "SELECT *, latitude, longitude, SQRT( POW(69.1 * (latitude - :lat), 2) + POW(69.1 * (:lon - longitude) * COS(latitude / 57.3), 2)) AS distance FROM City WHERE id != $ID ORDER BY distance LIMIT 0, $limit";
  407.         $params = array(
  408.             'lat' => $latitude,
  409.             'lon' => $longitude,
  410.         );
  411.         $stmt $this->em->getConnection()->prepare($sqlT);
  412.         if (version_compare(phpversion(), '7.3''<')) {
  413.             $result $stmt->executeQuery($params);
  414.             
  415.             $citiesDistant $result->fetchAllAssociative();    
  416.         }
  417.         else
  418.         {
  419.             $result $stmt->executeQuery($params);
  420.             $citiesDistant $result->fetchAllAssociative();
  421.         }
  422.         foreach ($citiesDistant as $city) {
  423.             $objectCity $this->em->getRepository(City::class)->findOneById($city['id']);
  424.             $cityResponse[] = $objectCity;
  425.         }
  426.         return $cityResponse;
  427.     }
  428.     private function getCompanyResponse($city)
  429.     {
  430.         $companies $city->getCompanies();
  431.         $latitude $city->getLatitude();
  432.         $longitude $city->getLongitude();
  433.         $companyResponse = array();
  434.         if (count($companies) < 20) {
  435.             $limit 20;
  436.             ///Do the dew
  437.             $rsm = new ResultSetMapping();
  438.             // build rsm here
  439.             $sqlT "SELECT *, latitude, longitude, SQRT( POW(69.1 * (latitude - :lat), 2) + POW(69.1 * (:lon - longitude) * COS(latitude / 57.3), 2)) AS distance FROM Company ORDER BY distance LIMIT 0, $limit";
  440.             $params = array(
  441.                 'lat' => $latitude,
  442.                 'lon' => $longitude,
  443.             );
  444.             $stmt $this->em->getConnection()->prepare($sqlT);
  445.             if (version_compare(phpversion(), '7.3''<')) {
  446.                 $result $stmt->executeQuery($params);
  447.                 $companiesDistant $result->fetchAllAssociative();    
  448.             }
  449.             else
  450.             {
  451.                 $result $stmt->executeQuery($params);
  452.                 $companiesDistant $result->fetchAllAssociative();
  453.             }
  454.         }
  455.         foreach ($companies as $company) {
  456.             $ccity $company->getCityobj();
  457.             $c = array();
  458.             $c['id'] = $company->getId();
  459.             $c['name'] = $company->getName();
  460.             $c['phone'] = $company->getPhone();
  461.             $c['street'] = $company->getStreet();
  462.             $c['zip'] = $company->getZip();
  463.             $c['cityname'] = $ccity->getName();
  464.             //$c['distance'] = round($this->distance($company->getLatitude(), $company->getLongitude(), $city->getLatitude(), $city->getLongitude(), 'K'), 0);
  465.             $c['distance'] = '';
  466.             $c['permalink'] = $company->getPermalinkP();
  467.             $c['citypermalink'] = $ccity->getPermalinkP();
  468.             $c['countypermalink'] = $ccity->getCounty()->getPermalinkP();
  469.             $c['description'] = $company->getDescription();
  470.             //echo '<pre>';
  471.             //var_dump($c['name'], $company->getLatitude(), $company->getLongitude(), $city->getLatitude(), $city->getLongitude(),$this->distance($company->getLatitude(), $company->getLongitude(), $city->getLatitude(), $city->getLongitude(), 'K'));
  472.             $companyResponse[$company->getName()] = $c;
  473.         }
  474.         //Simupate getPermalinkP
  475.         $url=array(
  476.         "%C3%85","%C3%A5",
  477.         "%C3%84","%C3%A4",
  478.         "%C3%96","%C3%B6",
  479.         );
  480.         $char=array(
  481.          "Å","å",
  482.          "Ä","ä",
  483.          "Ö","ö",
  484.         );
  485.         if (isset($companiesDistant)) {
  486.             foreach ($companiesDistant as $company) {
  487.                 //var_dump($company['cityobj_id']);
  488.                 if (!is_null($company['cityobj_id'])) {
  489.                     $ccity $this->em->getRepository(City::class)->findOneById($company['cityobj_id']);
  490.                     $c = array();
  491.                     $c['id'] = (int)$company['id'];
  492.                     $c['name'] = $company['name'];
  493.                     $c['phone'] = $company['phone'];
  494.                     $c['street'] = $company['street'];
  495.                     $c['zip'] = $company['zip'];
  496.                     $c['cityname'] = $ccity->getName();
  497.                     $c['distance'] = round($this->distance($company['latitude'], $company['longitude'], $city->getLatitude(), $city->getLongitude(), 'K'), 0);
  498.                     $c['permalink'] = str_replace($url$char$company['permalink']);
  499.                     $c['citypermalink'] =  $ccity->getPermalinkP();
  500.                     $c['countypermalink'] = $ccity->getCounty()->getPermalinkP();
  501.                     $c['description'] = $company['description'] == 'none' '' $company['description'];
  502.                     if (!isset($companyResponse[$company['name']]) && count($companyResponse) <= 20) {
  503.                         $companyResponse[$company['name']] = $c;
  504.                     }
  505.                 }
  506.             }
  507.         }
  508.         return $companyResponse;
  509.     }
  510.     private function getCurrentCounty($countypermalink)
  511.     {
  512.         return $this->em->getRepository(Counties::class)->findOneByPermalink($this->generatePermalink(strtolower($countypermalink)));
  513.     }
  514.     private function getCurrentCity($citypermalink$county)
  515.     {
  516.         //with join maybe
  517.         $query $this->em->getRepository(City::class)->createQueryBuilder('c')
  518.             ->innerJoin('c.county''co')
  519.             ->where('co.id = :countyId')
  520.             ->andWhere('c.permalink = :permalink')
  521.             ->setParameters(array(
  522.                 'countyId' => $county->getId(),
  523.                 'permalink' => $this->generatePermalink(strtolower(str_replace(array("Å","Ä","Ö"), array("å","ä","ö",), $citypermalink))),
  524.             ))
  525.             ->getQuery();
  526.         $city $query->getResult();
  527.         return $city[0];
  528.         //return $this->em->getRepository('SpinnerBundle:City')->findOneByPermalink($this->generatePermalink(strtolower(str_replace(array("Å","Ä","Ö"),array("å","ä","ö",),$citypermalink))));
  529.     }
  530.     private function getCurrentPage($pagepermalink)
  531.     {
  532.         return $this->em->getRepository(Page::class)->findOneByPermalink($this->generatePermalink($pagepermalink));
  533.     }
  534.     private function getCurrentArticle($articlepermalink)
  535.     {
  536.         //var_dump($this->generatePermalink($articlepermalink));
  537.         return $this->em->getRepository(Article::class)->findOneByPermalink($articlepermalink);
  538.     }
  539.     private function getCurrentCompany($companypermalink)
  540.     {
  541.         return $this->em->getRepository(Company::class)->findOneByPermalink($this->generatePermalink(strtolower(str_replace(array("Å","Ä","Ö"), array("å","ä","ö",), $companypermalink))));
  542.     }
  543.     private function paginate($query)
  544.     {
  545.         $paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query$fetchJoinCollection false);
  546.         //$paginator
  547.         //    ->getQuery()
  548.         //    ->setFirstResult($pageSize * ($currentPage - 1)) // set the offset
  549.         //    ->setMaxResults($pageSize); // set the limit
  550.         return $paginator;
  551.     }
  552.     
  553.     private function getArticlesDefaults()
  554.     {
  555.         $settings $this->em->getRepository('Webbamboo\SpinnersCommon\Entity\Articlesettings')->findAll();
  556.         $defaults = array();
  557.         foreach ($settings as $s) {
  558.             $defaults[$s->getSetting()] = $s->getValue();
  559.         }
  560.         return $defaults;
  561.     }
  562.     #[Route("/"name'spinner_front_index'methods: ['GET'], options: ['utf8' => true])]
  563.     public function indexAction(Request $request)
  564.     {
  565.         $h1 $this->em->getRepository(Generalsettings::class)->findOneBySetting('H1Index');
  566.         $metatitle $this->em->getRepository(Generalsettings::class)->findOneBySetting('MetaTitleIndex');
  567.         $metadescription $this->em->getRepository(Generalsettings::class)->findOneBySetting('MetaDescriptionIndex');
  568.         $content $this->em->getRepository(Generalsettings::class)->findOneBySetting('ContentIndex')->getValue();
  569.         $WTMeta $this->em->getRepository(Generalsettings::class)->findOneBySetting('WebmasterToolsMeta');
  570.         $wt str_replace(array('&lt;''&gt;''<p>''</p>'), array('<''>'''''), $WTMeta->getValue());
  571.         return $this->render(
  572.             'Frontend/index.html.twig',
  573.                 array(
  574.                     'menuHeading' => $this->getMenuHeading(),
  575.                     'counties' => $this->getCounties(),
  576.                     'h1' => $h1->getValue(),
  577.                     'metatitle' => $metatitle->getValue(),
  578.                     'metadescription' => $metadescription->getValue(),
  579.                     'content' => $content,
  580.                     'pages'   => $this->getPages(),
  581.                     'WTMeta'    => $wt,
  582.                     'Analytics'    => $this->getAnalytics(),
  583.                     'headerAlt'    => $this->getHeaderAlt(),
  584.                     'form'    => $this->getFormView($request),
  585.                     'formLabels' => $this->getFormLabels(),
  586.                     'defaults'      => $this->getArticlesDefaults(),
  587.                     )
  588.                 );
  589.     }
  590.     #[Route('/Flyttstädning-{countypermalink}'name'spinner_front_county'methods: ['GET'], options: ['utf8' => true])]
  591.     #[Route('/flyttstädning-{countypermalink}'name'spinner_front_county_lowercase'methods: ['GET'], options: ['utf8' => true])]
  592.     public function countyAction($countypermalinkRequest $request)
  593.     {
  594.         return $this->render(
  595.             'Frontend/county.html.twig',
  596.             array(
  597.                 'counties' => $this->getCounties(),
  598.                 'activecounty' => $this->getCurrentCounty($countypermalink),
  599.                 'cities' => $this->getCities($this->getCurrentCounty($countypermalink)->getId()),
  600.                 'menuHeading' => $this->getMenuHeading(),
  601.                 'pages'   => $this->getPages(),
  602.                 'Analytics'    => $this->getAnalytics(),
  603.                 'headerAlt'    => $this->getHeaderAlt(),
  604.                 'form'    => $this->getFormView($request),
  605.                 'formLabels' => $this->getFormLabels(),
  606.                 'defaults'      => $this->getArticlesDefaults(),
  607.                 'mostpopulated' => $this->getMostPopulatedCities($this->getCurrentCounty($countypermalink))
  608.             )
  609.         );
  610.     }
  611.     #[Route('/Flyttstädning-{countypermalink}/Alla-orter'name'spinner_front_county_all'methods: ['GET'], options: ['utf8' => true], priority15)]
  612.     public function countyallAction($countypermalinkRequest $request)
  613.     {
  614.         $currentCounty $this->getCurrentCounty($countypermalink);
  615.         $data $this->em->getRepository('Webbamboo\SpinnersCommon\Entity\Allcitiesmeta')->findOneByCountyid($currentCounty->getId());
  616.         return $this->render(
  617.             'Frontend/countyall.html.twig',
  618.             array(
  619.                 'counties' => $this->getCounties(),
  620.                 'data' => $data,
  621.                 'activecounty' => $currentCounty,
  622.                 'cities' => $this->getCities($currentCounty->getId()),
  623.                 'menuHeading' => $this->getMenuHeading(),
  624.                 'pages'   => $this->getPages(),
  625.                 'Analytics'    => $this->getAnalytics(),
  626.                 'headerAlt'    => $this->getHeaderAlt(),
  627.                 'form'    => $this->getFormView($request),
  628.                 'formLabels' => $this->getFormLabels(),
  629.                 'defaults'      => $this->getArticlesDefaults()
  630.             )
  631.         );
  632.     }
  633.     #[Route('/Flyttstädning-{countypermalink}/image/{imagename}'name'spinner_front_county_thumbnail'methods: ['GET'], options: ['utf8' => true])]
  634.     public function countythumbnailAction(Request $request$countypermalink$imagenameKernelInterface $appKernel)
  635.     {
  636.         $county $this->getCurrentCounty($countypermalink);
  637.         if ($request->query->get('preview')) {
  638.             $manual true;
  639.         } else {
  640.             $manual $county->getManual();
  641.         }
  642.         $imagename $manual $county->getManualThumbnail().'-thumbnail.png' $county->getThumbnail()->getPath().'-thumbnail.png';
  643.         $imagepath $appKernel->getProjectDir().'/public/county/'.$imagename;
  644.         $headers = array(
  645.             'Content-Type' => 'image/png',
  646.             'Content-Disposition' => 'inline; filename="'.$imagename.'"'
  647.         );
  648.         return new Response(file_get_contents($imagepath), 200$headers);
  649.     }
  650.     #[Route('/Flyttstädning-{citypermalink}/{companypermalink}/image/{imagename}'name'spinner_front_company_thumbnail'methods: ['GET'], options: ['utf8' => true])]
  651.     public function companythumbnailAction(
  652.         Request $request
  653.         $citypermalink
  654.         $companypermalink
  655.         $imagename
  656.         KernelInterface $appKernel
  657.     )
  658.     {
  659.         $company $this->getCurrentCompany($companypermalink$citypermalink);
  660.         if ($request->query->get('preview')) {
  661.             $manual true;
  662.         } else {
  663.             $manual $company->getManual();
  664.         }
  665.         $imagename $manual $company->getManualThumbnail().'-thumbnail.png' $company->getThumbnail()->getPath().'-thumbnail.png';
  666.         $imagepath $appKernel->getProjectDir().'/public/company/'.$imagename;
  667.         $headers = array(
  668.              'Content-Type' => 'image/png',
  669.              'Content-Disposition' => 'inline; filename="'.$imagename.'"'
  670.          );
  671.         return new Response(file_get_contents($imagepath), 200$headers);
  672.     }
  673.     #[Route('/{countypermalink}/Flyttstädning-{citypermalink}'name'spinner_front_city'methods: ['GET'], options: ['utf8' => true])]
  674.     #[Route('/{countypermalink}/flyttstädning-{citypermalink}'name'spinner_front_city_lowercase'methods: ['GET'], options: ['utf8' => true])]
  675.     public function cityAction($countypermalink$citypermalinkRequest $request)
  676.     {
  677.         $currentCounty $this->getCurrentCounty($countypermalink);
  678.         $currentCity $this->getCurrentCity($citypermalink$currentCounty);
  679.         $stickyCompany $this->em->getRepository(Company::class)->findOneByName('FlyttstädningsAkuten AB');
  680.         return $this->render(
  681.             'Frontend/city.html.twig',
  682.             array(
  683.                 'menuHeading' => $this->getMenuHeading(),
  684.                 'counties' => $this->getCounties(),
  685.                 'activecounty' => $currentCounty,
  686.                 'city' => $currentCity,
  687.                 'companies' => $this->getCompanyResponse($currentCity),
  688.                 'pages'   => $this->getPages(),
  689.                 'Analytics'    => $this->getAnalytics(),
  690.                 'headerAlt'    => $this->getHeaderAlt(),
  691.                 'cities' => $this->getCities($currentCounty->getId()),
  692.                 'form'    => $this->getFormView($request),
  693.                 'formLabels' => $this->getFormLabels(),
  694.                 'defaults'      => $this->getArticlesDefaults(),
  695.                 'closestcities' => $this->getClosestCities($currentCity),
  696.                 'sticky' => $stickyCompany
  697.                 )
  698.             );
  699.     }
  700.     #[Route('/{countypermalink}/Flyttstädning-{citypermalink}/image/{imagename}'name'spinner_front_city_thumbnail'methods: ['GET'], options: ['utf8' => true])]
  701.     public function citythumbnailAction(
  702.         Request $request
  703.         $countypermalink
  704.         $citypermalink
  705.         $imagename,
  706.         KernelInterface $appKernel
  707.     )
  708.     {
  709.         $currentCounty $this->getCurrentCounty($countypermalink);
  710.         $city $this->getCurrentCity($citypermalink$currentCounty);
  711.         if ($request->query->get('preview')) {
  712.             $manual true;
  713.         } else {
  714.             $manual $city->getManual();
  715.         }
  716.         $imagename = ( $manual && $city->getManualThumbnail() ) ? $city->getManualThumbnail().'-thumbnail.png' $city->getThumbnail()->getPath().'-thumbnail.png';
  717.         $imagepath $appKernel->getProjectDir().'/public/city/'.$imagename;
  718.         $headers = array(
  719.             'Content-Type' => 'image/png',
  720.             'Content-Disposition' => 'inline; filename="'.$imagename.'"'
  721.         );
  722.         return new Response(file_get_contents($imagepath), 200$headers);
  723.     }
  724.     #[Route('/p/{pagepermalink}'name'spinner_front_pages'methods: ['GET'], options: ['utf8' => true], priority1)]
  725.     public function pageAction($pagepermalinkRequest $request)
  726.     {
  727.         return $this->render(
  728.             'Frontend/page.html.twig',
  729.             array(
  730.                 'menuHeading' => $this->getMenuHeading(),
  731.                 'page' => $this->getCurrentPage($pagepermalink),
  732.                 'counties' => $this->getCounties(),
  733.                 'pages'   => $this->getPages(),
  734.                 'Analytics'    => $this->getAnalytics(),
  735.                 'headerAlt'    => $this->getHeaderAlt(),
  736.                 'form'    => $this->getFormView($request),
  737.                 'formLabels' => $this->getFormLabels(),
  738.                 'defaults'      => $this->getArticlesDefaults(),
  739.                 'isPage' => true
  740.                 )
  741.             );
  742.     }
  743.     private function getCompanyCity($latitude$longitude$citypermalink)
  744.     {
  745.         //var_dump($latitude, $longitude, $citypermalink);die();
  746.         $cityResponse = array();
  747.         $limit 1;
  748.         ///Do the dew
  749.         $rsm = new ResultSetMapping();
  750.         // build rsm here
  751.         //var_dump($citypermalink, $latitude, $longitude);
  752.         $lowerPermalink strtolower($citypermalink);
  753.         $sqlT "SELECT *, latitude, longitude, SQRT( POW(69.1 * (latitude - :lat), 2) + POW(69.1 * (:lon - longitude) * COS(latitude / 57.3), 2)) AS distance FROM City WHERE permalink = :permalink OR permalink = :lower ORDER BY distance LIMIT 0, $limit";
  754.         $params = array(
  755.             'lat' => $latitude,
  756.             'lon' => $longitude,
  757.             'permalink' => $this->generatePermalink(str_replace(array("Å","Ä","Ö"), array("å","ä","ö",), $citypermalink)),
  758.             'lower' => $this->generatePermalink(strtolower(str_replace(array("Å","Ä","Ö"), array("å","ä","ö",), $citypermalink)))
  759.         );
  760.         $stmt $this->em->getConnection()->prepare($sqlT);
  761.         if (version_compare(phpversion(), '7.3''<')) {
  762.             $result $stmt->executeQuery($params);
  763.             $citiesDistant $result->fetchAllAssociative();    
  764.         }
  765.         else
  766.         {
  767.             $result $stmt->executeQuery($params);
  768.             $citiesDistant $result->fetchAllAssociative();
  769.         }
  770.         
  771.         $cityID $citiesDistant[0]['id'];
  772.         return $this->em->getRepository(City::class)->findOneById($cityID);
  773.     }
  774.     #[Route('/Flyttstädning-{citypermalink}/{companypermalink}'name'spinner_front_company'methods: ['GET'], options: ['utf8' => true])]
  775.     public function companyAction(
  776.         $citypermalink
  777.         $companypermalink
  778.         Request $request,
  779.         RedirectManager $redirectManager
  780.     )
  781.     {
  782.         $company $this->getCurrentCompany($companypermalink$citypermalink);
  783.         if ($company->getCityobj()->getPermalink() == $this->generatePermalink(strtolower(str_replace(array("Å","Ä","Ö"), array("å","ä","ö",), $citypermalink)))) {
  784.             $currentCity $company->getCityobj();
  785.         } else {
  786.             $currentCity $this->getCompanyCity($company->getLatitude(), $company->getLongitude(), $citypermalink);
  787.         }
  788.         if ($redirectManager $redirectManager->work($company->getId(), $currentCity->getId())) {
  789.             return $this->redirect($redirectManager301);
  790.         }
  791.         
  792.         //FlyttstädningsAkuten AB entry
  793.         $stickyCompany $this->em->getRepository(Company::class)->findOneByName('FlyttstädningsAkuten AB');
  794.         return $this->render(
  795.             'Frontend/company.html.twig',
  796.             array(
  797.                 'menuHeading' => $this->getMenuHeading(),
  798.                 'counties' => $this->getCounties(),
  799.                 'activecounty' => $currentCity->getCounty(),
  800.                 'city' => $currentCity,
  801.                 'company' => $company,
  802.                 'pages'   => $this->getPages(),
  803.                 'Analytics'    => $this->getAnalytics(),
  804.                 'headerAlt'    => $this->getHeaderAlt(),
  805.                 'cities' => $this->getCities($currentCity->getCounty()->getId()),
  806.                 'form'    => $this->getFormView($request),
  807.                 'formLabels' => $this->getFormLabels(),
  808.                 'defaults'      => $this->getArticlesDefaults(),
  809.                 'closestcities' => $this->getClosestCities($currentCity),
  810.                 'sticky' => $stickyCompany
  811.                 )
  812.             );
  813.     }
  814.     #[Route('/a/'name'spinner_front_articles'methods: ['GET'], options: ['utf8' => true])]
  815.     #[Route('/a/page{pagenumber}'name'spinner_front_articles_pages'methods: ['GET'], options: ['utf8' => true])]
  816.     public function articlesloopAction($pagenumber=1)
  817.     {
  818.         $paginator $this->articleRepository->findPaginated($pagenumber);
  819.         $metaData $this->em->getRepository(Allpagesmeta::class)->findOneByPagenumber($pagenumber);
  820.         $defaults $this->getArticlesDefaults();
  821.         if ($metaData) {
  822.             $metaDescription $metaData->getMetadescription() ? $metaData->getMetadescription() : $defaults['MetaDescriptionArticlesLoop'];
  823.             $metaTitle $metaData->getMetatitle() ? $metaData->getMetatitle() : $defaults['MetaTitleArticlesLoop'];
  824.         } else {
  825.             $metaDescription $defaults['MetaDescriptionArticlesLoop'];
  826.             $metaTitle $defaults['MetaTitleArticlesLoop'];
  827.         }
  828.         return $this->render(
  829.             'Frontend/articlesloop.html.twig',
  830.             array(
  831.                 'articles'  => $paginator->getIterator(),
  832.                 'totalItems'    => $paginator->count(),
  833.                 'pagesCount'    => ceil(count($paginator) / 20),
  834.                 'defaults'      => $defaults,
  835.                 'currentPage'   => $pagenumber,
  836.                 'counties' => $this->getCounties(),
  837.                 'pages'   => $this->getPages(),
  838.                 'Analytics'    => $this->getAnalytics(),
  839.                 'headerAlt'    => htmlentities($this->getHeaderAlt()),
  840.                 'metaDescription' => $metaDescription,
  841.                 'metaTitle' => $metaTitle
  842.             )
  843.         );
  844.     }
  845.     #[Route('/a/{articlepermalink}'name'spinner_front_articles_single'methods: ['GET'], options: ['utf8' => true])]
  846.     public function articleAction($articlepermalinkRequest $request)
  847.     {
  848.         $article $this->getCurrentArticle($articlepermalink);
  849.         if($article->getStatus() === Article::STATUS_DRAFT)
  850.         {
  851.             $this->denyAccessUnlessGranted('ROLE_ADMIN');
  852.         }
  853.         return $this->render(
  854.             'Frontend/page.html.twig',
  855.             array(
  856.                 'menuHeading' => $this->getMenuHeading(),
  857.                 'page' => $article,
  858.                 'counties' => $this->getCounties(),
  859.                 'pages'   => $this->getPages(),
  860.                 'Analytics'    => $this->getAnalytics(),
  861.                 'headerAlt'    => $this->getHeaderAlt(),
  862.                 'defaults'      => $this->getArticlesDefaults(),
  863.                 'isPage' => false,
  864.                 'form'    => $this->getFormView($request),
  865.                 'formLabels' => $this->getFormLabels()
  866.                 )
  867.             );
  868.     }
  869. }