src/Twig/LayoutExtension.php line 793

Open in your IDE?
  1. <?php
  2. namespace App\Twig;
  3. use App\Model\DataObject\WeatherStation;
  4. use App\Service\CanonicalRedirectHelper;
  5. use App\Service\NewsletterService;
  6. use Carbon\Carbon;
  7. use Pimcore\Cache;
  8. use Pimcore\Config;
  9. use Pimcore\Google\Cse\Item;
  10. use Pimcore\Image;
  11. use Pimcore\Model\Asset;
  12. use Pimcore\Model\DataObject;
  13. use Pimcore\Model\DataObject\BlogTheme;
  14. use Pimcore\Model\DataObject\Community;
  15. use Pimcore\Model\DataObject\DemiInfrastructure;
  16. use Pimcore\Model\DataObject\Fieldcollection\Data\WeatherTextStationDataSet;
  17. use Pimcore\Model\DataObject\MediaUser;
  18. use Pimcore\Model\DataObject\Region;
  19. use Pimcore\Model\DataObject\WeatherAvalancheStation;
  20. use Pimcore\Model\DataObject\WeatherLiveStation;
  21. use Pimcore\Model\DataObject\WeatherTextStation;
  22. use Pimcore\Model\DataObject\Webcam;
  23. use Pimcore\Model\Document;
  24. use Pimcore\Model\Site;
  25. use Pimcore\Tool;
  26. use Pimcore\Translation\Translator;
  27. use Symfony\Component\HttpFoundation\Request;
  28. use Symfony\Component\HttpFoundation\RequestStack;
  29. use Symfony\Component\Intl\Countries;
  30. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  31. use Twig\Extension\AbstractExtension;
  32. use Twig\TwigFunction;
  33. class LayoutExtension extends AbstractExtension
  34. {
  35.     /**
  36.      * @var Config
  37.      */
  38.     private $systemConfig;
  39.     /**
  40.      * @var Translator
  41.      */
  42.     private $translator;
  43.     /**
  44.      * @var LinkGenerator
  45.      */
  46.     private $linkGenerator;
  47.     /**
  48.      * @var RequestStack
  49.      */
  50.     private $requestStack;
  51.     /**
  52.      * @var ObjectExtension
  53.      */
  54.     private $objectExtension;
  55.     private UrlGeneratorInterface $router;
  56.     public const ROOT_DOCUMENT_ID 1;
  57.     /**
  58.      * LayoutExtension constructor.
  59.      * @param Config $systemConfig
  60.      * @param Translator $translator
  61.      * @param LinkGenerator $linkGenerator
  62.      */
  63.     public function __construct(Config $systemConfigTranslator $translatorLinkGenerator $linkGeneratorRequestStack $requestStackObjectExtension $objectExtensionUrlGeneratorInterface $router)
  64.     {
  65.         $this->systemConfig $systemConfig;
  66.         $this->translator $translator;
  67.         $this->linkGenerator $linkGenerator;
  68.         $this->requestStack $requestStack;
  69.         $this->objectExtension $objectExtension;
  70.         $this->router $router;
  71.     }
  72.     /**
  73.      * @return string
  74.      */
  75.     public function getName()
  76.     {
  77.         return "Layout Extension";
  78.     }
  79.     /**
  80.      * @return array|TwigFunction[]
  81.      */
  82.     public function getFunctions()
  83.     {
  84.         return [
  85.             new TwigFunction('getEnv', [$this'getEnv']),
  86.             new TwigFunction('googleApiKey', [$this'googleApiKey']),
  87.             new TwigFunction('selectableIcons', [$this'getSelectableIcons']),
  88.             new TwigFunction('isValidAsset', [$this'isValidAsset']),
  89.             new TwigFunction('getImageDescription', [$this'getImageDescription']),
  90.             new TwigFunction('getImageTexts', [$this'getImageTexts']),
  91.             new TwigFunction('getWeatherIcon', [$this'getWeatherIcon']),
  92.             new TwigFunction('getSocialIcons', [$this'getSocialIcons']),
  93.             new TwigFunction('getRegionsArray', [$this'getRegionsArray']),
  94.             new TwigFunction('getIndexFromRegion', [$this'getIndexFromRegion']),
  95.             new TwigFunction('getWeatherPrognosis', [$this'getWeatherPrognosis']),
  96.             new TwigFunction('getThemeByCategoryId', [$this'getThemeByCategoryId']),
  97.             new TwigFunction('getUseRelativeLink', [$this'getUseRelativeLink']),
  98.             new TwigFunction('hostUrl', [$this'getHostUrl']),
  99.             new TwigFunction('getHotspotData', [$this'getHotspotData']),
  100.             new TwigFunction('getCountrySelectData', [$this'getCountrySelectData']),
  101.             new TwigFunction('getPathInfo', [$this'getPathInfo']),
  102.             new TwigFunction('getVideoEditable', [$this'getVideoEditable']),
  103.             new TwigFunction('getNewsletterPools', [$this'getNewsletterPools']),
  104.             new TwigFunction('getMediaUser', [$this'getMediaUser']),
  105.             new TwigFunction('getPressWishlistCount', [$this'getPressWishlistCount']),
  106.             new TwigFunction('getMasterRequest', [$this'getMasterRequest']),
  107.             new TwigFunction('getMainRequest', [$this'getMainRequest']),
  108.             new TwigFunction('randomizeRelationEvery24h', [$this'randomizeRelationEvery24h']),
  109.             new TwigFunction('randomizeBlock', [$this'randomizeBlock']),
  110.             new TwigFunction('getImageType', [$this'getImageType']),
  111.             new TwigFunction('getBadgesForAsset', [$this'getBadgesForAsset']),
  112.             new TwigFunction('getFormattedVideoDuration', [$this'getFormattedVideoDuration']),
  113.             new TwigFunction('getYoutubeIdFromHref', [$this'getYoutubeIdFromHref']),
  114.             new TwigFunction('getAccessiblityObjects', [$this'getAccessiblityObjects']),
  115.             new TwigFunction('getSubttitleOfAudio', [$this'getSubttitleOfAudio']),
  116.             new TwigFunction('checkIfNoRenderletIsValid', [$this'checkIfNoRenderletIsValid']),
  117.             new TwigFunction('getAuthorForQuote', [$this'getAuthorForQuote']),
  118.             new TwigFunction('getCurrentWeatherImage', [$this'getCurrentWeatherImage']),
  119.             new TwigFunction('getDownloadItemDataByAsset', [$this'getDownloadItemDataByAsset']),
  120.             new TwigFunction('getPackagesByPackageCategories', [$this'getPackagesByPackageCategories']),
  121.             new TwigFunction('hasGetParams', [$this'hasGetParams']),
  122.             new TwigFunction('removeUnpublishedElements', [$this'removeUnpublishedElements']),
  123.             new TwigFunction('chooseDescription', [$this'chooseDescription']),
  124.             new TwigFunction('getMainLogo', [$this'getMainLogo']),
  125.             new TwigFunction('getMainConfig', [$this'getMainConfig']),
  126.             new TwigFunction('getFileContent', [$this'getFileContent']),
  127.             new TwigFunction('getSVGPathForExperienceTeaserBackgroundText', [$this'getSVGPathForExperienceTeaserBackgroundText']),
  128.             new TwigFunction('getObjectImageFromCSEResult', [$this'getObjectImageFromCSEResult']),
  129.             new TwigFunction('getTimeOfDay', [$this'getTimeOfDay']),
  130.             new TwigFunction('getCache', [$this'getCache']),
  131.             new TwigFunction('saveInCache', [$this'saveInCache']),
  132.             new TwigFunction('cachingAllowed', [$this'cachingAllowed']),
  133.             new TwigFunction('getAssetOrientation', [$this'getAssetOrientation']),
  134.         ];
  135.     }
  136.     /**
  137.      * @param array $params
  138.      * @return bool
  139.      */
  140.     public function hasGetParams($params = []) {
  141.         if (empty($params)) {
  142.             return !empty($_GET);
  143.         }
  144.         foreach ($params as $param) {
  145.             if (array_key_exists($param$_GET))  {
  146.                 return true;
  147.             }
  148.         }
  149.         return false;
  150.     }
  151.     public function getEnv(string $envName) {
  152.         return $_ENV[$envName];
  153.     }
  154.     /**
  155.      * @return bool
  156.      */
  157.     public function getUseRelativeLink() {
  158.         return CanonicalRedirectHelper::USE_RELATIVE_LINK;
  159.     }
  160.     /**
  161.      * @param DataObject\DemiAccommodationServiceProvider|DemiInfrastructure $object
  162.      */
  163.     public function getAccessiblityObjects(DataObject $object) {
  164.         $accessibilityCategories = [];
  165.         if ($object->getDemiExtension() && $object->getDemiExtension()->getDemiAccessibilityCategories()) {
  166.             foreach($object->getDemiExtension()->getDemiAccessibilityCategories()->getAccessibilityCategories() ?: [] as $entry) {
  167.                 $category $entry->getObject();
  168.                 $percent $entry->getPercent();
  169.                 if($percent >= 80) {
  170.                     $accessibilityCategories[$category->getId()] = ['category' => $category'percent' => $percent'isTop' => $percent >= 85];
  171.                 }
  172.             }
  173.         }
  174.         return $accessibilityCategories;
  175.     }
  176.     /**
  177.      * @return Request|null
  178.      */
  179.     public function getMasterRequest() {
  180.         return $this->requestStack->getMainRequest();
  181.     }
  182.     /**
  183.      * @return Request|null
  184.      */
  185.     public function getMainRequest() {
  186.         return $this->requestStack->getMainRequest();
  187.     }
  188.     /**
  189.      * @return string[]
  190.      */
  191.     public function getNewsletterPools() {
  192.         return NewsletterService::ALLOWED_NEWSLETTER_LISTS;
  193.     }
  194.     /**
  195.      * @return mixed
  196.      */
  197.     public function googleApiKey() {
  198.         return $this->systemConfig['services']['google']['browser_api_key'];
  199.     }
  200.     /**
  201.      * @return string[][]
  202.      */
  203.     public function getSelectableIcons() {
  204.         return [
  205.             ['''No Icon'],
  206.             ['hiking''<span class="icon icon-hiking" style="font-size: 20px"></span> Hiking'],
  207.             ['baggage''<span class="icon icon-baggage" style="font-size: 20px"></span> Baggage'],
  208.             ['calendar''<span class="icon icon-calendar" style="font-size: 20px"></span> Calendar'],
  209.             ['eye''<span class="icon icon-eye" style="font-size: 20px"></span> Eye'],
  210.             ['heart-outline''<span class="icon icon-heart-outline" style="font-size: 20px"></span> Heart outline'],
  211.             ['heart''<span class="icon icon-heart" style="font-size: 20px"></span> Heart'],
  212.             ['infrastructure''<span class="icon icon-infrastructure" style="font-size: 20px"></span> Infrastructure'],
  213.             ['mountain''<span class="icon icon-mountain" style="font-size: 20px"></span> Mountain'],
  214.             ['regions''<span class="icon icon-regions" style="font-size: 20px"></span> Regions'],
  215.             ['pin''<span class="icon icon-pin" style="font-size: 20px"></span> Pin'],
  216.             ['search''<span class="icon icon-search" style="font-size: 20px"></span> Search'],
  217.             ['sightseeing''<span class="icon icon-sightseeing" style="font-size: 20px"></span> Sightseeing'],
  218.             ['tag''<span class="icon icon-tag" style="font-size: 20px"></span> Tag'],
  219.             ['traffic''<span class="icon icon-traffic" style="font-size: 20px"></span> Traffic'],
  220.             ['corona''<span class="icon icon-corona" style="font-size: 20px"></span> Corona'],
  221.         ];
  222.     }
  223.     /**
  224.      * @param Asset $asset
  225.      * @return bool
  226.      */
  227.     public function isValidAsset(Asset $asset) {
  228.         // check if contains neccessary data based on CC License
  229.         return true;
  230.     }
  231.     /**
  232.      * @param Asset\Image|null $image
  233.      * @return array|false
  234.      * @throws \Exception
  235.      */
  236.     public function getImageTexts(Asset $image null$noCopyrightIfInMetadata falsebool $onlyCopyright false) {
  237.         if (!$image instanceof Asset\Image) {
  238.             return false;
  239.         }
  240.         $arrayKey $image->getId() . ($noCopyrightIfInMetadata '_noCopyright' '');
  241.         $cacheKey $arrayKey '_' $this->requestStack->getCurrentRequest()?->getLocale();
  242.         if (!array_key_exists($arrayKey$this->imageMetadata)) {
  243.             $texts Cache::load($cacheKey);
  244.             if(!$texts) {
  245.                 $metadataCopyright $image->getMetadata('copyright');
  246.                 $copyright null;
  247.                 $metaData $image->getEmbeddedMetaData(true);
  248.                 if (!$noCopyrightIfInMetadata || $metadataCopyright == '') {
  249.                     $copyrightObject $image->getMetadata('General.copyright');
  250.                     if ($copyrightObject instanceof DataObject\MediaCopyright && !($noCopyrightIfInMetadata && $metadataCopyright != '')) {
  251.                         $copyright $copyrightObject->getText();
  252.                     }
  253.                     if ($copyright == '') {
  254.                         $copyright $metadataCopyright;
  255.                         if ($copyright == '') {
  256.                             if (isset($metaData['Copyright']) && $metaData['Copyright']) {
  257.                                 $copyright $metaData['Copyright'];
  258.                             } elseif (isset($metaData['CopyrightNotice']) && $metaData['CopyrightNotice']) {
  259.                                 $copyright $metaData['CopyrightNotice'];
  260.                             } elseif (isset($metaData['Rights'])) {
  261.                                 $copyright $metaData['Rights'];
  262.                             }
  263. //                    $copyright = $metaData['Copyright'] ?: ($metaData['CopyrightNotice'] ?: $metaData['Rights']);
  264.                         }
  265.                     }
  266.                     if ($copyright != '' && strpos($copyright'©') === false) {
  267.                         $copyright '© ' $copyright;
  268.                     }
  269.                 }
  270.                 $title $image->getMetadata('General.title');
  271.                 if ($title == '') {
  272.                     $title $image->getMetadata('title');
  273.                     if ($title == '') {
  274.                         if (isset($metaData['Title']) && $metaData['Title']) {
  275.                             $title $metaData['Title'];
  276.                         } elseif (isset($metaData['ObjectName'])) {
  277.                             $title $metaData['ObjectName'];
  278.                         }
  279. //                    $title = $metaData['Title'] ?: $metaData['ObjectName'];
  280.                     }
  281.                 }
  282.                 $author $image->getMetadata('General.author');
  283.                 if ($author instanceof DataObject\Contact) {
  284.                     $author $author->getName() ?: (trim($author->getFirstname() . ' ' $author->getLastname()));
  285.                 }
  286.                 if ($author == '') {
  287.                     $author $image->getMetadata('author');
  288.                     if ($author == '') {
  289.                         if (isset($metaData['Artist']) && $metaData['Artist']) {
  290.                             $author $metaData['Artist'];
  291.                         } elseif (isset($metaData['Creator']) && $metaData['Creator']) {
  292.                             $author $metaData['Creator'];
  293.                         } elseif (isset($metaData['By-line'])) {
  294.                             $author $metaData['By-line'];
  295.                         }
  296. //                    $author = $metaData['Artist'] ?: ($metaData['Creator'] ?: $metaData['By-line']);
  297.                     }
  298.                 }
  299.                 $texts = [];
  300.                 if ($title != '' && !$onlyCopyright) {
  301.                     $texts['title'] = $title;
  302.                 }
  303.                 if ($copyright != '') {
  304.                     $texts['copyright'] = $copyright;
  305.                 }
  306.                 if ($author != '' && !$onlyCopyright) {
  307.                     $texts['author'] = $author;
  308.                 }
  309.                 $usage $image->getMetadata('General.usage');
  310.                 if ($usage && !$onlyCopyright) {
  311.                     $texts['usage'] = $usage;
  312.                 }
  313.                 // save cache for 4 hours
  314.                 Cache::save($texts$cacheKey, [$image->getCacheTag()], 14400);
  315.             }
  316.             $this->imageMetadata[$arrayKey] = $texts;
  317.         }
  318.         return $this->imageMetadata[$arrayKey];
  319.     }
  320.     protected $imageMetadata = [];
  321.     /**
  322.      * @param Asset\Image|DataObject\Data\Hotspotimage|null $image
  323.      * @return false|string
  324.      * @throws \Exception
  325.      */
  326.     public function getImageDescription($image null$noCopyrightIfInMetadata falsebool $onlyCopyright false) {
  327.         if ($image == null) {
  328.             return false;
  329.         }
  330.         if ($image instanceof DataObject\Data\Hotspotimage) {
  331.             $image $image->getImage();
  332.         }
  333.         if($image instanceof Document\Editable\Image) {
  334.             $image $image->getImage();
  335.         }
  336.         if ($image instanceof Asset\Image) {
  337.             $texts $this->getImageTexts($image$noCopyrightIfInMetadata$onlyCopyright);
  338.         }
  339.         if (!empty($texts)) {
  340.             return implode(' | '$texts );
  341.         }
  342.         return false;
  343.     }
  344.     public const WEATHER_ICON_MAPPING = [
  345.         '01'    => '01',
  346.         '02'    => '02',
  347.         '03'    => '03',     #wetter_wolkig.svg
  348.         '04'    => '03',
  349.         '05'    => '07',
  350.         '06'    => '12',
  351.         '07'    => '12',
  352.         '08'    => '08',
  353.         '09'    => '06',
  354.         '10'    => '05',
  355.         '11'    => '11',
  356.         '12'    => '11',
  357.         '13'    => '11',
  358.         '14'    => '09',
  359.         '15'    => '10',
  360.         '16'    => '10',
  361.         '17'    => '04',
  362.         '18'    => '04',
  363.         '19'    => '04',
  364.         '20'    => '08',
  365.         '21'    => '08',
  366.         '22'    => '08',
  367.         '23'    => '08',
  368.         '24'    => '08',
  369.         '25'    => '08',
  370.         '26'    => '13',
  371.         '27'    => '13',
  372.         '28'    => '14',
  373.         '29'    => '08',
  374.         '30'    => '10',
  375.         '31'    => '08',
  376.         '32'    => '10',
  377.         '41'    => '01',
  378.         '42'    => '12',
  379.         '43'    => '15',     #wetter_wolkig.svg
  380.         '44'    => '03',
  381.         '45'    => '12',
  382.         '48'    => '12',
  383.         '49'    => '12',
  384.         '61'    => '04',
  385.         '62'    => '04',
  386.         '63'    => '08',     #wetter_leichter_regen.svg
  387.         '64'    => '04',
  388.         '65'    => '04',
  389.         '66'    => '06',
  390.         '67'    => '04',
  391.         '68'    => '05',
  392.         '69'    => '05',
  393.         '71'    => '08',
  394.         '72'    => '08',
  395.         '73'    => '09',
  396.         '74'    => '08',
  397.         '75'    => '08',
  398.         '76'    => '10',
  399.         '77'    => '08',
  400.         '78'    => '10',
  401.         '79'    => '10',
  402.         '81'    => '08',
  403.         '82'    => '08',
  404.         '83'    => '11',
  405.         '84'    => '08',
  406.         '85'    => '08',
  407.         '86'    => '11',
  408.         '87'    => '08',
  409.         '88'    => '11',
  410.         '89'    => '11',
  411.         '90'    => '02',
  412.         '91'    => '13',
  413.         '92'    => '13',
  414.         '93'    => '14',
  415.         '94'    => '13',
  416.         '95'    => '13',
  417.         '96'    => '14',
  418.         '97'    => '08',
  419.         '98'    => '10',
  420.         '99'    => '08',
  421.     ];
  422.     /**
  423.      * @param $symb
  424.      * @return string
  425.      */
  426.     public function getWeatherIcon($symb) {
  427.         return self::WEATHER_ICON_MAPPING[$symb];
  428.     }
  429.     public const SOCIAL_ICONs = [
  430.         "mail",
  431.         "linkedin",
  432.         "instagram",
  433.         "facebook",
  434.         "pinterest",
  435.         "twitter",
  436.         "whatsapp",
  437.         "youtube",
  438.         "tiktok",
  439.     ];
  440.     /**
  441.      * @return array
  442.      */
  443.     public function getSocialIcons() {
  444.         $icons = [];
  445.         foreach (self::SOCIAL_ICONs as $icon) {
  446.             $icons[] = [$icon'<span class=\'icon icon-' $icon '\' style=\'display:inline-block;width: 20px;font-size: 16px\'></span> ' ucfirst($icon)];
  447.         }
  448.         return $icons;
  449.     }
  450.     /**
  451.      * @param bool $includeMainRegion
  452.      * @return array
  453.      */
  454.     public function getRegionsArray($includeMainRegion false) {
  455.         $regions = [
  456.             'regiongraz' => Region::getById(326447),
  457.             'suedweststeiermark' => Region::getById(324085),
  458.             'thermenvulkanland' => Region::getById(326440),
  459.             'schladmingdachstein' => Region::getById(326444),
  460.             'oststeiermark' => Region::getById(326443),
  461.             'hochsteiermark' => Region::getById(326445),
  462.             'murau' => Region::getById(326446),
  463.             'murtal' => Region::getById(1037676),
  464.             'gesaeuse' => Region::getById(326441),
  465.             'ausseerland' => Region::getById(326442),
  466.             'erzbergleoben' => Region::getById(889409),
  467.         ];
  468.         if ($includeMainRegion) {
  469.             $regions array_merge(['steiermark' => Region::getById(324083)], $regions);
  470.         }
  471.         return $regions;
  472.     }
  473.     /**
  474.      * @param Region|null $currentRegion
  475.      * @return int
  476.      */
  477.     public function getIndexFromRegion(Region $currentRegion null$includeMainRegion false) {
  478.         $index 0;
  479.         if ($currentRegion != '') {
  480.             foreach ($this->getRegionsArray($includeMainRegion) as $region) {
  481.                 if ($region->getId() == $currentRegion->getId()) {
  482.                     return $index;
  483.                 }
  484.                 $index++;
  485.             }
  486.         }
  487.         return 0;
  488.     }
  489.     /**
  490.      * @return array
  491.      */
  492.     public function getWeatherPrognosis() {
  493.         $weatherTextStation = new WeatherTextStation\Listing();
  494.         $weatherTextStation->addConditionParam('IFNULL(isMountain,0) = 0');
  495.         $weatherTextStation->setOrderKey('o_modificationdate');
  496.         $weatherTextStation->setOrder('DESC');
  497.         $weatherTextStation->setLimit(1);
  498.         $weatherTextStation $weatherTextStation->current();
  499.         $prognosis = [
  500.             'today' => [],
  501.             'tomorrow' => [],
  502.             'modifiedDate' => null
  503.         ];
  504.         $duplicateTextCheck = [];
  505.         if ($weatherTextStation instanceof WeatherTextStation) {
  506.             /** @var WeatherTextStationDataSet $item */
  507.             foreach ($weatherTextStation->getWeatherData()->getItems() as $item) {
  508.                 $hash md5($item->getTitle() . $item->getText());
  509.                 if (!in_array($hash$duplicateTextCheck)) {
  510.                     if ($item->getDate()->isToday()) {
  511.                         $prognosis['today'][$item->getDaytime()] = [
  512.                             'title' => $item->getTitle(),
  513.                             'text' => $item->getText()
  514.                         ];
  515.                     } else if ($item->getDate()->isTomorrow()) {
  516.                         $prognosis['tomorrow'][$item->getDaytime()] = [
  517.                             'title' => $item->getTitle(),
  518.                             'text' => $item->getText()
  519.                         ];
  520.                     }
  521.                     $duplicateTextCheck[] = $hash;
  522.                 }
  523.             }
  524.             $prognosis['modifiedDate'] = Carbon::createFromTimestamp($weatherTextStation->getModificationDate());
  525.         }
  526.         return $prognosis;
  527.     }
  528.     /**
  529.      * @param $categoryId
  530.      * @return BlogTheme
  531.      */
  532.     public function getThemeByCategoryId($categoryId){
  533.         $blogTheme = new BlogTheme\Listing();
  534.         $blogTheme->addConditionParam('name != "" AND name IS NOT NULL AND blogCategories LIKE :categoryId', ['categoryId' => "%," $categoryId ",%"]);
  535.         $blogTheme->setLimit(1);
  536.         return $blogTheme->current();
  537.     }
  538.     public function getHostUrl() {
  539.         return \Pimcore\Tool::getHostUrl();
  540.     }
  541.     public function getHotspotData($left$top$item null$weatherOnly false$title '') {
  542.         if ($item) {
  543.             $link '';
  544.             $linkText '';
  545.             if ($item instanceof Region && $weatherOnly) {
  546.                 if ($item->getIsLive()) {
  547.                     $link $item->getSiteConfig()->getWeatherOverview();
  548.                     $linkText $item->getNameLocalized() ?: $item->getName();
  549.                 }
  550.                 $item $item->getWeatherLiveStation() ?: $item->getWeatherStation();
  551.             }
  552.             if ($item instanceof Community && $weatherOnly) {
  553.                 $link $this->linkGenerator->generate($item);
  554.                 $linkText $item->getNameLocalized() ?: $item->getName();
  555.                 $item $item->getLiveWeather() ?: $item->getPrognosis();
  556.             }
  557.             if ($item instanceof WeatherLiveStation) {
  558.                 return [
  559.                     'left' => $left,
  560.                     'top' => $top,
  561.                     'value' => $item->getTemperature() . '°',
  562.                     'img' => "/static/img/weather/" $this->getWeatherIcon($item->getSymbol()) . '.svg',
  563.                     'detail' => [
  564.                         'title' => $item->getName() . ', ' $item->getAltitude() . 'm',
  565.                         'subtitle' => '',
  566.                         'link' => [
  567.                             'href' => $link,
  568.                             'text' => $linkText ?: $this->translator->trans('weather.Details')
  569.                         ],
  570.                         'hasWeatherDetail' => true
  571.                     ]
  572.                 ];
  573.             }
  574.             if ($item instanceof WeatherStation) {
  575.                 return [
  576.                     'left' => $left,
  577.                     'top' => $top,
  578.                     'value' => $item->getTempNow() . '°',
  579.                     'img' => "/static/img/weather/" $this->getWeatherIcon($item->getSymbNow()) . '.svg',
  580.                     'detail' => [
  581.                         'title' => $item->getName() . ', ' $item->getAltitude() . 'm',
  582.                         'subtitle' => '',
  583.                         'link' => [
  584.                             'href' => $link,
  585.                             'text' => $linkText ?: $this->translator->trans('weather.Details')
  586.                         ],
  587.                         'hasWeatherDetail' => true
  588.                     ]
  589.                 ];
  590.             }
  591.             if ($item instanceof Region) {
  592.                 return [
  593.                     'left' => $left,
  594.                     'top' => $top,
  595.                     'smallHotspot' => true,
  596.                     'detail' => [
  597.                         'title' => $item->getNameLocalized() ?: $item->getName(),
  598.                         'subtitle' => '',
  599.                         'link' => [
  600.                             'href' => $item->getSiteConfig()->getHome(),
  601.                             'target' => '_blank',
  602.                             'text' => $this->translator->trans('generic.Details')
  603.                         ]
  604.                     ]
  605.                 ];
  606.             }
  607.             if ($item instanceof Community) {
  608.                 return [
  609.                     'left' => $left,
  610.                     'top' => $top,
  611.                     'smallHotspot' => true,
  612.                     'detail' => [
  613.                         'title' => $item->getNameLocalized() ?: $item->getName(),
  614.                         'subtitle' => '',
  615.                         'link' => [
  616.                             'href' => $this->linkGenerator->generate($item),
  617.                             'target' => '_blank',
  618.                             'text' => $this->translator->trans('generic.Details')
  619.                         ]
  620.                     ]
  621.                 ];
  622.             }
  623.             if ($item instanceof WeatherAvalancheStation) {
  624.                 return [
  625.                     'left' => $left,
  626.                     'top' => $top,
  627.                     'isPlain' => true,
  628.                     'avalanche' => 'avalanche-icon-' $item->getSymbol()
  629.                 ];
  630.             }
  631.             if($item instanceof DemiInfrastructure) {
  632.                 return [
  633.                     'left' => $left,
  634.                     'top' => $top,
  635.                     'smallHotspot' => true,
  636.                     'value' => null,
  637.                     'img' => null,
  638.                     'icon' => true,
  639.                     'detail' => true,
  640.                     'title' => $item->getName(),
  641.                     'subtitle' => '',
  642.                     'link' =>  [
  643.                         'href' => $this->linkGenerator->generate($item),
  644.                         'text' => $this->translator->trans('arrival.marker.buttontext'),
  645.                     ]
  646.                 ];
  647.             }
  648.             if ($item instanceof Webcam) {
  649.                 $iframeUrl '';
  650.                 if ($item->getWebcamType() === 'Panomax' || $item->getWebcamType() === 'Panocloud' || $item->getWebcamType() === 'iFrame') {
  651.                     $iframeUrl $item->getIFrameUrl();
  652.                 } else {
  653.                     $iframeUrl "https://webtv.feratel.com/webtv/?design=v5" . (!$item->getFeratelRemovePGParam() ? "&pg=63EC2CEF-349C-4921-B13D-6C0600312A71" '') . "&cam=" $item->getFid();
  654.                 }
  655.                 return [
  656.                     'left' => $left,
  657.                     'top' => $top,
  658.                     'value' => null,
  659.                     'img' => "/static/icons/svg/webcams.svg",
  660.                     'detail' => [
  661.                         'image' => $item->getImage_override() ?? $item->getImage(),
  662.                         'webcamIframe' => [
  663.                             'url' => $iframeUrl,
  664.                             'buttonText' => $this->translator->trans('generic.Details'),
  665.                         ]
  666.                     ],
  667.                     'icon' => true,
  668.                     'title' => $item->getName(),
  669.                     'subtitle' => $item->getRegion()?->getName()
  670.                 ];
  671.             }
  672.             if($item instanceof Asset\Image) {
  673.                 return [
  674.                     'left' => $left,
  675.                     'top' => $top,
  676.                     'smallHotspot' => true,
  677.                     'value' => null,
  678.                     'img' => null,
  679.                     'icon' => true,
  680.                     'detail' => [
  681.                         'image' => $item,
  682.                     ],
  683.                     'title' => $title ?: $item->getMetadata('General.title'),
  684.                     'subtitle' => '',
  685.                     'isPlain' => false,
  686.                 ];
  687.             }
  688.         }
  689.         return [];
  690.     }
  691.     public function getCountrySelectData($locale 'en'$currentSelectedCountryCode '')  {
  692.         $retArray = [[
  693.             "label" => "",
  694.             "value" => "",
  695.             "disabled" => true,
  696.             "selected" => empty($currentSelectedCountryCode),
  697.             "class" => "sr-only"
  698.         ]];
  699.         foreach (Countries::getNames($locale) as $countryCode => $countryName) {
  700.             $retArray[] = [
  701.                 "label" => $countryName,
  702.                 "value" => $countryCode,
  703.                 "class" => '',
  704.                 "selected" => !empty($currentSelectedCountryCode) && $currentSelectedCountryCode == $countryCode
  705.             ];
  706.         }
  707.         return $retArray;
  708.     }
  709.     public function getPathInfo(string $filename) {
  710.         return pathinfo($filename)['extension'];
  711.     }
  712.     public function getVideoEditable(\Pimcore\Model\DataObject\Data\Video $v$optionalPoster null) {
  713.         $videoData $v->getData();
  714.         if($videoData) {
  715.             $video = new  \Pimcore\Model\Document\Editable\Video();
  716.             $video->setConfig([
  717.                 "thumbnail" => "video"// specify your thumbnail here - IMPORTANT!
  718.                 "attributes" => [
  719.                     "class" => "embed-responsive-item js-play-video__video",
  720.                     "preload" => "auto",
  721.                     "lowQualityPlaceholder" => true,
  722.                     "controls" => "false",
  723.                     "controlsList" => "nodownload",
  724.                 ]
  725.             ]);
  726.             $video->setDataFromEditmode([
  727.                 'type' => $v->getType(),
  728.                 'id' => $videoData instanceof Asset $videoData->getId() : $videoData,
  729.                 'title' => $v->getTitle(),
  730.                 'description' => $v->getDescription(),
  731.                 'poster' => $optionalPoster instanceof Asset\Image $optionalPoster : ($v->getPoster() ?: null)
  732.             ]);
  733.             return $video;
  734.         }
  735.         return null;
  736.     }
  737.     public function getMediaUser(Request $request) {
  738.         $pressSession $request->getSession()->getBag('pressLogin');
  739.         if($userId $pressSession->get('userid')) {
  740.             if($user MediaUser::getById($userId)) {
  741.                 return $user;
  742.             }
  743.         }
  744.         return null;
  745.     }
  746.     public function getPressWishlistCount(Request $request) : int {
  747.         $dossiers $request->getSession()?->get('pressDossierWishlistIds', []);
  748.         $articles $request->getSession()?->get('pressArticleWishlistIds', []);
  749.         $image $request->getSession()?->get('pressImageWishlistIds', []);
  750.         $album $request->getSession()?->get('pressAlbumWishlistIds', []);
  751.         $albumItems $request->getSession()?->get('pressAlbumItemsWishlistIds', []);
  752.         return count($dossiers) + count($articles) + count($image) + count($album) + count($albumItems);
  753.     }
  754.     public function randomizeRelationEvery24h(array $elementsDocument $document) {
  755.         $ids implode(',',array_map(function($element) {
  756.             return $element->getId();
  757.         }, $elements));
  758.         $cacheKey md5('radnomizeRelations' $ids $document->getId());
  759.         if (!($data \Pimcore\Cache::load($cacheKey))) {
  760.             $cacheTime 86400//== 1 day in seconds
  761.             shuffle($elements);
  762.             \Pimcore\Cache::save($elements$cacheKey, [], $cacheTime0true);
  763.             return $elements;
  764.         } else {
  765.             return $data;
  766.         }
  767.     }
  768.     public function randomizeBlock(array $elementsDocument $document) : array {
  769.         $ids implode(',',array_map(function($element) {
  770.             return $element->getEditable('headline')->getData();
  771.         }, $elements));
  772.         $cacheKey md5('randomizeRelations' $ids $document->getId());
  773.         if (!($data \Pimcore\Cache::load($cacheKey))) {
  774.             $cacheTime 86400//== 1 day in seconds
  775.             shuffle($elements);
  776.             \Pimcore\Cache::save($elements$cacheKey, [], $cacheTime0true);
  777.             return $elements;
  778.         } else {
  779.             return $data;
  780.         }
  781.     }
  782.     public function getImageType(Asset $asset) {
  783.         $mimetype $asset->getMimetype();
  784.         $posSlash strpos($mimetype'/' );
  785.         return substr($mimetype$posSlash+1);
  786.     }
  787.     public function getBadgesForAsset(Asset $assetDataObject\MediaAsset $mediaAsset null) {
  788.         $badges = [];
  789.         $categories $asset->getMetadata('General.categories');
  790.         $number $asset->getMetadata('General.number');
  791.         if($mediaAsset instanceof DataObject\MediaAsset) {
  792.             if(!empty($mediaAsset->getCategories())) {
  793.                 $categories $mediaAsset->getCategories();
  794.             }
  795.             if($mediaAsset->getNumber()) {
  796.                 $number $mediaAsset->getNumber();
  797.             }
  798.         }
  799.         if(!empty($categories)) {
  800.             if(is_array($categories)) {
  801.                 $badges[] = $categories[0]->getName();
  802.             } else {
  803.                 $badges[] = $categories->getName();
  804.             }
  805.         }
  806.         if(!empty($number)) {
  807.             $badges[] = $this->translator->trans('general.Nr') . ' ' $number;
  808.         }
  809.         return $badges;
  810.     }
  811.     public function getFormattedVideoDuration(Asset\Video $video) {
  812.         $duration $video->getDuration();
  813.         $mins floor($duration 60);
  814.         if($mins 10) {
  815.             $mins $mins;
  816.         }
  817.         $sec ceil($duration 60);
  818.         if($sec 10) {
  819.             $sec $sec;
  820.         }
  821.         return $mins ':' $sec;
  822.     }
  823.     public function getYoutubeIdFromHref(string $youtubeUrl) {
  824.         $pos strpos($youtubeUrl'v=') + 2;
  825.         return substr($youtubeUrl$pos);
  826.     }
  827.     public function getSubttitleOfAudio(Asset\Audio $audiostring $locale 'de') : string {
  828.         $subtitle '';
  829.         if($copyright $audio->getMetadata('General.copyright'$locale)) {
  830.             $subtitle .= '© ' $copyright->getText();
  831.         }
  832.         /** @var DataObject\PressAuthor $author */
  833.         if($author $audio->getMetadata('General.author')) {
  834.             if(!empty($subtitle)) $subtitle .= '<br>';
  835.             $subtitle .= $author->getName();
  836.         }
  837.         if($description $audio->getMetadata('General.usage'$locale)) {
  838.             if(!empty($subtitle)) $subtitle .= '<br>';
  839.             $subtitle .= $description;
  840.         }
  841.         if($description $audio->getMetadata('General.description'$locale)) {
  842.             if(!empty($subtitle)) $subtitle .= '<br>';
  843.             $subtitle .= $description;
  844.         }
  845.         return $subtitle;
  846.     }
  847.     /**
  848.      * @param Document\Editable\Renderlet[] $renderlets
  849.      * @return bool
  850.      */
  851.     public function checkIfNoRenderletIsValid($renderlets) : bool {
  852.         /**
  853.          * @var Document\Editable\Renderlet $renderlet
  854.          */
  855.         foreach ($renderlets as $renderlet) {
  856.             if(!$renderlet->isEmpty()) {
  857.                 if($renderlet->getType() == 'object') {
  858.                     if(($o $renderlet->getO()) && $o instanceof DataObject) {
  859.                         if($o instanceof DataObject\DemiEvent) {
  860.                             if($this->objectExtension->isEventNotExpired($o)) {
  861.                                 return false;
  862.                             }
  863.                         } elseif($o instanceof DataObject\BlogArticle) {
  864.                             if(!$o->getArticleDate()->isFuture()) {
  865.                                 return false;
  866.                             }
  867.                         } elseif($o instanceof DataObject\Package) {
  868.                             if($this->objectExtension->isPackageNotExpired($o)) {
  869.                                 return false;
  870.                             }
  871.                         }
  872.                     }
  873.                 } else { // is document or asset => cannot expire
  874.                     return false;
  875.                 }
  876.             }
  877.         }
  878.         return true;
  879.     }
  880.     /**
  881.      * @param $object
  882.      * @param string $authorText
  883.      * @return string
  884.      */
  885.     public function getAuthorForQuote($objectstring $authorText) : string {
  886.         if($object instanceof DataObject\PressAuthor) {
  887.             return $object->getName();
  888.         } elseif($object instanceof DataObject\BlogAuthor) {
  889.             return $object->getName();
  890.         } elseif(!empty($authorText)) {
  891.             return $authorText;
  892.         }
  893.         return '';
  894.     }
  895.     public function getCurrentWeatherImage(WeatherStation $weatherStationDataObject\SiteConfig $config) : ?Asset\Image {
  896.         $icon $this->getCurrentWeatherIcon($weatherStation);
  897.         if( $icon !== null ){
  898.             $icon $this->getWeatherIcon$icon ); //get mapped icon
  899.         }
  900.         if($icon && ($image $config->get('icon' $icon))) {
  901.             return $image;
  902.         } elseif($image $config->getIconDefault()) {
  903.             return $image;
  904.         }
  905.         return null;
  906.     }
  907.     private function getCurrentWeatherIcon(WeatherStation $weatherStation)
  908.     {
  909.         $currentHour Carbon::now()->hour;
  910.         $today $weatherStation->today();
  911.         if($today) {
  912.             if($currentHour >= && $currentHour 11) { //morning
  913.                 return $today->getSymb06();
  914.             }elseif($currentHour >= 11 && $currentHour 16) { //lunch
  915.                 return $today->getSymb12();
  916.             }elseif($currentHour >= 16 && $currentHour 21) { //evening
  917.                 return $today->getSymb18();
  918.             } else { // night 21-03
  919.                 return $today->getSymb24();
  920.             }
  921.         }
  922.         return null;
  923.     }
  924.     public function getDownloadItemDataByAsset(Asset $asset) {
  925.         $image false;
  926.         $viewLink false;
  927.         if ($asset instanceof Asset\Image) {
  928.             $image $asset->getThumbnail('download-list-item');
  929.             $viewLink $asset->getFullPath();
  930.         } else if ($asset instanceof Asset\Video) {
  931.             $image $asset->getImageThumbnail('download-list-item');
  932.         } else if ($asset instanceof Asset\Document) {
  933.             $image $asset->getImageThumbnail('download-list-item');
  934.             if ($asset->getMimetype() == 'application/pdf') {
  935.                 $viewLink $asset->getFullPath();
  936.             }
  937.         }
  938.         $filename $asset->getFilename();
  939.         $fileEnding pathinfo($filename)['extension'];
  940.         return [
  941.             'file' => strtoupper($fileEnding),
  942.             'image' => $image,
  943.             'href' => $this->router->generate('app_asset_download', ['id' => $asset->getId()]),
  944.             'text' => $asset->getFilename(),
  945.             'fileSize' => $asset->getFileSize(true),
  946.             'viewLink' =>  $viewLink
  947.         ];
  948.     }
  949.     /**
  950.      * @param DataObject\PackageCategory[] $categories
  951.      */
  952.     public function getPackagesByPackageCategories(array $categories) : array {
  953.         $elements = [];
  954.         $allCategories = [];
  955.         foreach($categories as $category) {
  956.             $this->getChildPackageCategories($category$allCategories);
  957.         }
  958.         $packageListing = new DataObject\Package\Listing();
  959.         $conditions = [];
  960.         foreach ($allCategories as $key => $category) {
  961.             $conditions[] = 'categories LIKE "%,' $key ',%"';
  962.         }
  963.         if(!empty($conditions)) {
  964.             $packageListing->addConditionParam(implode(' OR '$conditions));
  965.         }
  966.         return $packageListing->getObjects();
  967.     }
  968.     public function removeUnpublishedElements(array $elements) : array {
  969.         $publishedElements = [];
  970.         foreach ($elements as $element) {
  971.             if(method_exists($element'getPublished') && $element->getPublished()) {
  972.                 $publishedElements[] = $element;
  973.             }
  974.         }
  975.         return $publishedElements;
  976.     }
  977.     public function chooseDescription(?string $shortDescription, ?string $longDescriptionint $numSignsShortDescription 100) {
  978.         //returns the sD if it has a min. of letters, otherwise returns the lD except it is empty.
  979.         if(strlen($shortDescription) > $numSignsShortDescription) {
  980.             return $shortDescription;
  981.         } elseif(!empty($longDescription)) {
  982.             return $longDescription;
  983.         }
  984.         return $shortDescription;
  985.     }
  986.     /**
  987.      * @return Asset\Image|null
  988.      */
  989.     public function getMainLogo():?Asset\Image{
  990.         $rootDocument Document::getById(self::ROOT_DOCUMENT_ID);
  991.         if($rootDocument) {
  992.             $mainConfig $rootDocument->getProperty('siteConfig');
  993.             if ($mainConfig) {
  994.                 $logo $mainConfig->getLogo();
  995.                 if ($logo instanceof Asset\Image) {
  996.                     return $logo;
  997.                 }
  998.             }
  999.         }
  1000.         return null;
  1001.     }
  1002.     public function getMainConfig(){
  1003.         $rootDocument Document::getById(self::ROOT_DOCUMENT_ID);
  1004.         if($rootDocument) {
  1005.             $mainConfig $rootDocument->getProperty('siteConfig');
  1006.             if ($mainConfig) {
  1007.                 return $mainConfig->getId();
  1008.             }
  1009.         }
  1010.         return null;
  1011.     }
  1012.     private function getChildPackageCategories(DataObject\PackageCategory $category, array & $categories) {
  1013.         $categories[$category->getId()] = $category;
  1014.         foreach ($category->getChildren() as $child) {
  1015.             if($child instanceof DataObject\PackageCategory) {
  1016.                 $this->getChildPackageCategories($child$categories);
  1017.             }
  1018.         }
  1019.     }
  1020.     public function getFileContent($file) {
  1021.         return file_get_contents$file );
  1022.     }
  1023.     public function getSVGPathForExperienceTeaserBackgroundText(string $textstring $lang) {
  1024.         $mapping = [
  1025.             "discover-en" => "en/discover.svg",
  1026.             "enjoy-en" => "en/enjoy.svg",
  1027.             "experience-en" => "en/experience.svg",
  1028.             "visit-en"  => "en/visit.svg",
  1029.             "discover-de" => "de/entdecken.svg",
  1030.             "enjoy-de" => "de/genießen.svg",
  1031.             "experience-de" => "de/erleben.svg",
  1032.             "visit-de"  => "de/besuchen.svg",
  1033.             "discover-cz" => "cze/objevte.svg",
  1034.             "enjoy-cz" => "cze/užívejte si.svg",
  1035.             "experience-cz" => "cze/zažijte.svg",
  1036.             "visit-cz"  => "cze/navštivte.svg",
  1037.             "discover-hu" => "hun/kalandok.svg",
  1038.             "enjoy-hu" => "hun/élvezetek.svg",
  1039.             "experience-hu" => "hun/élmények.svg",
  1040.             "visit-hu"  => "hun/látnivalók.svg",
  1041.             "discover-nl" => "nl/ontdekken.svg",
  1042.             "enjoy-nl" => "nl/genieten.svg",
  1043.             "experience-nl" => "nl/beleven.svg",
  1044.             "visit-nl"  => "nl/bezoeken.svg",
  1045.             "discover-pl" => "pl/odkryj.svg",
  1046.             "enjoy-pl" => "pl/ciesz się.svg",
  1047.             "experience-pl" => "pl/doświadcz.svg",
  1048.             "visit-pl"  => "pl/odwiedź.svg",
  1049.         ];
  1050.         return $mapping[$text '-' $lang];
  1051.     }
  1052.     public function getObjectImageFromCSEResult(Item $cseItem) {
  1053.         $path parse_url($cseItem->getLink())['path'];
  1054.         $id $this->getIdFromPath($path);
  1055.         if($id) {
  1056.             $object DataObject::getById($id);
  1057.             if($object instanceof DataObject\DemiAccommodationServiceProvider) {
  1058.                 return $object->getImages() ? current($object->getImages()) : null;
  1059.             }
  1060.         }
  1061.         return null;
  1062.     }
  1063.     private function getIdFromPath(string $path) : int {
  1064.         $matches = array();
  1065.         if (preg_match('#(\d+)$#'$path$matches)) {
  1066.             return $matches[1];
  1067.         }
  1068.         return 0;
  1069.     }
  1070.     public function getTimeOfDay(int $hourint $minuteint $second) {
  1071.         $timeString '';
  1072.         if($hour 10) {
  1073.             $timeString .= '0';
  1074.         }
  1075.         $timeString .= $hour ':';
  1076.         if($minute 10) {
  1077.             $timeString .= '0';
  1078.         }
  1079.         $timeString .= $minute ':';
  1080.         if($second 10) {
  1081.             $timeString .= '0';
  1082.         }
  1083.         $timeString .= $second;
  1084.         return $timeString;
  1085.     }
  1086.     public function getCache($cacheKey) {
  1087.         return \Pimcore\Cache::load($cacheKey) ?? false;
  1088.     }
  1089.     public function saveInCache($cacheKey$data$lifetime 86400) {
  1090.         \Pimcore\Cache::save($data$cacheKey, [], $lifetime0true);
  1091.     }
  1092.     public function cachingAllowed() : bool {
  1093.         if($this->getEnv('APP_CACHE') !== 'true') {
  1094.             return false;
  1095.         }
  1096.         $request $this->getMainRequest(); # no caching if pimcore_preview
  1097.         if(Tool::isFrontendRequestByAdmin($request)) {
  1098.             return false;
  1099.         }
  1100.         if($request) {
  1101.             // no caching if path starts with a site root document like /steiermark.com/
  1102.             $sites = new Site\Listing();
  1103.             foreach ($sites as $site) {
  1104.                 if ($site && $site->getRootDocument() instanceof Document\Page) {
  1105.                     if(str_starts_with($request->getPathInfo(), $site->getRootDocument()->getRealFullPath() . '/')) {
  1106.                         return false;
  1107.                     }
  1108.                 }
  1109.             }
  1110.         }
  1111.         return true;
  1112. //        old:
  1113. //        return $this->getEnv('APP_CACHE') === 'true' && !$request?->get('pimcore_preview') && !str_starts_with($request->getPathInfo(), '/steiermark.com/');
  1114.     }
  1115.     public function getAssetOrientation($asset) : string {
  1116.         $orientation 'landscape';
  1117.         if($asset instanceof Asset\Image) {
  1118.             $orientation $asset->getWidth() >= $asset->getHeight() ? 'landscape' 'portrait';
  1119.         }
  1120.         return $orientation;
  1121.     }
  1122. }