vendor/contao/core-bundle/src/Resources/contao/elements/ContentGallery.php line 76

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Contao.
  4.  *
  5.  * (c) Leo Feyer
  6.  *
  7.  * @license LGPL-3.0-or-later
  8.  */
  9. namespace Contao;
  10. use Contao\CoreBundle\Exception\PageNotFoundException;
  11. use Contao\Model\Collection;
  12. use Symfony\Component\Filesystem\Path;
  13. /**
  14.  * Front end content element "gallery".
  15.  */
  16. class ContentGallery extends ContentElement
  17. {
  18.     /**
  19.      * Files object
  20.      * @var Collection|FilesModel
  21.      */
  22.     protected $objFiles;
  23.     /**
  24.      * Template
  25.      * @var string
  26.      */
  27.     protected $strTemplate 'ce_gallery';
  28.     /**
  29.      * Return if there are no files
  30.      *
  31.      * @return string
  32.      */
  33.     public function generate()
  34.     {
  35.         // Use the home directory of the current user as file source
  36.         if ($this->useHomeDir && System::getContainer()->get('contao.security.token_checker')->hasFrontendUser())
  37.         {
  38.             $this->import(FrontendUser::class, 'User');
  39.             if ($this->User->assignDir && $this->User->homeDir)
  40.             {
  41.                 $this->multiSRC = array($this->User->homeDir);
  42.             }
  43.         }
  44.         else
  45.         {
  46.             $this->multiSRC StringUtil::deserialize($this->multiSRC);
  47.         }
  48.         // Return if there are no files
  49.         if (empty($this->multiSRC) || !\is_array($this->multiSRC))
  50.         {
  51.             return '';
  52.         }
  53.         // Get the file entries from the database
  54.         $this->objFiles FilesModel::findMultipleByUuids($this->multiSRC);
  55.         if ($this->objFiles === null)
  56.         {
  57.             return '';
  58.         }
  59.         // Make sure we have at least one item per row to prevent division by zero
  60.         if ($this->perRow 1)
  61.         {
  62.             $this->perRow 1;
  63.         }
  64.         return parent::generate();
  65.     }
  66.     /**
  67.      * Generate the content element
  68.      */
  69.     protected function compile()
  70.     {
  71.         $images = array();
  72.         $projectDir System::getContainer()->getParameter('kernel.project_dir');
  73.         $objFiles $this->objFiles;
  74.         // Get all images
  75.         while ($objFiles->next())
  76.         {
  77.             // Continue if the files has been processed or does not exist
  78.             if (isset($images[$objFiles->path]) || !file_exists(Path::join($projectDir$objFiles->path)))
  79.             {
  80.                 continue;
  81.             }
  82.             // Single files
  83.             if ($objFiles->type == 'file')
  84.             {
  85.                 $objFile = new File($objFiles->path);
  86.                 if (!$objFile->isImage)
  87.                 {
  88.                     continue;
  89.                 }
  90.                 $row $objFiles->row();
  91.                 $row['mtime'] = $objFile->mtime;
  92.                 // Add the image
  93.                 $images[$objFiles->path] = $row;
  94.             }
  95.             // Folders
  96.             else
  97.             {
  98.                 $objSubfiles FilesModel::findByPid($objFiles->uuid, array('order' => 'name'));
  99.                 if ($objSubfiles === null)
  100.                 {
  101.                     continue;
  102.                 }
  103.                 while ($objSubfiles->next())
  104.                 {
  105.                     // Skip subfolders and files that do not exist
  106.                     if ($objSubfiles->type == 'folder' || !file_exists(Path::join($projectDir$objSubfiles->path)))
  107.                     {
  108.                         continue;
  109.                     }
  110.                     $objFile = new File($objSubfiles->path);
  111.                     if (!$objFile->isImage)
  112.                     {
  113.                         continue;
  114.                     }
  115.                     $row $objSubfiles->row();
  116.                     $row['mtime'] = $objFile->mtime;
  117.                     // Add the image
  118.                     $images[$objSubfiles->path] = $row;
  119.                 }
  120.             }
  121.         }
  122.         // Sort array
  123.         switch ($this->sortBy)
  124.         {
  125.             default:
  126.             case 'name_asc':
  127.                 uksort($images, static function ($a$b): int
  128.                 {
  129.                     return strnatcasecmp(basename($a), basename($b));
  130.                 });
  131.                 break;
  132.             case 'name_desc':
  133.                 uksort($images, static function ($a$b): int
  134.                 {
  135.                     return -strnatcasecmp(basename($a), basename($b));
  136.                 });
  137.                 break;
  138.             case 'date_asc':
  139.                 uasort($images, static function (array $a, array $b)
  140.                 {
  141.                     return $a['mtime'] <=> $b['mtime'];
  142.                 });
  143.                 break;
  144.             case 'date_desc':
  145.                 uasort($images, static function (array $a, array $b)
  146.                 {
  147.                     return $b['mtime'] <=> $a['mtime'];
  148.                 });
  149.                 break;
  150.             // Deprecated since Contao 4.0, to be removed in Contao 5.0
  151.             case 'meta':
  152.                 trigger_deprecation('contao/core-bundle''4.0''The "meta" key in "Contao\ContentGallery::compile()" has been deprecated and will no longer work in Contao 5.0.');
  153.                 // no break
  154.             case 'custom':
  155.                 $images ArrayUtil::sortByOrderField($images$this->orderSRC);
  156.                 break;
  157.             case 'random':
  158.                 shuffle($images);
  159.                 $this->Template->isRandomOrder true;
  160.                 break;
  161.         }
  162.         $images array_values($images);
  163.         // Limit the total number of items (see #2652)
  164.         if ($this->numberOfItems 0)
  165.         {
  166.             $images \array_slice($images0$this->numberOfItems);
  167.         }
  168.         $offset 0;
  169.         $total \count($images);
  170.         $limit $total;
  171.         // Paginate the result of not randomly sorted (see #8033)
  172.         if ($this->perPage && $this->sortBy != 'random')
  173.         {
  174.             // Get the current page
  175.             $id 'page_g' $this->id;
  176.             $page = (int) (Input::get($id) ?? 1);
  177.             // Do not index or cache the page if the page number is outside the range
  178.             if ($page || $page max(ceil($total/$this->perPage), 1))
  179.             {
  180.                 throw new PageNotFoundException('Page not found: ' Environment::get('uri'));
  181.             }
  182.             // Set limit and offset
  183.             $offset = ($page 1) * $this->perPage;
  184.             $limit min($this->perPage $offset$total);
  185.             $objPagination = new Pagination($total$this->perPageConfig::get('maxPaginationLinks'), $id);
  186.             $this->Template->pagination $objPagination->generate("\n  ");
  187.         }
  188.         $rowcount 0;
  189.         $colwidth floor(100/$this->perRow);
  190.         $body = array();
  191.         $figureBuilder System::getContainer()
  192.             ->get('contao.image.studio')
  193.             ->createFigureBuilder()
  194.             ->setSize($this->size)
  195.             ->setLightboxGroupIdentifier('lb' $this->id)
  196.             ->enableLightbox((bool) $this->fullsize);
  197.         // Rows
  198.         for ($i=$offset$i<$limit$i+=$this->perRow)
  199.         {
  200.             $class_tr '';
  201.             if ($rowcount == 0)
  202.             {
  203.                 $class_tr .= ' row_first';
  204.             }
  205.             if (($i $this->perRow) >= $limit)
  206.             {
  207.                 $class_tr .= ' row_last';
  208.             }
  209.             $class_eo = (($rowcount 2) == 0) ? ' even' ' odd';
  210.             // Columns
  211.             for ($j=0$j<$this->perRow$j++)
  212.             {
  213.                 $class_td '';
  214.                 if ($j == 0)
  215.                 {
  216.                     $class_td .= ' col_first';
  217.                 }
  218.                 if ($j == ($this->perRow 1))
  219.                 {
  220.                     $class_td .= ' col_last';
  221.                 }
  222.                 // Image / empty cell
  223.                 if (($j $i) < $limit && null !== ($image $images[$i $j] ?? null))
  224.                 {
  225.                     $figure $figureBuilder
  226.                         ->fromId($image['id'])
  227.                         ->build();
  228.                     $cellData $figure->getLegacyTemplateData($this->imagemargin);
  229.                     $cellData['figure'] = $figure;
  230.                 }
  231.                 else
  232.                 {
  233.                     $cellData = array('addImage' => false);
  234.                 }
  235.                 // Add column width and class
  236.                 $cellData['colWidth'] = $colwidth '%';
  237.                 $cellData['class'] = 'col_' $j $class_td;
  238.                 $body['row_' $rowcount $class_tr $class_eo][$j] = (object) $cellData;
  239.             }
  240.             ++$rowcount;
  241.         }
  242.         $request System::getContainer()->get('request_stack')->getCurrentRequest();
  243.         // Always use the default template in the back end
  244.         if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  245.         {
  246.             $this->galleryTpl '';
  247.         }
  248.         $objTemplate = new FrontendTemplate($this->galleryTpl ?: 'gallery_default');
  249.         $objTemplate->setData($this->arrData);
  250.         $objTemplate->body $body;
  251.         $objTemplate->headline $this->headline// see #1603
  252.         $this->Template->images $objTemplate->parse();
  253.     }
  254. }
  255. class_alias(ContentGallery::class, 'ContentGallery');