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

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