src/Controller/PackageController.php line 31

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\CanonicalRedirectHelper;
  4. use App\Service\FormHelper;
  5. use App\Service\RecaptchaExtension;
  6. use Carbon\Carbon;
  7. use Elements\Bundle\HashCashBundle\Service\HashCashService;
  8. use Knp\Component\Pager\PaginatorInterface;
  9. use Pimcore\Translation\Translator;
  10. use Symfony\Component\HttpFoundation\RedirectResponse;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Pimcore\Model\DataObject;
  13. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use Pimcore\Db;
  16. class PackageController extends AbstractController
  17. {
  18.     private Translator $translator;
  19.     private FormHelper $formHelper;
  20.     public function __construct(Translator $translatorFormHelper $formHelper) {
  21.         $this->translator $translator;
  22.         $this->formHelper $formHelper;
  23.     }
  24.     public function overviewAction(Request $requestPaginatorInterface $paginator)
  25.     {
  26.         $selectedRegion null;
  27.         if ($this->document->getProperty('region') instanceof DataObject\Region && !$this->document->getProperty('region')->getIsMainRegion()) {
  28.             $selectedRegion $this->document->getProperty('region')->getId();
  29.         }
  30.         $selectedRegion $request->get("regions"$selectedRegion);
  31.         $regions = new DataObject\Region\Listing();
  32.         $regionsSelect = [[
  33.             "label" => "",
  34.             "value" => "",
  35.             "disabled" => true,
  36.             "selected" => $selectedRegion false true,
  37.             "class" => "sr-only",
  38.         ]];
  39.         foreach ($regions as $key => $region) {
  40.             $regionsSelect[] = [
  41.                 "label" => $region->getName(),
  42.                 "value" => $region->getId(),
  43.                 "class" => "",
  44.                 "selected" => $selectedRegion && $selectedRegion == $region->getId()
  45.             ];
  46.         }
  47.         $condition = [];
  48.         $optionCategories $baseCategories = [];
  49.         if($this->getDocumentEditable('relations''basecategories') && !empty($this->getDocumentEditable('relations''basecategories')->getData())) {
  50.             foreach($this->getDocumentEditable('relations''basecategories') as $basecategory) {
  51.                 $baseCategories[$basecategory->getId()] =  $basecategory->getId();
  52.             }
  53.             $allBaseCategoryIds $this->getChildObjectIds($baseCategories, ['packageCategory'], true);
  54.         }
  55.         if($this->getDocumentEditable('relations''optioncategories') && !empty($this->getDocumentEditable('relations''optioncategories')->getData())) {
  56.             foreach($this->getDocumentEditable('relations''optioncategories') as $optioncategory) {
  57.                 $optionCategories[$optioncategory->getId()] =  $optioncategory;
  58.             }
  59.         }
  60.         $selectedCategory $request->get("category");
  61.         $packageCategories = new DataObject\PackageCategory\Listing();
  62.         if(!empty($allBaseCategoryIds)) {
  63.             $packageCategories->addConditionParam('o_id IN (:ids)', ['ids' => $allBaseCategoryIds ]);
  64.         }
  65.         $packageCategories->setOrderKey('name');
  66.         $packageCategories->addConditionParam("name != '' ");
  67.         $categoriesSelect = [[
  68.             "label" => "",
  69.             "value" => "",
  70.             "disabled" => true,
  71.             "selected" => $selectedCategory == null,
  72.             "class" => "sr-only",
  73.         ]];
  74.         foreach ($packageCategories as $key => $packageCategory) {
  75.             if(array_key_exists($packageCategory->getId(),  $optionCategories) ){
  76.                 $categoriesSelect[] = [
  77.                     "label" => $packageCategory->getName(),
  78.                     "value" => $packageCategory->getId(),
  79.                     "class" => "",
  80.                     "selected" => $selectedCategory && $selectedCategory == $packageCategory->getId()
  81.                 ];
  82.             }
  83.         }
  84.         $selectedPrice $request->get('price');
  85.         $priceIntervals $this->getDocumentEditable('input''priceintervals') != '' explode(','$this->getDocumentEditable('input''priceintervals')) : [];
  86.         $priceRanges $this->getPriceRanges($priceIntervals);
  87.         $priceSelect = [[
  88.             "label" => "",
  89.             "value" => "",
  90.             "disabled" => true,
  91.             "selected" => $selectedPrice == null,
  92.             "class" => "sr-only",
  93.         ]];
  94.         foreach ($priceRanges as $key => $priceRange) {
  95.             if($priceRange['from'] != '' && $priceRange['to'] != '') {
  96.                 $label $priceRange['from'] . ' - ' $priceRange['to'] . ' €';
  97.             } elseif($priceRange['from'] != '') {
  98.                 $label =  '> ' $priceRange['from'] . ' €';
  99.             } elseif($priceRange['to'] != '') {
  100.                 $label '< ' $priceRange['to'] . ' €';
  101.             }
  102.             $priceSelect[] = [
  103.                 "label" => $label ?? '',
  104.                 "value" => $key,
  105.                 "class" => "",
  106.                 "selected" => $selectedPrice && $selectedPrice == $key
  107.             ];
  108.         }
  109.         $dateFrom $request->get('from');
  110.         if($dateFrom) {
  111.             $dateFrom Carbon::createFromFormat('Y-m-d H:i:s'str_replace('T'' '$request->get('from')) );
  112.         }
  113.         $dateTo $request->get('to');
  114.         if($dateTo) {
  115.             $dateTo Carbon::createFromFormat('Y-m-d H:i:s'str_replace('T'' '$request->get('to')) );
  116.         }
  117.         $offers = new DataObject\Package\Listing();
  118.         //alle 82, busreisen: 4, ys 1
  119.         $packageTypes $this->getDocumentEditable('multiselect''packageTypes')->getData();
  120.         $packageSubQueries = [];
  121.         foreach ($packageTypes as $packageType) {
  122.             if($packageType === 'styriaPackages') {
  123.                 $packageSubQueries[] = '(isBusTour is null OR isBusTour = 0) AND (isYoungStyria is null OR isYoungStyria = 0)';
  124.             } elseif($packageType === 'busTour') {
  125.                 $packageSubQueries[] = 'isBusTour is not null AND isBusTour = 1';
  126.             } elseif($packageType === 'isYoungStyria') {
  127.                 $packageSubQueries[] = 'isYoungStyria is not null AND isYoungStyria = 1';
  128.             }
  129.         }
  130.         if(!empty($packageSubQueries)) {
  131.             $offers->addConditionParam(implode(' OR '$packageSubQueries));
  132.         }
  133.         if($selectedRegion && ($region DataObject\Region::getById($selectedRegion))) {
  134.             $regionsAndCommunitiesIds $this->getChildRegionAndCommunityIds($regiontrue);
  135.             $subRegionCondition = [];
  136.             foreach ($regionsAndCommunitiesIds as $id) {
  137.                 $subRegionCondition[] = "regions LIKE '%,object|" $id ",%'";
  138.             }
  139.             if(!empty($subRegionCondition)) {
  140.                 $offers->addConditionParam('('.  implode(' OR '$subRegionCondition) . ')');
  141.             }
  142.         }
  143.         if($selectedCategory) {
  144.             $offers->addConditionParam("categories LIKE :cat", ['cat' => '%,' $selectedCategory ',%']);
  145.         } elseif(!empty($allBaseCategoryIds)) {
  146.             $subconditions = [];
  147.             foreach($allBaseCategoryIds as $baseCategoryId) {
  148.                 $subconditions[] = 'categories LIKE "%,' $baseCategoryId ',%"';
  149.             }
  150.             if(!empty($subconditions)) {
  151.                 $offers->addConditionParam('(' implode(' OR '$subconditions) . ')');
  152.             }
  153.         }
  154.         $offerBeginDate = [];
  155.         $offerCount 0;
  156.         if($this->getDocumentEditable('checkbox''datefilter')->isChecked() && $dateFrom && $dateFrom instanceof Carbon) {
  157.             #also considering the min. nights the guest has to stay
  158.             $offerBeginDate[] = '(beginDate <= ' $dateFrom->getTimestamp() . ' OR beginDate >= ' $dateFrom->getTimestamp() . ')';
  159.             $offerBeginDate[] = 'endDate >= ' $dateFrom->getTimestamp();
  160.         }
  161.         if($this->getDocumentEditable('checkbox''datefilter')->isChecked() && $dateTo && $dateTo instanceof Carbon) {
  162.             #also considering the min. nights the guest has to stay
  163.             $offerBeginDate[] = 'beginDate <= ' $dateTo->getTimestamp();
  164.         } else { // if no timerange is used => show only packages that are not in the past
  165.             $offerBeginDate[] = 'endDate >= ' Carbon::now()->getTimestamp();
  166.         }
  167.         if(!empty($offerBeginDate)){
  168.             $packagePeriod Db::get()->createQueryBuilder();
  169.             $packagePeriod->select('o_id')->from('object_collection_PackagePeriod_78')->where(implode(' AND '$offerBeginDate));
  170.             $ids $packagePeriod->execute()->fetchAll();
  171.             $ids array_map(function($a){return $a['o_id'];}, $ids);
  172.             $offerCount count($ids);
  173.             if($offerCount 0) {
  174.                 $offers->addConditionParam('o_id IN (' implode(','$ids) . ')');
  175.             }
  176.         }
  177.         if($selectedPrice) {
  178.             if($priceRanges[$selectedPrice]['from'] != '' && $priceRanges[$selectedPrice]['to'] != '') {
  179.                 $offers->addConditionParam("price != '' and price >= :priceFrom and price <= :priceTo", ['priceFrom' => $priceRanges[$selectedPrice]['from'], 'priceTo' => $priceRanges[$selectedPrice]['to']]);
  180.             } elseif($priceRanges[$selectedPrice]['from'] != '' ) {
  181.                 $offers->addConditionParam("price != '' and price > :priceFrom", ['priceFrom' => $priceRanges[$selectedPrice]['from']]);
  182.             } elseif($priceRanges[$selectedPrice]['to'] != '') {
  183.                 $offers->addConditionParam("price != '' and price < :priceTo", ['priceTo' => $priceRanges[$selectedPrice]['to']]);
  184.             }
  185.         }
  186.         // p_r($offers->getCondition()); die();
  187.         $limit = (int) $this->getDocumentEditable('numeric''numTeasers')->getData();
  188.         if ($limit <= 0) {
  189.             $limit 8;
  190.         }
  191.         if($this->getDocumentEditable('checkbox''randomize-package')->isChecked()) {
  192.             $offers->setOrderKey("Rand(" Carbon::today()->unix() . ")"false);
  193.         }
  194.         if($offerCount == 0){
  195.             $offers =  [];
  196.         }
  197.         $paginator $paginator->paginate($offers, (int)$request->get('page',1), $limit);
  198.         $paginator->setPageRange(3);
  199.         if ($request->isXmlHttpRequest()) {
  200.             return $this->json([
  201.                 'success' => true,
  202.                 'html' => $this->renderView('Package/Includes/top-offers-list.html.twig', ['paginator' => $paginator])
  203.             ]);
  204.         }
  205.         return $this->renderTemplate('Package/overview.html.twig', [
  206.             'regionsSelect'  => $regionsSelect,
  207.             'packageCategories' => $categoriesSelect,
  208.             'paginator' => $paginator,
  209.             'top-offers' => $offers,
  210.             'priceSelect' => $priceSelect,
  211.             'dateTo' => $dateTo,
  212.             'dateFrom' => $dateFrom,
  213.         ]);
  214.     }
  215.     public function detailAction(Request $requestHashCashService $hashCashServiceCanonicalRedirectHelper $redirectHelper)
  216.     {
  217.         if($request->isMethod('post')) {
  218.             $res $this->inquiry($request$hashCashService);
  219.             if($res instanceof RedirectResponse) {
  220.                 return $res;
  221.             }
  222.         }
  223.         $package DataObject\Package::getById($request->get('id'0));
  224.         if (!$package){
  225.             throw new NotFoundHttpException("the requested object doesn't exist anymore");
  226.         }
  227.         if (CanonicalRedirectHelper::ENABLE_CANONICAL_REDIRECT && $redirect $redirectHelper->canonicalRedirect($package)) {
  228.             return $redirect;
  229.         }
  230.         $topicSelect = [[
  231.             "label" => "",
  232.             "value" => "",
  233.             "disabled" => true,
  234.             "selected" => true,
  235.             "class" => "sr-only",
  236.         ]];
  237.         foreach ($package->getCategories() as $cat) {
  238.             $topicSelect[] = [
  239.                 "label" => $cat->getName(),
  240.                 "value" => $cat->getId(),
  241.                 "class" => ""
  242.             ];
  243.         }
  244.         $regionSelect = [[
  245.             "label" => "",
  246.             "value" => "",
  247.             "disabled" => true,
  248.             "selected" => true,
  249.             "class" => "sr-only",
  250.         ]];
  251.         foreach ($package->getRegions() as $reg) {
  252.             $regionSelect[] = [
  253.                 "label" => $reg->getName(),
  254.                 "value" => $reg->getId(),
  255.                 "class" => ""
  256.             ];
  257.         }
  258.         $adultsSelect = [[
  259.             "label" => "",
  260.             "value" => "",
  261.             "disabled" => true,
  262.             "selected" => true,
  263.             "class" => "sr-only",
  264.         ]];
  265.         $childrenSelect = [[
  266.             "label" => "",
  267.             "value" => "",
  268.             "disabled" => true,
  269.             "selected" => true,
  270.             "class" => "sr-only",
  271.         ]];
  272.         for($i 0$i <= 10$i++) {
  273.             $val = [
  274.                 "label" => $i,
  275.                 "value" => $i,
  276.                 "class" => ""
  277.             ];
  278.             if ($i 0$adultsSelect[] = $val;
  279.             $childrenSelect[] = $val;
  280.         }
  281.         return $this->renderTemplate('Package/detail.html.twig', [
  282.             'package' => $package,
  283.             'packageDates' => $this->getPackageDatesTK($package$request->getLocale()),
  284.             'topicSelect' => $topicSelect,
  285.             'regionSelect' => $regionSelect,
  286.             'adultsSelect' => $adultsSelect,
  287.             'childrenSelect' => $childrenSelect,
  288.             'errors' => $res ?? []
  289.         ]);
  290.     }
  291.     /**
  292.      * @Route("/contact-modal", name="contact-modal")
  293.      * @param Request $request
  294.      */
  295.     private function inquiry(Request $requestHashCashService $hashCashService) {
  296.         $params = [];
  297. //        p_r($hashCashService->validateProcessFrom()); die();
  298.         if ($hashCashService->validateProcessFrom()) {
  299.             $requiredParams = [
  300.                 'packageId',
  301.                 'packageName',
  302.                 'salutation',
  303.                 'firstname',
  304.                 'lastname',
  305.                 'email',
  306.                 'arrival',
  307.                 'departure',
  308.             ];
  309.             $package DataObject\Package::getById($request->get('packageId'));
  310.             $optionalParams = [
  311.                 'phone',
  312.                 'title',
  313.             ];
  314.             if($package->getIsBusTour()) {
  315.                 $requiredParams[] = 'persons';
  316.                 $optionalParams[] = 'doublerooms';
  317.                 $optionalParams[] = 'singlerooms';
  318.             } else {
  319.                 $requiredParams[] = 'adults';
  320.                 $optionalParams[] = 'children';
  321.             }
  322.             $errors = [];
  323.             if(!$package) {
  324.                 $errors[] = 'no valid package';
  325.             }
  326.             if($package->getEnableCategoriesInForm()) {
  327.                 $requiredParams[] = 'topic';
  328.             }
  329.             if($package->getEnableRegionsInForm()) {
  330.                 $requiredParams[] = 'region';
  331.             }
  332.             foreach ($requiredParams as $param) {
  333.                 if (!$request->get($paramnull)) {
  334.                     $errors[] = $param;
  335.                     continue;
  336.                 }
  337.                 $params[$param] = $request->get($param);
  338.             }
  339.             if(isset($params['salutation'])) {
  340.                 $params['salutation'] = $this->translator->trans($params['salutation']);
  341.             }
  342.             foreach ($optionalParams as $param) {
  343.                 if ($val $request->get($param)) {
  344.                     $params[$param] = $val;
  345.                 }
  346.             }
  347.             if(array_key_exists('children'$params) && $params['children'] > 0) {
  348.                 $params['childAge'] = $this->formHelper->getTranslatedChildAges($request->get('ca0', []));
  349.             }
  350.             $config $this->document->getProperty('siteConfig');
  351.             if (!$config instanceof DataObject\SiteConfig) {
  352.                 $errors[] = 'config';
  353.             }
  354.         } else {
  355.             $errors[] = 'hashcash not valid';
  356.         }
  357.         if(empty($errors)) {
  358.             $arrivalDate Carbon::createFromFormat('Y-m-d H:i:s'str_replace('T'' '$params['arrival']));
  359.             $params['arrival'] = $arrivalDate $arrivalDate->format('d.m.Y') : null;
  360.             $departureDate Carbon::createFromFormat('Y-m-d H:i:s'str_replace('T'' '$params['departure']));
  361.             $params['departure'] = $departureDate $departureDate->format('d.m.Y') : null;
  362.             $mailDoc $config->getTopOffersMail();
  363.             $mailDocUser $config->getTopOffersMailUser();
  364.             $successPage $config->getTopOffersMailSuccessPage();
  365.             if($package->getIsBusTour()) {
  366.                 if($config->getTopOffersMailBusTravel()) {
  367.                     $mailDoc =$config->getTopOffersMailBusTravel();
  368.                 }
  369.                 if($config->getTopOffersMailUserBusTravel()) {
  370.                     $mailDocUser $config->getTopOffersMailUserBusTravel();
  371.                 }
  372.                 if($config->getTopOffersMailSuccessPageBusTravel()) {
  373.                     $successPage $config->getTopOffersMailSuccessPageBusTravel();
  374.                 }
  375.             } elseif($package->getIsYoungStyria()) {
  376.                 if($config->getTopOffersMailYoungStyria()) {
  377.                     $mailDoc $config->getTopOffersMailYoungStyria();
  378.                 }
  379.                 if($config->getTopOffersMailUserYoungStyria()) {
  380.                     $mailDocUser $config->getTopOffersMailUserYoungStyria();
  381.                 }
  382.                 if($config->getTopOffersMailSuccessPageYoungStyria()) {
  383.                     $successPage $config->getTopOffersMailSuccessPageYoungStyria();
  384.                 }
  385.             }
  386.             if($mailDoc) {
  387.                 $notification = new \Pimcore\Mail();
  388.                 //default take from backend settings
  389.                 if(!\Pimcore::inDebugMode() && $package DataObject\Package::getById($request->get('packageId'0))) {
  390.                     if(($poi $package->getPoi()) && ($mail $package->getPoi()->getEmail())) {
  391.                         $notification->addTo($mail);
  392.                     }else{
  393.                         if($mail $package->getEmail()){
  394.                             $notification->addTo($mail);
  395.                         }
  396.                     }
  397.                 }
  398.                 if ($package->getIsBusTour()){
  399.                     $params['items'] = ['packageId''packageName''salutation''firstname''lastname''email''arrival''departure''persons''doublerooms''singlerooms''message'];
  400.                 } else {
  401.                     $params['items'] = ['packageId''packageName''salutation''firstname''lastname''email''arrival''departure''adults''childAge''message'];
  402.                 }
  403.                 $notification->setDocument($mailDoc);
  404.                 $notification->setParams($params);
  405.                 $notification->send();
  406.             } else {
  407.                 $errors[] = 'mail admin';
  408.             }
  409.             if($mailDocUser) {
  410.                 $notification = new \Pimcore\Mail();
  411.                 if($package->getIsBusTour()){
  412.                     $params['items'] = ['packageName''salutation''firstname''lastname''email''arrival''departure''persons''doublerooms''singlerooms''message'];
  413.                 } else {
  414.                     $params['items'] = ['packageName''salutation''firstname''lastname''email''arrival''departure''adults''childAge''message'];
  415.                 }
  416.                 $notification->setDocument($mailDocUser);
  417.                 $notification->addTo($params['email']);
  418.                 $notification->setParams($params);
  419.                 $notification->send();
  420.                 if($successPage $config->getTopOffersMailSuccessPage()) {
  421.                     return $this->redirect($successPage->getFullPath());
  422.                 }
  423.             } else {
  424.                 $errors[] = 'mail user';
  425.             }
  426.             if(empty($errors) && $successPage) {
  427.                 return $this->redirect($successPage->getFullPath());
  428.             }
  429.         }
  430.         return $errors;
  431.     }
  432.     protected function getChildObjectIds($parentIds = [], $filterClasses = [], $includeParents false) {
  433.         $return = [];
  434.         if(!empty($parentIds)) {
  435.             if($includeParents) {
  436.                 $return $parentIds;
  437.             }
  438.             $paths = [];
  439.             foreach($parentIds as $parentId) {
  440.                 $_obj \Pimcore\Model\DataObject::getById($parentId);
  441.                 if ($_obj instanceof \Pimcore\Model\DataObject) {
  442.                     $paths[] = $_obj->getFullPath();
  443.                 }
  444.             }
  445.             if(!empty($paths)) {
  446.                 $condition = [];
  447.                 $subcondition = [];
  448.                 foreach($paths as $path) {
  449.                     $subcondition[] = 'o_path LIKE "'.$path.'/%"';
  450.                 }
  451.                 if(!empty($subcondition)) {
  452.                     $condition[] = '(' implode(' OR '$subcondition) . ')';
  453.                 }
  454.                 if(!empty($filterClasses)) {
  455.                     $subcondition = [];
  456.                     foreach($filterClasses as $filterClass) {
  457.                         $subcondition[] = 'o_className = "'.lcfirst($filterClass).'"';
  458.                     }
  459.                     $condition[] = '('.implode(' OR '$subcondition).')';
  460.                 }
  461.                 if(!empty($condition)) {
  462.                     $list = new \Pimcore\Model\DataObject\Listing();
  463.                     $list->setCondition(implode(' AND ' $condition));
  464.                 }
  465.                 foreach($list as $object) {
  466.                     $return[] = $object->getId();
  467.                 }
  468.             }
  469.         }
  470.         return array_unique($return);
  471.     }
  472.     private function getPriceRanges(array $priceIntervals = []) {
  473.         $normalizedIntervals = [];
  474.         foreach ($priceIntervals as $entry) {
  475.             $e trim($entry);
  476.             if (is_numeric($e) && (int)$e != 0) {
  477.                 $normalizedIntervals[] = (int)$e;
  478.             }
  479.         }
  480.         sort($normalizedIntervals);
  481.         $priceRanges = [];
  482.         $last count($normalizedIntervals ?? []) - 1;
  483.         $preventry 0;
  484.         foreach ($normalizedIntervals as $count => $entry) {
  485.             if ($count == 0) {
  486.                 $priceRanges[$count 1] = ['to' => $entry'from' => ''];
  487.             } else {
  488.                 $priceRanges[$count 1] = ['from' => $preventry'to' => $entry];
  489.             }
  490.             $preventry $entry;
  491.         }
  492.         if ($preventry) {
  493.             $priceRanges[$count 2] = ['from' => $preventry'to' => ''];
  494.         }
  495.         return $priceRanges;
  496.     }
  497.     protected function getChildRegionAndCommunityIds(\Pimcore\Model\DataObject\Region $region$includeParent false) {
  498.         $lifetime 60*30;   #30 minutes
  499.         $cacheKey md5('region-'.$region->getId().($includeParent '-parent' '-children'));
  500.         if(!$ids \Pimcore\Cache::load($cacheKey)) {
  501.             try {
  502.                 $ids $includeParent ? [$region->getId()] : [];
  503.                 $regionList = new \Pimcore\Model\DataObject\Region\Listing();
  504.                 $regionList->setCondition('o_path LIKE "'.$region->getFullPath().'/%"');
  505.                 foreach($regionList as $_region) {
  506.                     $ids[] = $_region->getId();
  507.                 }
  508.                 $communityList = new \Pimcore\Model\DataObject\Community\Listing();
  509.                 $communityList->setCondition('o_path LIKE "'.$region->getFullPath().'/%"');
  510.                 foreach($communityList as $_community) {
  511.                     $ids[] = $_community->getId();
  512.                 }
  513.                 \Pimcore\Cache::save(array_unique($ids), $cacheKey, array("output"), $lifetime);
  514.             } catch (\Exception $e) {
  515.             }
  516.         }
  517.         return $ids;
  518.     }
  519.     private function getPackageDatesTK(DataObject\Package $packageString $lang) : string {
  520.         $packageDates = [];
  521.         $first true;
  522.         foreach($package->getPeriods() ?: [] as $period) {
  523.             if(Carbon::now()->lte($period->getEndDate()) ) {
  524.                 $date $period->getBeginDate()->format('d.m.Y') . ' - ' $period->getEndDate()->format('d.m.Y');
  525.                 if($first) {
  526.                     $first false;
  527.                     $date $this->translator->trans('package-detail.Gültig von: ', [], null$lang) . ' '$date;
  528.                 }
  529.                 $packageDates[] =  $date ;
  530.             }
  531.         }
  532.         return !empty($packageDates) ? "<div>" implode(",</div><div>"$packageDates) . "</div>" "";
  533.     }
  534. }