src/Twig/AppRuntime.php line 158

  1. <?php
  2. namespace App\Twig;
  3. use App\Entity\News;
  4. use App\Repository\NewsRepository;
  5. use App\Repository\UseCaseRepository;
  6. use DateTime;
  7. use Sulu\Bundle\MediaBundle\Api\Media;
  8. use Sulu\Component\SmartContent\ArrayAccessItem;
  9. use Symfony\Component\Filesystem\Exception\FileNotFoundException;
  10. use Twig\Extension\RuntimeExtensionInterface;
  11. class AppRuntime implements RuntimeExtensionInterface
  12. {
  13.     // Defines the max words count for each element in teaser-grid/news-grid
  14.     public const MAX_WORDS_COUNT 20;
  15.     private string $flyOutNavigationPath;
  16.     public function __construct(
  17.         private readonly NewsRepository    $newsRepository,
  18.         private readonly UseCaseRepository $useCaseRepository,
  19.         string                             $projectDir,
  20.         private readonly bool              $forceWebpThumbnails,
  21.         private readonly array             $forceWebpThumbnailsTypes
  22.     )
  23.     {
  24.         $this->flyOutNavigationPath $projectDir '/navigation/flyOutNavigation.json';
  25.     }
  26.     /**
  27.      * @return array
  28.      */
  29.     public function getFlyOutNavigation(): array
  30.     {
  31.         if (!file_exists($this->flyOutNavigationPath)) {
  32.             throw new FileNotFoundException('Fly-Out-Navigation JSON file does not exist!');
  33.         }
  34.         $contentJSON file_get_contents($this->flyOutNavigationPath);
  35.         return json_decode($contentJSONtrue);
  36.     }
  37.     /**
  38.      * Return all news from database.
  39.      * News are filtered by tags from news-grid.
  40.      *
  41.      * @param string|null $newsGridTags
  42.      * @return array
  43.      */
  44.     public function getNews(?string $newsGridTags): array
  45.     {
  46.         $newsArray = [];
  47.         $news $this->newsRepository->findAll();
  48.         if (count($news) > 0) {
  49.             /** @var News $item */
  50.             foreach ($news as $item) {
  51.                 $itemTags $item->getTags();
  52.                 // news-grid has Tags
  53.                 if (!empty($newsGridTags) && !empty(trim($newsGridTags))) {
  54.                     // But news item does not --> Continue to next news item!
  55.                     if (empty($itemTags)) {
  56.                         continue;
  57.                     }
  58.                     if (str_contains($itemTags',') !== false) {
  59.                         $newsItemTagsArray explode(','$itemTags);
  60.                         $newsItemTagsArray array_map('trim'$newsItemTagsArray);
  61.                     } else {
  62.                         $newsItemTagsArray = [trim($itemTags)];
  63.                     }
  64.                     $matched false;
  65.                     foreach ($newsItemTagsArray as $newsItemTag) {
  66.                         // news item has at least one tag that matches news-grid Tags
  67.                         if (str_contains(strtolower($newsGridTags), strtolower($newsItemTag)) !== false) {
  68.                             $matched true;
  69.                             break;
  70.                         }
  71.                     }
  72.                     // news item does not have any tag that matches news-grid Tags --> Continue to next news item!
  73.                     if (!$matched) {
  74.                         continue;
  75.                     }
  76.                 }
  77.                 $image json_decode($item->getImage(), true);
  78.                 $dateObject = new DateTime($item->getDate());
  79.                 $newsArray[] = [
  80.                     'title' => $item->getTitle(),
  81.                     'description' => $item->getDescription(),
  82.                     'source' => $item->getSource(),
  83.                     'date' => $item->getDate(),
  84.                     'dateGerman' => $dateObject->format('d.m.Y'),
  85.                     'image' => $image['id'],
  86.                     'thumbnails' => null,
  87.                     'url' => $item->getUrl(),
  88.                 ];
  89.             }
  90.         }
  91.         return $newsArray;
  92.     }
  93.     /**
  94.      * Return all news from database.
  95.      * News are filtered by tags from news-grid.
  96.      *
  97.      * @return array
  98.      */
  99.     public function getUseCases(string $locale): array
  100.     {
  101.         $useCasesArray = [];
  102.         $useCases $this->useCaseRepository->findAllWithTopics($locale);
  103.         if (count($useCases) > 0) {
  104.             foreach ($useCases as $item) {
  105.                 $image json_decode($item->getImage(), true);
  106.                 $topicImage json_decode($item->getUseCaseTopic()->getImage(), true);
  107.                 $useCasesArray[] = [
  108.                     'topic' => [
  109.                         'title' => $item->getUseCaseTopic()->getTitle(),
  110.                         'description' => $item->getUseCaseTopic()->getDescription(),
  111.                         'image' => $topicImage['id'],
  112.                     ],
  113.                     'title' => $item->getTitle(),
  114.                     'titleMobile' => $item->getTitleMobile(),
  115.                     'description' => $item->getDescription(),
  116.                     'image' => $image['id'],
  117.                     'thumbnails' => null,
  118.                 ];
  119.             }
  120.         }
  121.         return $useCasesArray;
  122.     }
  123.     /**
  124.      * - Map stories to array like news
  125.      * - Merge stories and news
  126.      * - Sort by date
  127.      *
  128.      * @param array $stories
  129.      * @param array $publications
  130.      * @param array $pages
  131.      * @param array $news
  132.      * @param bool $contentMixed
  133.      * @return array
  134.      */
  135.     public function sortByDate(
  136.         array $stories,
  137.         array $publications,
  138.         array $pages,
  139.         array $news,
  140.         bool $contentMixed false
  141.     ): array {
  142.         $pagesArray = [];
  143.         // Get other pages only if contentMixed is true
  144.         if ($contentMixed) {
  145.             $pagesArray array_merge($stories$publications$pages);
  146.         }
  147.         $newsArray $news;
  148.         if (count($pagesArray) > 0) {
  149.             $newsArray array_merge($pagesArray$news);
  150.         }
  151.         // Sort descending by date
  152.         usort($newsArray, function ($a$b) {
  153.             return $a['date'] < $b['date'];
  154.         });
  155.         return $newsArray;
  156.     }
  157.     /**
  158.      * Prepare data from smart content for news-grid.
  159.      * If description has more than 20 words, the first 20 words will be cut and ... will be added to the end.
  160.      * If alternativeText is available, replace description. Text will not be cut. Length remains unchanged.
  161.      *
  162.      * @param array $items
  163.      * @param string $locale
  164.      * @return array
  165.      */
  166.     public function getDataFromSmartContent(array $itemsstring $locale): array
  167.     {
  168.         $data = [];
  169.         /** @var ArrayAccessItem $item */
  170.         foreach ($items as $item) {
  171.             /** @var Media $image */
  172.             $excerptImage $item['excerptAlternativeImage'] ?? $item['excerptImages'] ?? null;
  173.             $thumbnails $excerptImage instanceof Media $excerptImage->getThumbnails() : null;
  174.             // Teaser grid title is preferred, then title!
  175.             $title $item['excerptTitleTeaserGrid'] ?? '';
  176.             if (empty($title)) {
  177.                 $title $item['excerptTitle'] ?? '';
  178.             }
  179.             // Custom Text is preferred, then description!
  180.             $description $item['excerptCustomText'] ?? '';
  181.             if (empty($description)) {
  182.                 $description $item['excerptDescription'] ?? '';
  183.                 if (!empty($description)) {
  184.                     $descriptionArray explode(' '$description);
  185.                     // Get the first 20 words
  186.                     if (count($descriptionArray) > self::MAX_WORDS_COUNT) {
  187.                         $descriptionArray array_slice($descriptionArray0self::MAX_WORDS_COUNT);
  188.                         $description implode(' '$descriptionArray);
  189.                         $description .= ' ...';
  190.                     }
  191.                 }
  192.             }
  193.             // Creation date from settings is date of story!
  194.             $authored $item['authored'];
  195.             $data[] = [
  196.                 'title' => $title,
  197.                 'description' => $description,
  198.                 'source' => $item['excerptType'] ?? '',
  199.                 'date' => $authored->format('Y-m-d'),
  200.                 'dateGerman' => $authored->format('d.m.Y'),
  201.                 'image' => $thumbnails['2880x'] ?? null,
  202.                 'thumbnails' => $thumbnails,
  203.                 'url' => '/' $locale $item['url'],  // Add locale to URL
  204.             ];
  205.         }
  206.         return $data;
  207.     }
  208.     public function getThumbnailUrl($media$size)
  209.     {
  210.         if($media instanceof Media) {
  211.             $thumbnails $media->getThumbnails();
  212.             if(!array_key_exists($size$thumbnails)) {
  213.                 throw new \InvalidArgumentException('Unknown thumbnail size "' $size '".');
  214.             }
  215.             if($this->forceWebpThumbnails && in_array($media->getFileVersion()->getMimeType(), $this->forceWebpThumbnailsTypes)) {
  216.                 $size .= '.webp';
  217.             }
  218.             return $thumbnails[$size];
  219.         } else if(is_array($media) && array_key_exists('thumbnails'$media)) {
  220.             $thumbnails $media['thumbnails'];
  221.             if(!array_key_exists($size$thumbnails)) {
  222.                 throw new \InvalidArgumentException('Unknown thumbnail size "' $size '".');
  223.             }
  224.             $extensionMimeMap = [
  225.                 'jpg' => 'image/jpeg',
  226.                 'jpeg' => 'image/jpeg',
  227.                 'png' => 'image/png',
  228.                 'webp' => 'image/webp'
  229.             ];
  230.             $ext strtolower(pathinfo(parse_url($media['image'],  PHP_URL_PATH), PATHINFO_EXTENSION));
  231.             if($this->forceWebpThumbnails && array_key_exists($ext$extensionMimeMap) && in_array($extensionMimeMap[$ext], $this->forceWebpThumbnailsTypes)) {
  232.                 $size .= '.webp';
  233.             }
  234.             return $thumbnails[$size];
  235.         }
  236.     }
  237. }