src/Controller/TourController.php line 25

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\CanonicalRedirectHelper;
  4. use App\Twig\LinkGenerator;
  5. use App\Twig\RegionExtension;
  6. use Carbon\Carbon;
  7. use Elements\Bundle\AlpsteinBundle\Services\AlpsteinConfig;
  8. use Elements\Bundle\CmsToolsBundle\Tool\Helper\FunctionsHelper;
  9. use Jaybizzle\CrawlerDetect\CrawlerDetect;
  10. use Knp\Component\Pager\PaginatorInterface;
  11. use Pimcore\Model\DataObject;
  12. use Pimcore\Model\DataObject\AlpsteinCategory;
  13. use Pimcore\Model\DataObject\AlpsteinTour;
  14. use Pimcore\Model\DataObject\Region;
  15. use Pimcore\Model\Document\Editable;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. class TourController extends AbstractController
  21. {
  22.     public function overviewAction(Request $requestPaginatorInterface $paginatorRegionExtension $regionExtension)
  23.     {
  24.         $viewParams = [];
  25.         // Load Kategorien
  26.         $alpsteinFiltering = new AlpsteinTour\Listing();
  27.         $alpsteinFiltering->addConditionParam("name != '' AND name IS NOT NULL");
  28.         // caching filterdata using a file in private var folder. not sure why pimcore cache doesn't work here. it hits some kind of limit of 50 elements in cache
  29.         // also this way the generation of filter data can be outsources to a command
  30.         $filename PIMCORE_PRIVATE_VAR '/tourFilterData-Cache-' $request->getLocale() . '.json';
  31.         if (file_exists($filename) && filemtime($filename) > strtotime('-1 day') && !$request->get('cache-new')) {
  32.             $filteringData json_decode(file_get_contents($filename), true);
  33.         } else {
  34.             $filteringData = [];
  35.         }
  36.         if (empty($filteringData)) {
  37.             $filteringData = [
  38.                 'length' => [
  39.                     'min' => 0.0,
  40.                     'max' => 0.0
  41.                 ],
  42.                 'duration' => [
  43.                     'min' => 0.0,
  44.                     'max' => 0.0
  45.                 ],
  46.                 'altitude' => [
  47.                     'min' => 0.0,
  48.                     'max' => 0.0
  49.                 ],
  50.                 'categories' => [],
  51.                 'regions' => []
  52.             ];
  53.             foreach( $alpsteinFiltering as $tour ){
  54.                 // get All Filters
  55.                 // Length
  56.                 $length = ( (float)$tour->getLength() / 1000) + 1;
  57.                 if( $filteringData['length']['max'] < $length ){
  58.                     $filteringData['length']['max'] = number_format$length1'.''' );
  59.                 }
  60.                 // Duration
  61.                 $duration = (int)($tour->getTimeMin()/60) + 1;
  62.                 if( $filteringData['duration']['max'] < $duration ){
  63.                     $filteringData['duration']['max'] = $duration;
  64.                 }
  65.                 // Altitude
  66.                 $altitude = (int)$tour->getElevationAscent();
  67.                 if( $filteringData['altitude']['max'] < $altitude ){
  68.                     $filteringData['altitude']['max'] = $altitude;
  69.                 }
  70.                 // Categories
  71.                 foreach( $tour->getCategory() as $cat ){
  72.                     if( $cat instanceof AlpsteinCategory ){
  73.                         $filteringData['categories'][$cat->getId()] = [
  74.                             'id' => $cat->getId(),
  75.                             'name' => $cat->getName(),
  76.                             'sorting' => $cat->getSorting() ?? 9999999999999999
  77.                         ];
  78.                     }
  79.                 }
  80.             }
  81. //            sort categories by sorting
  82.             usort($filteringData['categories'], function($a$b) {
  83.                 return $a['sorting'] <=> $b['sorting'];
  84.             });
  85.             // Regions
  86.             $regions = new Region\Listing();
  87.             $regions->addConditionParam('IFNULL(generalSolutionsId, "") != "" AND IFNULL(isMainRegion, 0) != 1');
  88.             $regions->setOrderKey('sorting');
  89.             foreach($regions as $region) {
  90.                 $filteringData['regions'][$region->getId()] = [
  91.                     'id' => $region->getId(),
  92.                     'name' => $region->getName()
  93.                 ];
  94.             }
  95.             file_put_contents($filenamejson_encode($filteringData));
  96.         }
  97.         // Filter Ergebnis
  98.         $tourListing = new AlpsteinTour\Listing();
  99.         $tourListing->addConditionParam("name != '' AND name IS NOT NULL");
  100.         /** @var Editable\Numeric $qsEditable */
  101.         $qsEditable $this->getDocumentEditable('numeric''qs');
  102.         // disable for now --> should be reactivated when ranking is filled in every tour
  103. //        if (!$qsEditable->isEmpty()) {
  104. //            $tourListing->addConditionParam("ranking >= " . $qsEditable->getData());
  105. //        }
  106.         // Prefilter Region/Tour Type
  107.         /** @var DataObject\Community[] $regions */
  108.         if ($regions $this->getDocumentEditable('relations''regions')) {
  109.             $regionsCond = [];
  110.             foreach ($regions as $region) {
  111.                 if ($region instanceof Region) {
  112.                     $regionsCond[] = 'mainRegion__id = ' $region->getId();
  113.                     $regionAndCommunityId $regionExtension->getAllCommunityIdsByRegion($regionfalsetrue$request->get('clearCache'false));
  114.                     $regionsCond[] =  'communityObjects LIKE "%,' implode(',%" OR communityObjects LIKE "%,'$regionAndCommunityId) . ',%"';
  115.                 } else if($region instanceof DataObject\Community) {
  116.                     $regionsCond[] = 'communityObjects LIKE "%,' $region->getId() . ',%"';
  117.                 }
  118.             }
  119.             if (!empty($regionsCond)) {
  120.                 $tourListing->addConditionParam('(' implode(' OR '$regionsCond) . ')');
  121.             }
  122.         }
  123.         $showCategoriesAsFilter $this->getDocumentEditable('checkbox''showCategoriesAsFilter')->isChecked();
  124.         /** @var AlpsteinCategory[] $categories */
  125.         $filteringData['filterCategories'] = [];
  126.         if ($categories $this->getDocumentEditable('relations''categories')) {
  127.             $categoriesCond = [];
  128.             foreach ($categories as $category) {
  129.                 if($showCategoriesAsFilter) {
  130.                     $filteringData['filterCategories'][] = $category;
  131.                 }
  132.                 $categoriesCond[] = 'category LIKE "%,' $category->getId() . ',%"';
  133.             }
  134.             if (!empty($categoriesCond)) {
  135.                 $tourListing->addConditionParam('(' implode(' OR '$categoriesCond) . ')');
  136.             }
  137.         }
  138.         if ($community DataObject\Community::getById($request->get('community'))) {
  139.             $viewParams['community'] = $community;
  140.             $functionsHelper = new FunctionsHelper();
  141.             if (false) { // seems to be more acurate than radius search because radius search only considers starting point
  142.                 $tourListing->addConditionParam('communityObjects LIKE :communityId', ['communityId' => '%,' $community->getId() . ',%']);
  143.             } else if (!empty($community->getDetailRelatedTours())) {
  144.                 $ids = [];
  145.                 foreach($community->getDetailRelatedTours() as $relatedTour) {
  146.                     $ids[] = $relatedTour->getId();
  147.                 }
  148.                 if (!empty($ids)) {
  149.                     $tourListing->addConditionParam('o_id IN (' implode(','$ids) . ')');
  150.                 }
  151.             } else {
  152.                 $radius $community->getDetailRadiusTour() ?: 10;
  153.                 $tourListing->addConditionParam($functionsHelper->getGeoDistanceQuery(new DataObject\Data\GeoCoordinates($community->getGeoposition()->getLatitude(), $community->getGeoposition()->getLongitude()), 'startingPoint') . ' <= ' $radius);
  154.             }
  155.         }
  156.         // Filter Keyword
  157.         if( $request->get('tourKeyword') ){
  158.             $tourListing->addConditionParam('name LIKE :keyword', [ 'keyword' => '%' $request->get('tourKeyword') . '%' ]);
  159.         }
  160.         // Filter Public Transport Friendly
  161.         if ($request->get('publicTransportFriendly')) {
  162.             $tourListing->addConditionParam('IFNULL(publicTransportFriendly, 0) = 1');
  163.         }
  164.         // Filter Categories
  165.         if( $request->get('tourCategory'0) && $request->get('tourCategory') != 'all' ){
  166.             $tourListing->addConditionParam('category LIKE :catId', [ 'catId' => '%,' $request->get('tourCategory') . ',%' ]);
  167.         }
  168.         // Filter Difficulty
  169.         if( $request->get('tourDifficulty'0) && $request->get('tourDifficulty') != 'all' ){
  170.             $tourListing->addConditionParam('ratingDifficulty = :difficulty', [ 'difficulty' => $request->get('tourDifficulty') ]);
  171.         }
  172.         // Filter Startpunkt
  173.         if( $request->get('tourStart'0) && $request->get('tourStart') != 'all' ){
  174.             $tourListing->addConditionParam('startingPointDesc = :tourStart', [ 'tourStart' => $request->get('tourStart') ]);
  175.         }
  176.         // Filter Region
  177.         if( $request->get('tourRegion'0) && $request->get('tourRegion') != 'all' ){
  178.             $region DataObject::getById($request->get('tourRegion'));
  179.             $regionsCond = [];
  180.             if ($region instanceof Region) {
  181.                 $regionsCond[] = 'mainRegion__id = ' $region->getId();
  182.                 $regionAndCommunityId $regionExtension->getAllCommunityIdsByRegion($regionfalsetrue$request->get('clearCache'false));
  183.                 $regionsCond[] =  'communityObjects LIKE "%,' implode(',%" OR communityObjects LIKE "%,'$regionAndCommunityId) . ',%"';
  184.             } else if($region instanceof DataObject\Community) {
  185.                 $regionsCond[] = 'communityObjects LIKE "%,' $region->getId() . ',%"';
  186.             }
  187.             if (!empty($regionsCond)) {
  188.                 $tourListing->addConditionParam('(' implode(' OR '$regionsCond) . ')');
  189.             }
  190.         }
  191.         // Filter Properties
  192.         if( $request->get('tourProperty'0) && $request->get('tourProperty') != 'all' ){
  193.             $tourListing->addConditionParam('tourProperties LIKE :property', ['property' => '%,' $request->get('tourProperty') . ',%']);
  194.         }
  195.         // Filter Strecke
  196.         if( $request->get('rangeLengthMin'0) || $request->get('rangeLengthMax'0) ){
  197.             $streckeMin = ((float) $request->get('rangeLengthMin'0)) * 1000;
  198.             $streckeMax = ((float) $request->get('rangeLengthMax'$filteringData['length']['max'])) * 1000;
  199.             $tourListing->addConditionParam('( IFNULL(length, 0) >= :lengthMin AND IFNULL(length, 0) <= :lengthMax )', [ 'lengthMin' => $streckeMin'lengthMax' => $streckeMax ]);
  200.         }
  201.         // Filter Dauer
  202.         if( $request->get('durationMin'0) || $request->get('durationMax'0) ){
  203.             $timeMin = ((float) $request->get('durationMin'0)) * 60;
  204.             $timeMax = ((float) $request->get('durationMax'$filteringData['duration']['max'])) * 60;
  205.             $tourListing->addConditionParam('( IFNULL(timeMin, 0) >= :timeMin AND IFNULL(timeMin, 0) <= :timeMax )', [ 'timeMin' => $timeMin'timeMax' => $timeMax ]);
  206.         }
  207.         // Filter Altitude
  208.         if( $request->get('altitudeMin'0) || $request->get('altitudeMax'0) ){
  209.             $altitudeMin = (float) $request->get('altitudeMin'0);
  210.             $altitudeMax = (float) $request->get('altitudeMax'$filteringData['altitude']['max']);
  211. //            $tourListing->addConditionParam('( (elevationMaxAltitude - elevationMinAltitude) >= :altitudeMin AND (elevationMaxAltitude - elevationMinAltitude) <= :altitudeMax )', [ 'altitudeMin' => $altitudeMin, 'altitudeMax' => $altitudeMax ]);
  212.             $tourListing->addConditionParam('( IFNULL(elevationAscent, 0) >= :altitudeMin AND IFNULL(elevationAscent, 0) <= :altitudeMax )', [ 'altitudeMin' => $altitudeMin'altitudeMax' => $altitudeMax ]);
  213.         }
  214.         $sorting $this->getDocumentEditable('select''tour_sorting')?->getData();
  215.         if(!empty($sorting)) {
  216.             $tourListing->setOrderKey($sortingfalse);
  217.         }
  218.         // Paginator
  219.         $paginator $paginator->paginate$tourListing$request->get('page'1), 16 );
  220.         $paginator->setPageRange);
  221.         $viewParams['tourListing'] = $paginator;
  222.         $viewParams['filterData'] = $filteringData;
  223.         if ($request->isXmlHttpRequest()) {
  224.             return $this->json([
  225.                 'success' => true,
  226.                 'html' => $this->renderView('Tour/container.html.twig'$viewParams)
  227.             ]);
  228.         }
  229.         return $this->renderTemplate('Tour/overview.html.twig'$viewParams);
  230.     }
  231.     public function detailAction(Request $requestAlpsteinConfig $alpsteinConfigAlpsteinTour $idCanonicalRedirectHelper $redirectHelper)
  232.     {
  233.         $object $id;
  234.         if( !$object || ( !$object->isPublished() && !$this->editmode && !$request->get('pimcore_object_preview') && !$_COOKIE['pimcore_admin_sid'] ) ) {
  235.             throw new NotFoundHttpException("The requested object doesn't exist anymore");
  236.         }
  237.         if (CanonicalRedirectHelper::ENABLE_CANONICAL_REDIRECT && $redirect $redirectHelper->canonicalRedirect($object)) {
  238.             return $redirect;
  239.         }
  240.         if (!empty($object->getManualRecommendation())) {
  241.             $recommendations $object->getManualRecommendation();
  242.         } else {
  243.             $recommendations = [];
  244.             $crawlerDetect = new CrawlerDetect();
  245.             // only show recommendations for non-crawlers, because geoDistanceQuery is performance intensive
  246.             if(!$crawlerDetect->isCrawler()){
  247.                 $recommendations = new AlpsteinTour\Listing();
  248.                 $recommendations->addConditionParam('name != "" AND name IS NOT NULL AND o_id != ' $object->getId());
  249.                 if (!$object->getDisableRadiusLimitation() && $object->getStartingPoint()) {
  250.                     $functionsHelper = new FunctionsHelper();
  251.                     $recommendations->addConditionParam($functionsHelper->getGeoDistanceQuery($object->getStartingPoint(), 'startingPoint') . ' < 10');
  252.                 }
  253.                 $categoryCondition = [];
  254.                 if (!empty($object->getSimilarCategories())) {
  255.                     $categories $object->getSimilarCategories();
  256.                 } else {
  257.                     $categories $object->getCategory();
  258.                 }
  259.                 foreach ($categories ?: [] as $category) {
  260.                     $categoryCondition[] = 'category LIKE "%,' $category->getId() . ',%"';
  261.                 }
  262.                 if (!empty($categoryCondition)) {
  263.                     $recommendations->addConditionParam('(' implode(' OR '$categoryCondition) . ')');
  264.                 }
  265.                 $recommendations->setLimit(7);
  266.                 $recommendations->setOrderKey('RAND()'false);
  267.             } else {
  268.                 // just log, if crawler is detected
  269.                 file_put_contents(PIMCORE_LOG_DIRECTORY '/blocked_tour_detail-requests.log'"[" Carbon::now()->format("Y-m-d H:i:s") . "] " .  $crawlerDetect->getMatches(). ": " $request->getRequestUri() .PHP_EOLFILE_APPEND LOCK_EX);
  270.             }
  271.         }
  272.         return $this->renderTemplate('Tour/detail.html.twig', [
  273.             'tour' => $object,
  274.             'alpsteinConfig' => $alpsteinConfig,
  275.             'recommendations' => $recommendations
  276.         ]);
  277.     }
  278.     /**
  279.      * @param Request $request
  280.      * @return RedirectResponse
  281.      * @Route("{_locale}/api/{type}/326442/tour-redirect/{foreignId}", name="pia_map", requirements={"type"="alpstein|contwise"})
  282.      */
  283.     public function mapPiaLink(Request $requestLinkGenerator $linkGenerator) {
  284.         $tour AlpsteinTour::getByAlpsteinId($request->get('foreignId'), 1) ?? AlpsteinTour::getByGeneralSolutionsId($request->get('foreignId'), 1);
  285.         if(!$tour) {
  286.             throw new NotFoundHttpException("invalid tour");
  287.         }
  288.         $url $linkGenerator->generate($tour);
  289.         if(!$url) {
  290.             throw new NotFoundHttpException("Redirect not possible");
  291.         }
  292.         return new RedirectResponse($url);
  293.     }
  294. }