vendor/contao/news-bundle/src/Resources/contao/modules/ModuleNewsList.php line 79

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 module "news list".
  14.  *
  15.  * @property array  $news_archives
  16.  * @property string $news_featured
  17.  * @property string $news_order
  18.  */
  19. class ModuleNewsList extends ModuleNews
  20. {
  21.     /**
  22.      * Template
  23.      * @var string
  24.      */
  25.     protected $strTemplate 'mod_newslist';
  26.     /**
  27.      * Display a wildcard in the back end
  28.      *
  29.      * @return string
  30.      */
  31.     public function generate()
  32.     {
  33.         $request System::getContainer()->get('request_stack')->getCurrentRequest();
  34.         if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  35.         {
  36.             $objTemplate = new BackendTemplate('be_wildcard');
  37.             $objTemplate->wildcard '### ' $GLOBALS['TL_LANG']['FMD']['newslist'][0] . ' ###';
  38.             $objTemplate->title $this->headline;
  39.             $objTemplate->id $this->id;
  40.             $objTemplate->link $this->name;
  41.             $objTemplate->href StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', array('do'=>'themes''table'=>'tl_module''act'=>'edit''id'=>$this->id)));
  42.             return $objTemplate->parse();
  43.         }
  44.         $this->news_archives $this->sortOutProtected(StringUtil::deserialize($this->news_archives));
  45.         // Return if there are no archives
  46.         if (empty($this->news_archives) || !\is_array($this->news_archives))
  47.         {
  48.             return '';
  49.         }
  50.         // Show the news reader if an item has been selected
  51.         if ($this->news_readerModule && (isset($_GET['items']) || (Config::get('useAutoItem') && isset($_GET['auto_item']))))
  52.         {
  53.             return $this->getFrontendModule($this->news_readerModule$this->strColumn);
  54.         }
  55.         // Tag the news archives (see #2137)
  56.         if (System::getContainer()->has('fos_http_cache.http.symfony_response_tagger'))
  57.         {
  58.             $responseTagger System::getContainer()->get('fos_http_cache.http.symfony_response_tagger');
  59.             $responseTagger->addTags(array_map(static function ($id) { return 'contao.db.tl_news_archive.' $id; }, $this->news_archives));
  60.         }
  61.         return parent::generate();
  62.     }
  63.     /**
  64.      * Generate the module
  65.      */
  66.     protected function compile()
  67.     {
  68.         $limit null;
  69.         $offset = (int) $this->skipFirst;
  70.         // Maximum number of items
  71.         if ($this->numberOfItems 0)
  72.         {
  73.             $limit $this->numberOfItems;
  74.         }
  75.         // Handle featured news
  76.         if ($this->news_featured == 'featured')
  77.         {
  78.             $blnFeatured true;
  79.         }
  80.         elseif ($this->news_featured == 'unfeatured')
  81.         {
  82.             $blnFeatured false;
  83.         }
  84.         else
  85.         {
  86.             $blnFeatured null;
  87.         }
  88.         $this->Template->articles = array();
  89.         $this->Template->empty $GLOBALS['TL_LANG']['MSC']['emptyList'];
  90.         // Get the total number of items
  91.         $intTotal $this->countItems($this->news_archives$blnFeatured);
  92.         if ($intTotal 1)
  93.         {
  94.             return;
  95.         }
  96.         $total $intTotal $offset;
  97.         // Split the results
  98.         if ($this->perPage && (!isset($limit) || $this->numberOfItems $this->perPage))
  99.         {
  100.             // Adjust the overall limit
  101.             if (isset($limit))
  102.             {
  103.                 $total min($limit$total);
  104.             }
  105.             // Get the current page
  106.             $id 'page_n' $this->id;
  107.             $page Input::get($id) ?? 1;
  108.             // Do not index or cache the page if the page number is outside the range
  109.             if ($page || $page max(ceil($total/$this->perPage), 1))
  110.             {
  111.                 throw new PageNotFoundException('Page not found: ' Environment::get('uri'));
  112.             }
  113.             // Set limit and offset
  114.             $limit $this->perPage;
  115.             $offset += (max($page1) - 1) * $this->perPage;
  116.             $skip = (int) $this->skipFirst;
  117.             // Overall limit
  118.             if ($offset $limit $total $skip)
  119.             {
  120.                 $limit $total $skip $offset;
  121.             }
  122.             // Add the pagination menu
  123.             $objPagination = new Pagination($total$this->perPageConfig::get('maxPaginationLinks'), $id);
  124.             $this->Template->pagination $objPagination->generate("\n  ");
  125.         }
  126.         $objArticles $this->fetchItems($this->news_archives$blnFeatured, ($limit ?: 0), $offset);
  127.         // Add the articles
  128.         if ($objArticles !== null)
  129.         {
  130.             $this->Template->articles $this->parseArticles($objArticles);
  131.         }
  132.         $this->Template->archives $this->news_archives;
  133.     }
  134.     /**
  135.      * Count the total matching items
  136.      *
  137.      * @param array   $newsArchives
  138.      * @param boolean $blnFeatured
  139.      *
  140.      * @return integer
  141.      */
  142.     protected function countItems($newsArchives$blnFeatured)
  143.     {
  144.         // HOOK: add custom logic
  145.         if (isset($GLOBALS['TL_HOOKS']['newsListCountItems']) && \is_array($GLOBALS['TL_HOOKS']['newsListCountItems']))
  146.         {
  147.             foreach ($GLOBALS['TL_HOOKS']['newsListCountItems'] as $callback)
  148.             {
  149.                 if (($intResult System::importStatic($callback[0])->{$callback[1]}($newsArchives$blnFeatured$this)) === false)
  150.                 {
  151.                     continue;
  152.                 }
  153.                 if (\is_int($intResult))
  154.                 {
  155.                     return $intResult;
  156.                 }
  157.             }
  158.         }
  159.         return NewsModel::countPublishedByPids($newsArchives$blnFeatured);
  160.     }
  161.     /**
  162.      * Fetch the matching items
  163.      *
  164.      * @param array   $newsArchives
  165.      * @param boolean $blnFeatured
  166.      * @param integer $limit
  167.      * @param integer $offset
  168.      *
  169.      * @return Collection|NewsModel|null
  170.      */
  171.     protected function fetchItems($newsArchives$blnFeatured$limit$offset)
  172.     {
  173.         // HOOK: add custom logic
  174.         if (isset($GLOBALS['TL_HOOKS']['newsListFetchItems']) && \is_array($GLOBALS['TL_HOOKS']['newsListFetchItems']))
  175.         {
  176.             foreach ($GLOBALS['TL_HOOKS']['newsListFetchItems'] as $callback)
  177.             {
  178.                 if (($objCollection System::importStatic($callback[0])->{$callback[1]}($newsArchives$blnFeatured$limit$offset$this)) === false)
  179.                 {
  180.                     continue;
  181.                 }
  182.                 if ($objCollection === null || $objCollection instanceof Collection)
  183.                 {
  184.                     return $objCollection;
  185.                 }
  186.             }
  187.         }
  188.         // Determine sorting
  189.         $t NewsModel::getTable();
  190.         $order '';
  191.         if ($this->news_featured == 'featured_first')
  192.         {
  193.             $order .= "$t.featured DESC, ";
  194.         }
  195.         switch ($this->news_order)
  196.         {
  197.             case 'order_headline_asc':
  198.                 $order .= "$t.headline";
  199.                 break;
  200.             case 'order_headline_desc':
  201.                 $order .= "$t.headline DESC";
  202.                 break;
  203.             case 'order_random':
  204.                 $order .= "RAND()";
  205.                 break;
  206.             case 'order_date_asc':
  207.                 $order .= "$t.date";
  208.                 break;
  209.             default:
  210.                 $order .= "$t.date DESC";
  211.         }
  212.         return NewsModel::findPublishedByPids($newsArchives$blnFeatured$limit$offset, array('order'=>$order));
  213.     }
  214. }
  215. class_alias(ModuleNewsList::class, 'ModuleNewsList');