vendor/contao/faq-bundle/src/Resources/contao/modules/ModuleFaqReader.php line 37

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\InternalServerErrorException;
  11. use Contao\CoreBundle\Exception\PageNotFoundException;
  12. use Contao\CoreBundle\Routing\ResponseContext\HtmlHeadBag\HtmlHeadBag;
  13. /**
  14. * Class ModuleFaqReader
  15. *
  16. * @property Comments $Comments
  17. * @property string $com_template
  18. * @property array $faq_categories
  19. */
  20. class ModuleFaqReader extends Module
  21. {
  22. /**
  23. * Template
  24. * @var string
  25. */
  26. protected $strTemplate = 'mod_faqreader';
  27. /**
  28. * Display a wildcard in the back end
  29. *
  30. * @return string
  31. */
  32. public function generate()
  33. {
  34. $request = System::getContainer()->get('request_stack')->getCurrentRequest();
  35. if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  36. {
  37. $objTemplate = new BackendTemplate('be_wildcard');
  38. $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['faqreader'][0] . ' ###';
  39. $objTemplate->title = $this->headline;
  40. $objTemplate->id = $this->id;
  41. $objTemplate->link = $this->name;
  42. $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', array('do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id)));
  43. return $objTemplate->parse();
  44. }
  45. // Set the item from the auto_item parameter
  46. if (!isset($_GET['items']) && isset($_GET['auto_item']) && Config::get('useAutoItem'))
  47. {
  48. Input::setGet('items', Input::get('auto_item'));
  49. }
  50. // Return an empty string if "items" is not set (to combine list and reader on same page)
  51. if (!Input::get('items'))
  52. {
  53. return '';
  54. }
  55. $this->faq_categories = StringUtil::deserialize($this->faq_categories);
  56. if (empty($this->faq_categories) || !\is_array($this->faq_categories))
  57. {
  58. throw new InternalServerErrorException('The FAQ reader ID ' . $this->id . ' has no categories specified.');
  59. }
  60. return parent::generate();
  61. }
  62. /**
  63. * Generate the module
  64. */
  65. protected function compile()
  66. {
  67. /** @var PageModel $objPage */
  68. global $objPage;
  69. if ($this->overviewPage)
  70. {
  71. $this->Template->referer = PageModel::findById($this->overviewPage)->getFrontendUrl();
  72. $this->Template->back = $this->customLabel ?: $GLOBALS['TL_LANG']['MSC']['faqOverview'];
  73. }
  74. else
  75. {
  76. trigger_deprecation('contao/faq-bundle', '4.13', 'If you do not select an overview page in the FAQ reader module, the "go back" link will no longer be shown in Contao 5.0.');
  77. $this->Template->back = $GLOBALS['TL_LANG']['MSC']['goBack'];
  78. $this->Template->referer = 'javascript:history.go(-1)';
  79. }
  80. $objFaq = FaqModel::findPublishedByParentAndIdOrAlias(Input::get('items'), $this->faq_categories);
  81. if (null === $objFaq)
  82. {
  83. throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
  84. }
  85. // Add the FAQ record to the template (see #221)
  86. $this->Template->faq = $objFaq->row();
  87. // Overwrite the page metadata (see #2853, #4955 and #87)
  88. $responseContext = System::getContainer()->get('contao.routing.response_context_accessor')->getResponseContext();
  89. if ($responseContext && $responseContext->has(HtmlHeadBag::class))
  90. {
  91. /** @var HtmlHeadBag $htmlHeadBag */
  92. $htmlHeadBag = $responseContext->get(HtmlHeadBag::class);
  93. $htmlDecoder = System::getContainer()->get('contao.string.html_decoder');
  94. if ($objFaq->pageTitle)
  95. {
  96. $htmlHeadBag->setTitle($objFaq->pageTitle); // Already stored decoded
  97. }
  98. elseif ($objFaq->question)
  99. {
  100. $htmlHeadBag->setTitle($htmlDecoder->inputEncodedToPlainText($objFaq->question));
  101. }
  102. if ($objFaq->description)
  103. {
  104. $htmlHeadBag->setMetaDescription($htmlDecoder->inputEncodedToPlainText($objFaq->description));
  105. }
  106. elseif ($objFaq->question)
  107. {
  108. $htmlHeadBag->setMetaDescription($htmlDecoder->inputEncodedToPlainText($objFaq->question));
  109. }
  110. if ($objFaq->robots)
  111. {
  112. $htmlHeadBag->setMetaRobots($objFaq->robots);
  113. }
  114. }
  115. $this->Template->question = $objFaq->question;
  116. $this->Template->answer = StringUtil::encodeEmail($objFaq->answer);
  117. $this->Template->addImage = false;
  118. $this->Template->before = false;
  119. // Add image
  120. if ($objFaq->addImage)
  121. {
  122. $figure = System::getContainer()
  123. ->get('contao.image.studio')
  124. ->createFigureBuilder()
  125. ->from($objFaq->singleSRC)
  126. ->setSize($objFaq->size)
  127. ->setOverwriteMetadata($objFaq->getOverwriteMetadata())
  128. ->enableLightbox((bool) $objFaq->fullsize)
  129. ->buildIfResourceExists();
  130. if (null !== $figure)
  131. {
  132. $figure->applyLegacyTemplateData($this->Template, $objFaq->imagemargin, $objFaq->floating);
  133. }
  134. }
  135. $this->Template->enclosure = array();
  136. // Add enclosure
  137. if ($objFaq->addEnclosure)
  138. {
  139. $this->addEnclosuresToTemplate($this->Template, $objFaq->row());
  140. }
  141. $strAuthor = '';
  142. /** @var UserModel $objAuthor */
  143. if (($objAuthor = $objFaq->getRelated('author')) instanceof UserModel)
  144. {
  145. $strAuthor = $objAuthor->name;
  146. }
  147. $this->Template->info = sprintf($GLOBALS['TL_LANG']['MSC']['faqCreatedBy'], Date::parse($objPage->dateFormat, $objFaq->tstamp), $strAuthor);
  148. // Tag the FAQ (see #2137)
  149. if (System::getContainer()->has('fos_http_cache.http.symfony_response_tagger'))
  150. {
  151. $responseTagger = System::getContainer()->get('fos_http_cache.http.symfony_response_tagger');
  152. $responseTagger->addTags(array('contao.db.tl_faq.' . $objFaq->id));
  153. }
  154. // schema.org information
  155. $this->Template->getSchemaOrgData = static function () use ($objFaq)
  156. {
  157. return ModuleFaq::getSchemaOrgData(array($objFaq));
  158. };
  159. $bundles = System::getContainer()->getParameter('kernel.bundles');
  160. // HOOK: comments extension required
  161. if ($objFaq->noComments || !isset($bundles['ContaoCommentsBundle']))
  162. {
  163. $this->Template->allowComments = false;
  164. return;
  165. }
  166. /** @var FaqCategoryModel $objCategory */
  167. $objCategory = $objFaq->getRelated('pid');
  168. $this->Template->allowComments = $objCategory->allowComments;
  169. // Comments are not allowed
  170. if (!$objCategory->allowComments)
  171. {
  172. return;
  173. }
  174. // Adjust the comments headline level
  175. $intHl = min((int) str_replace('h', '', $this->hl), 5);
  176. $this->Template->hlc = 'h' . ($intHl + 1);
  177. $this->import(Comments::class, 'Comments');
  178. $arrNotifies = array();
  179. // Notify the system administrator
  180. if ($objCategory->notify != 'notify_author' && isset($GLOBALS['TL_ADMIN_EMAIL']))
  181. {
  182. $arrNotifies[] = $GLOBALS['TL_ADMIN_EMAIL'];
  183. }
  184. /** @var UserModel $objAuthor */
  185. if ($objCategory->notify != 'notify_admin' && ($objAuthor = $objFaq->getRelated('author')) instanceof UserModel && $objAuthor->email)
  186. {
  187. $arrNotifies[] = $objAuthor->email;
  188. }
  189. $objConfig = new \stdClass();
  190. $objConfig->perPage = $objCategory->perPage;
  191. $objConfig->order = $objCategory->sortOrder;
  192. $objConfig->template = $this->com_template;
  193. $objConfig->requireLogin = $objCategory->requireLogin;
  194. $objConfig->disableCaptcha = $objCategory->disableCaptcha;
  195. $objConfig->bbcode = $objCategory->bbcode;
  196. $objConfig->moderate = $objCategory->moderate;
  197. $this->Comments->addCommentsToTemplate($this->Template, $objConfig, 'tl_faq', $objFaq->id, $arrNotifies);
  198. }
  199. }
  200. class_alias(ModuleFaqReader::class, 'ModuleFaqReader');