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 Carbon\Carbon;
  6. use Elements\Bundle\AlpsteinBundle\Services\AlpsteinConfig;
  7. use Elements\Bundle\CmsToolsBundle\Tool\Helper\FunctionsHelper;
  8. use Jaybizzle\CrawlerDetect\CrawlerDetect;
  9. use Knp\Component\Pager\PaginatorInterface;
  10. use Pimcore\Model\DataObject;
  11. use Pimcore\Model\DataObject\AlpsteinCategory;
  12. use Pimcore\Model\DataObject\AlpsteinRegion;
  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 $paginator)
  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.                         ];
  77.                     }
  78.                 }
  79.             }
  80.             asort$filteringData['categories'] );
  81.             // Regions
  82.             $regions = new Region\Listing();
  83.             $regions->addConditionParam('alpsteinRegions != "" AND alpsteinRegions IS NOT NULL');
  84.             $regions->setOrderKey('sorting');
  85.             foreach($regions as $region) {
  86.                 $filteringData['regions'][$region->getId()] = [
  87.                     'id' => $region->getId(),
  88.                     'name' => $region->getName()
  89.                 ];
  90.             }
  91.             file_put_contents($filenamejson_encode($filteringData));
  92.         }
  93.         // Filter Ergebnis
  94.         $tourListing = new AlpsteinTour\Listing();
  95.         $tourListing->addConditionParam("name != '' AND name IS NOT NULL");
  96.         /** @var Editable\Numeric $qsEditable */
  97.         $qsEditable $this->getDocumentEditable('numeric''qs');
  98.         // disable for now --> should be reactivated when ranking is filled in every tour
  99. //        if (!$qsEditable->isEmpty()) {
  100. //            $tourListing->addConditionParam("ranking >= " . $qsEditable->getData());
  101. //        }
  102.         // Prefilter Region/Tour Type
  103.         /** @var AlpsteinRegion[] $regions */
  104.         if ($regions $this->getDocumentEditable('relations''regions')) {
  105.             $regionsCond = [];
  106.             foreach ($regions as $region) {
  107.                 if ($region instanceof Region) {
  108.                     foreach ($region->getAlpsteinRegions() ?: [] as $alpsteinRegion) {
  109.                         // not needed as alpstein adds all regions and subregions to tour
  110. //                        foreach (self::getAllSubRegionIds($alpsteinRegion) ?: [] as $subRegionId) {
  111. //                            $regionsCond[] = 'regions LIKE "%,' . $subRegionId . ',%"';
  112. //                        }
  113.                         $regionsCond[] = 'regions LIKE "%,' $alpsteinRegion->getId() . ',%"';
  114.                     }
  115.                 } else if ($region instanceof AlpsteinRegion) {
  116.                     foreach (self::getAllSubRegionIds($region) ?: [] as $subRegionId) {
  117.                         $regionsCond[] = 'regions LIKE "%,' $subRegionId ',%"';
  118.                     }
  119.                     $regionsCond[] = 'regions LIKE "%,' $region->getId() . ',%"';
  120.                 }
  121.             }
  122.             if (!empty($regionsCond)) {
  123.                 $tourListing->addConditionParam('(' implode(' OR '$regionsCond) . ')');
  124.             }
  125.         }
  126.         /** @var AlpsteinCategory[] $categories */
  127.         $filteringData['childCategories'] = [];
  128.         if ($categories $this->getDocumentEditable('relations''categories')) {
  129.             $categoriesCond = [];
  130.             foreach ($categories as $category) {
  131.                 foreach ($category->getChildren() ?: [] as $childCategory) {
  132.                     if ($childCategory instanceof AlpsteinCategory) {
  133.                         $categoriesCond[] = 'category LIKE "%,' $childCategory->getId() . ',%"';
  134.                         $filteringData['childCategories'][] = $childCategory;
  135.                     }
  136.                 }
  137.                 $categoriesCond[] = 'category LIKE "%,' $category->getId() . ',%"';
  138.             }
  139.             if (!empty($categoriesCond)) {
  140.                 $tourListing->addConditionParam('(' implode(' OR '$categoriesCond) . ')');
  141.             }
  142.         }
  143.         if ($community DataObject\Community::getById($request->get('community'))) {
  144.             $viewParams['community'] = $community;
  145.             $functionsHelper = new FunctionsHelper();
  146.             if (false) { // seems to be more acurate than radius search because radius search only considers starting point
  147.                 $communityCond = [];
  148.                 foreach ($community->getAlpsteinObjects() ?: [] as $alpsteinRegion) {
  149.                     if ($alpsteinRegion instanceof DataObject\AlpsteinCommunity) {
  150.                         $communityCond[] = 'communities LIKE "%,' $alpsteinRegion->getId() . ',%"';
  151.                     } else if ($alpsteinRegion instanceof AlpsteinRegion) {
  152.                         $communityCond[] = 'regions LIKE "%,' $alpsteinRegion->getId() . ',%"';
  153.                     }
  154.                 }
  155.                 if (!empty($communityCond)) {
  156.                     $tourListing->addConditionParam('(' implode(' OR '$communityCond) . ')');
  157.                 }
  158.             } else if (!empty($community->getDetailRelatedTours())) {
  159.                 $ids = [];
  160.                 foreach($community->getDetailRelatedTours() as $relatedTour) {
  161.                     $ids[] = $relatedTour->getId();
  162.                 }
  163.                 if (!empty($ids)) {
  164.                     $tourListing->addConditionParam('o_id IN (' implode(','$ids) . ')');
  165.                 }
  166.             } else {
  167.                 $radius $community->getDetailRadiusTour() ?: 10;
  168.                 $tourListing->addConditionParam($functionsHelper->getGeoDistanceQuery(new DataObject\Data\GeoCoordinates($community->getGeoposition()->getLatitude(), $community->getGeoposition()->getLongitude()), 'startingPoint') . ' <= ' $radius);
  169.             }
  170.         }
  171.         // Filter Keyword
  172.         if( $request->get('tourKeyword') ){
  173.             $tourListing->addConditionParam('name LIKE :keyword', [ 'keyword' => '%' $request->get('tourKeyword') . '%' ]);
  174.         }
  175.         // Filter Public Transport Friendly
  176.         if ($request->get('publicTransportFriendly')) {
  177.             $tourListing->addConditionParam('IFNULL(publicTransportFriendly, 0) = 1');
  178.         }
  179.         // Filter Categories
  180.         if( $request->get('tourCategory'0) && $request->get('tourCategory') != 'all' ){
  181.             $category AlpsteinCategory::getById($request->get('tourCategory'));
  182.             if ($category instanceof AlpsteinCategory) {
  183.                 $categoriesCond = [];
  184.                 foreach ($category->getChildren() ?: [] as $childCategory) {
  185.                     if ($childCategory instanceof AlpsteinCategory) {
  186.                         $categoriesCond[] = 'category LIKE "%,' $childCategory->getId() . ',%"';
  187.                     }
  188.                 }
  189.                 $categoriesCond[] = 'category LIKE "%,' $category->getId() . ',%"';
  190.                 if (!empty($categoriesCond)) {
  191.                     $tourListing->addConditionParam('(' implode(' OR '$categoriesCond) . ')');
  192.                 }
  193.             }
  194.             $tourListing->addConditionParam('category LIKE :catId', [ 'catId' => '%,' $request->get('tourCategory') . ',%' ]);
  195.         }
  196.         // Filter Difficulty
  197.         if( $request->get('tourDifficulty'0) && $request->get('tourDifficulty') != 'all' ){
  198.             $tourListing->addConditionParam('ratingDifficulty = :difficulty', [ 'difficulty' => $request->get('tourDifficulty') ]);
  199.         }
  200.         // Filter Startpunkt
  201.         if( $request->get('tourStart'0) && $request->get('tourStart') != 'all' ){
  202.             $tourListing->addConditionParam('startingPointDesc = :tourStart', [ 'tourStart' => $request->get('tourStart') ]);
  203.         }
  204.         // Filter Region
  205.         if( $request->get('tourRegion'0) && $request->get('tourRegion') != 'all' ){
  206.             $region DataObject::getById($request->get('tourRegion'));
  207.             $regionsCond = [];
  208.             if ($region instanceof Region) {
  209.                 foreach ($region->getAlpsteinRegions() ?: [] as $alpsteinRegion) {
  210.                     $regionsCond[] = 'regions LIKE "%,' $alpsteinRegion->getId() . ',%"';
  211.                 }
  212.             } else if ($region instanceof AlpsteinRegion) {
  213.                 foreach (self::getAllSubRegionIds($region) ?: [] as $subRegionId) {
  214.                     $regionsCond[] = 'regions LIKE "%,' $subRegionId ',%"';
  215.                 }
  216.                 $regionsCond[] = 'regions LIKE "%,' $region->getId() . ',%"';
  217.             }
  218.             if (!empty($regionsCond)) {
  219.                 $tourListing->addConditionParam('(' implode(' OR '$regionsCond) . ')');
  220.             }
  221.         }
  222.         // Filter Properties
  223.         if( $request->get('tourProperty'0) && $request->get('tourProperty') != 'all' ){
  224.             $tourListing->addConditionParam('tourProperties LIKE :property', ['property' => '%,' $request->get('tourProperty') . ',%']);
  225.         }
  226.         // Filter Strecke
  227.         if( $request->get('rangeLengthMin'0) || $request->get('rangeLengthMax'0) ){
  228.             $streckeMin = ((float) $request->get('rangeLengthMin'0)) * 1000;
  229.             $streckeMax = ((float) $request->get('rangeLengthMax'$filteringData['length']['max'])) * 1000;
  230.             $tourListing->addConditionParam('( IFNULL(length, 0) >= :lengthMin AND IFNULL(length, 0) <= :lengthMax )', [ 'lengthMin' => $streckeMin'lengthMax' => $streckeMax ]);
  231.         }
  232.         // Filter Dauer
  233.         if( $request->get('durationMin'0) || $request->get('durationMax'0) ){
  234.             $timeMin = ((float) $request->get('durationMin'0)) * 60;
  235.             $timeMax = ((float) $request->get('durationMax'$filteringData['duration']['max'])) * 60;
  236.             $tourListing->addConditionParam('( IFNULL(timeMin, 0) >= :timeMin AND IFNULL(timeMin, 0) <= :timeMax )', [ 'timeMin' => $timeMin'timeMax' => $timeMax ]);
  237.         }
  238.         // Filter Altitude
  239.         if( $request->get('altitudeMin'0) || $request->get('altitudeMax'0) ){
  240.             $altitudeMin = (float) $request->get('altitudeMin'0);
  241.             $altitudeMax = (float) $request->get('altitudeMax'$filteringData['altitude']['max']);
  242. //            $tourListing->addConditionParam('( (elevationMaxAltitude - elevationMinAltitude) >= :altitudeMin AND (elevationMaxAltitude - elevationMinAltitude) <= :altitudeMax )', [ 'altitudeMin' => $altitudeMin, 'altitudeMax' => $altitudeMax ]);
  243.             $tourListing->addConditionParam('( IFNULL(elevationAscent, 0) >= :altitudeMin AND IFNULL(elevationAscent, 0) <= :altitudeMax )', [ 'altitudeMin' => $altitudeMin'altitudeMax' => $altitudeMax ]);
  244.         }
  245.         $sorting $this->getDocumentEditable('select''tour_sorting')?->getData();
  246.         if(!empty($sorting)) {
  247.             $tourListing->setOrderKey($sortingfalse);
  248.         }
  249.         // Paginator
  250.         $paginator $paginator->paginate$tourListing$request->get('page'1), 16 );
  251.         $paginator->setPageRange);
  252.         $viewParams['tourListing'] = $paginator;
  253.         $viewParams['filterData'] = $filteringData;
  254.         if ($request->isXmlHttpRequest()) {
  255.             return $this->json([
  256.                 'success' => true,
  257.                 'html' => $this->renderView('Tour/container.html.twig'$viewParams)
  258.             ]);
  259.         }
  260.         return $this->renderTemplate('Tour/overview.html.twig'$viewParams);
  261.     }
  262.     public function detailAction(Request $requestAlpsteinConfig $alpsteinConfigAlpsteinTour $idCanonicalRedirectHelper $redirectHelper)
  263.     {
  264.         $object $id;
  265.         if( !$object || ( !$object->isPublished() && !$this->editmode && !$request->get('pimcore_object_preview') && !$_COOKIE['pimcore_admin_sid'] ) ) {
  266.             throw new NotFoundHttpException("The requested object doesn't exist anymore");
  267.         }
  268.         if (CanonicalRedirectHelper::ENABLE_CANONICAL_REDIRECT && $redirect $redirectHelper->canonicalRedirect($object)) {
  269.             return $redirect;
  270.         }
  271.         if (!empty($object->getManualRecommendation())) {
  272.             $recommendations $object->getManualRecommendation();
  273.         } else {
  274.             $recommendations = [];
  275.             $crawlerDetect = new CrawlerDetect();
  276.             // only show recommendations for non-crawlers, because geoDistanceQuery is performance intensive
  277.             if(!$crawlerDetect->isCrawler()){
  278.                 $recommendations = new AlpsteinTour\Listing();
  279.                 $recommendations->addConditionParam('name != "" AND name IS NOT NULL AND o_id != ' $object->getId());
  280.                 if (!$object->getDisableRadiusLimitation()) {
  281.                     $functionsHelper = new FunctionsHelper();
  282.                     $recommendations->addConditionParam($functionsHelper->getGeoDistanceQuery($object->getStartingPoint(), 'startingPoint') . ' < 10');
  283.                 }
  284.                 $categoryCondition = [];
  285.                 if (!empty($object->getSimilarCategories())) {
  286.                     $categories $object->getSimilarCategories();
  287.                 } else {
  288.                     $categories $object->getCategory();
  289.                 }
  290.                 foreach ($categories ?: [] as $category) {
  291.                     $categoryCondition[] = 'category LIKE "%,' $category->getId() . ',%"';
  292.                 }
  293.                 if (!empty($categoryCondition)) {
  294.                     $recommendations->addConditionParam('(' implode(' OR '$categoryCondition) . ')');
  295.                 }
  296.                 $recommendations->setLimit(7);
  297.                 $recommendations->setOrderKey('RAND()'false);
  298.             } else {
  299.                 // just log, if crawler is detected
  300.                 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);
  301.             }
  302.         }
  303.         return $this->renderTemplate('Tour/detail.html.twig', [
  304.             'tour' => $object,
  305.             'alpsteinConfig' => $alpsteinConfig,
  306.             'recommendations' => $recommendations
  307.         ]);
  308.     }
  309.     public static function getAllSubRegionIds(AlpsteinRegion $region) {
  310.         $ids = [];
  311.         foreach($region->getSubRegions() ?: [] as $subRegion) {
  312.             $ids[] = $subRegion->getId();
  313.             $ids array_merge($idsself::getAllSubRegionIds($subRegion));
  314.         }
  315.         return $ids;
  316.     }
  317.     /**
  318.      * @param Request $request
  319.      * @return RedirectResponse
  320.      * @Route("{_locale}/api/{type}/326442/tour-redirect/{foreignId}", name="pia_map", requirements={"type"="alpstein|contwise"})
  321.      */
  322.     public function mapPiaLink(Request $requestLinkGenerator $linkGenerator) {
  323.         $tour AlpsteinTour::getByAlpsteinId($request->get('foreignId'), 1) ?? AlpsteinTour::getByGeneralSolutionsId($request->get('foreignId'), 1);
  324.         if(!$tour) {
  325.             throw new NotFoundHttpException("invalid tour");
  326.         }
  327.         $url $linkGenerator->generate($tour);
  328.         if(!$url) {
  329.             throw new NotFoundHttpException("Redirect not possible");
  330.         }
  331.         return new RedirectResponse($url);
  332.     }
  333. }