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

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