vendor/contao/faq-bundle/src/Resources/contao/modules/ModuleFaqList.php line 153

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. /**
  11. * Class ModuleFaqList
  12. *
  13. * @property array $faq_categories
  14. * @property int $faq_readerModule
  15. */
  16. class ModuleFaqList extends Module
  17. {
  18. /**
  19. * Template
  20. * @var string
  21. */
  22. protected $strTemplate = 'mod_faqlist';
  23. /**
  24. * Target pages
  25. * @var array
  26. */
  27. protected $arrTargets = array();
  28. /**
  29. * Display a wildcard in the back end
  30. *
  31. * @return string
  32. */
  33. public function generate()
  34. {
  35. $request = System::getContainer()->get('request_stack')->getCurrentRequest();
  36. if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  37. {
  38. $objTemplate = new BackendTemplate('be_wildcard');
  39. $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['faqlist'][0] . ' ###';
  40. $objTemplate->title = $this->headline;
  41. $objTemplate->id = $this->id;
  42. $objTemplate->link = $this->name;
  43. $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', array('do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id)));
  44. return $objTemplate->parse();
  45. }
  46. $this->faq_categories = StringUtil::deserialize($this->faq_categories);
  47. // Return if there are no categories
  48. if (empty($this->faq_categories) || !\is_array($this->faq_categories))
  49. {
  50. return '';
  51. }
  52. // Show the FAQ reader if an item has been selected
  53. if ($this->faq_readerModule > 0 && (isset($_GET['items']) || (Config::get('useAutoItem') && isset($_GET['auto_item']))))
  54. {
  55. return $this->getFrontendModule($this->faq_readerModule, $this->strColumn);
  56. }
  57. // Tag the FAQ categories (see #2137)
  58. if (System::getContainer()->has('fos_http_cache.http.symfony_response_tagger'))
  59. {
  60. $responseTagger = System::getContainer()->get('fos_http_cache.http.symfony_response_tagger');
  61. $responseTagger->addTags(array_map(static function ($id) { return 'contao.db.tl_faq_category.' . $id; }, $this->faq_categories));
  62. }
  63. return parent::generate();
  64. }
  65. /**
  66. * Generate the module
  67. */
  68. protected function compile()
  69. {
  70. $objFaq = FaqModel::findPublishedByPids($this->faq_categories);
  71. if ($objFaq === null)
  72. {
  73. $this->Template->faq = array();
  74. return;
  75. }
  76. $tags = array();
  77. $arrFaq = array_fill_keys($this->faq_categories, array());
  78. // Add FAQs
  79. while ($objFaq->next())
  80. {
  81. $arrTemp = $objFaq->row();
  82. $arrTemp['title'] = StringUtil::specialchars($objFaq->question, true);
  83. $arrTemp['href'] = $this->generateFaqLink($objFaq);
  84. /** @var FaqCategoryModel $objPid */
  85. $objPid = $objFaq->getRelated('pid');
  86. if (empty($arrFaq[$objFaq->pid]))
  87. {
  88. $arrFaq[$objFaq->pid] = $objPid->row();
  89. }
  90. $arrFaq[$objFaq->pid]['items'][] = $arrTemp;
  91. $tags[] = 'contao.db.tl_faq.' . $objFaq->id;
  92. }
  93. // Tag the FAQs (see #2137)
  94. if (System::getContainer()->has('fos_http_cache.http.symfony_response_tagger'))
  95. {
  96. $responseTagger = System::getContainer()->get('fos_http_cache.http.symfony_response_tagger');
  97. $responseTagger->addTags($tags);
  98. }
  99. $arrFaq = array_values(array_filter($arrFaq));
  100. $cat_count = 0;
  101. $cat_limit = \count($arrFaq);
  102. // Add classes
  103. foreach ($arrFaq as $k=>$v)
  104. {
  105. $count = 0;
  106. $limit = \count($v['items']);
  107. for ($i=0; $i<$limit; $i++)
  108. {
  109. $arrFaq[$k]['items'][$i]['class'] = trim(((++$count == 1) ? ' first' : '') . (($count >= $limit) ? ' last' : '') . ((($count % 2) == 0) ? ' odd' : ' even'));
  110. }
  111. $arrFaq[$k]['class'] = trim(((++$cat_count == 1) ? ' first' : '') . (($cat_count >= $cat_limit) ? ' last' : '') . ((($cat_count % 2) == 0) ? ' odd' : ' even'));
  112. }
  113. $this->Template->faq = $arrFaq;
  114. }
  115. /**
  116. * Create links and remember pages that have been processed
  117. *
  118. * @param FaqModel $objFaq
  119. *
  120. * @return string
  121. *
  122. * @throws \Exception
  123. */
  124. protected function generateFaqLink($objFaq)
  125. {
  126. /** @var FaqCategoryModel $objCategory */
  127. $objCategory = $objFaq->getRelated('pid');
  128. $jumpTo = (int) $objCategory->jumpTo;
  129. // A jumpTo page is not mandatory for FAQ categories (see #6226) but required for the FAQ list module
  130. if ($jumpTo < 1)
  131. {
  132. throw new \Exception("FAQ categories without redirect page cannot be used in an FAQ list");
  133. }
  134. // Get the URL from the jumpTo page of the category
  135. if (!isset($this->arrTargets[$jumpTo]))
  136. {
  137. $this->arrTargets[$jumpTo] = StringUtil::ampersand(Environment::get('request'));
  138. if ($jumpTo > 0 && ($objTarget = PageModel::findByPk($jumpTo)) !== null)
  139. {
  140. /** @var PageModel $objTarget */
  141. $this->arrTargets[$jumpTo] = StringUtil::ampersand($objTarget->getFrontendUrl(Config::get('useAutoItem') ? '/%s' : '/items/%s'));
  142. }
  143. }
  144. return sprintf(preg_replace('/%(?!s)/', '%%', $this->arrTargets[$jumpTo]), ($objFaq->alias ?: $objFaq->id));
  145. }
  146. }
  147. class_alias(ModuleFaqList::class, 'ModuleFaqList');