PageRenderTime 70ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/phpmyfaq/index.php

http://github.com/thorsten/phpMyFAQ
PHP | 769 lines | 568 code | 62 blank | 139 comment | 123 complexity | 36518cff4169a7b1b85a0f619a718c0b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /**
  3. * This is the main public frontend page of phpMyFAQ. It detects the browser's
  4. * language, gets and sets all cookie, post and get information and includes
  5. * the templates we need and set all internal variables to the template
  6. * variables. That's all.
  7. *
  8. * This Source Code Form is subject to the terms of the Mozilla Public License,
  9. * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  10. * obtain one at http://mozilla.org/MPL/2.0/.
  11. *
  12. * @package phpMyFAQ
  13. * @author Thorsten Rinne <thorsten@phpmyfaq.de>
  14. * @author Lars Tiedemann <php@larstiedemann.de>
  15. * @author Matteo Scaramuccia <matteo@phpmyfaq.de>
  16. * @copyright 2001-2021 phpMyFAQ Team
  17. * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
  18. * @link https://www.phpmyfaq.de
  19. * @since 2001-02-12
  20. */
  21. use phpMyFAQ\Attachment\AttachmentFactory;
  22. use phpMyFAQ\Auth\AuthLdap as AuthLdap;
  23. use phpMyFAQ\Auth\AuthSso as AuthSso;
  24. use phpMyFAQ\Category;
  25. use phpMyFAQ\Category\CategoryRelation;
  26. use phpMyFAQ\Core\Exception;
  27. use phpMyFAQ\Faq;
  28. use phpMyFAQ\Filter;
  29. use phpMyFAQ\Helper\CategoryHelper as HelperCategory;
  30. use phpMyFAQ\Helper\HttpHelper as HelperHttp;
  31. use phpMyFAQ\Helper\LanguageHelper;
  32. use phpMyFAQ\Language;
  33. use phpMyFAQ\Language\Plurals;
  34. use phpMyFAQ\Link;
  35. use phpMyFAQ\Permission\MediumPermission;
  36. use phpMyFAQ\Seo;
  37. use phpMyFAQ\Session;
  38. use phpMyFAQ\Strings;
  39. use phpMyFAQ\System;
  40. use phpMyFAQ\Tags;
  41. use phpMyFAQ\Template;
  42. use phpMyFAQ\Template\TemplateHelper;
  43. use phpMyFAQ\User\CurrentUser;
  44. use phpMyFAQ\Utils;
  45. //
  46. // Define the named constant used as a check by any included PHP file
  47. //
  48. const IS_VALID_PHPMYFAQ = null;
  49. //
  50. // Bootstrapping
  51. //
  52. require __DIR__ . '/src/Bootstrap.php';
  53. //
  54. // HTTP Helper
  55. //
  56. $http = new HelperHttp();
  57. //
  58. // Get language (default: english)
  59. //
  60. $Language = new Language($faqConfig);
  61. $faqLangCode = $Language->setLanguage($faqConfig->get('main.languageDetection'), $faqConfig->get('main.language'));
  62. // Preload English strings
  63. require_once 'lang/language_en.php';
  64. $faqConfig->setLanguage($Language);
  65. $showCaptcha = Filter::filterInput(INPUT_GET, 'gen', FILTER_UNSAFE_RAW);
  66. if (isset($faqLangCode) && Language::isASupportedLanguage($faqLangCode) && is_null($showCaptcha)) {
  67. // Overwrite English strings with the ones we have in the current language,
  68. // but don't include UTF-8 encoded files, these will break the captcha images
  69. if (!file_exists('lang/language_' . $faqLangCode . '.php')) {
  70. $faqLangCode = 'en';
  71. }
  72. require_once 'lang/language_' . $faqLangCode . '.php';
  73. } else {
  74. $faqLangCode = 'en';
  75. }
  76. //Load plurals support for selected language
  77. $plr = new Plurals($PMF_LANG);
  78. //
  79. // Initializing static string wrapper
  80. //
  81. Strings::init($faqLangCode);
  82. /*
  83. * Initialize attachment factory
  84. */
  85. AttachmentFactory::init(
  86. $faqConfig->get('records.attachmentsStorageType'),
  87. $faqConfig->get('records.defaultAttachmentEncKey'),
  88. $faqConfig->get('records.enableAttachmentEncryption')
  89. );
  90. //
  91. // Get user action
  92. //
  93. $action = Filter::filterInput(INPUT_GET, 'action', FILTER_UNSAFE_RAW);
  94. //
  95. // Authenticate current user
  96. //
  97. $auth = $error = null;
  98. $loginVisibility = 'hidden';
  99. $faqusername = Filter::filterInput(INPUT_POST, 'faqusername', FILTER_UNSAFE_RAW);
  100. $faqpassword = Filter::filterInput(INPUT_POST, 'faqpassword', FILTER_UNSAFE_RAW, FILTER_FLAG_NO_ENCODE_QUOTES);
  101. $faqaction = Filter::filterInput(INPUT_POST, 'faqloginaction', FILTER_UNSAFE_RAW);
  102. $rememberMe = Filter::filterInput(INPUT_POST, 'faqrememberme', FILTER_UNSAFE_RAW);
  103. // Set username via SSO
  104. if ($faqConfig->get('security.ssoSupport') && isset($_SERVER['REMOTE_USER'])) {
  105. $faqusername = trim($_SERVER['REMOTE_USER']);
  106. $faqpassword = '';
  107. }
  108. // Login via local DB or LDAP or SSO
  109. if (!is_null($faqusername) && !is_null($faqpassword)) {
  110. $user = new CurrentUser($faqConfig);
  111. if (!is_null($rememberMe) && 'rememberMe' === $rememberMe) {
  112. $user->enableRememberMe();
  113. }
  114. if ($faqConfig->get('ldap.ldapSupport') && function_exists('ldap_connect')) {
  115. try {
  116. $authLdap = new AuthLdap($faqConfig);
  117. $user->addAuth($authLdap, 'ldap');
  118. } catch (Exception $e) {
  119. $error = $e->getMessage() . '<br>';
  120. }
  121. }
  122. if ($faqConfig->get('security.ssoSupport')) {
  123. $authSso = new AuthSso($faqConfig);
  124. $user->addAuth($authSso, 'sso');
  125. }
  126. if ($user->login($faqusername, $faqpassword)) {
  127. if ($user->getStatus() != 'blocked') {
  128. $auth = true;
  129. if (empty($action)) {
  130. $action = $faqaction; // SSO logins don't have $faqaction
  131. }
  132. } else {
  133. $error = $error . $PMF_LANG['ad_auth_fail'] . ' (' . $faqusername . ')';
  134. $loginVisibility = '';
  135. $action = 'password' === $action ? 'password' : 'login';
  136. }
  137. } else {
  138. // error
  139. $error = $error . $PMF_LANG['ad_auth_fail'];
  140. $loginVisibility = '';
  141. $action = 'password' === $action ? 'password' : 'login';
  142. }
  143. } else {
  144. // Try to authenticate with cookie information
  145. $user = CurrentUser::getFromCookie($faqConfig);
  146. // authenticate with session information
  147. if (!$user instanceof CurrentUser) {
  148. $user = CurrentUser::getFromSession($faqConfig);
  149. }
  150. if ($user instanceof CurrentUser) {
  151. $auth = true;
  152. } else {
  153. $user = new CurrentUser($faqConfig);
  154. }
  155. }
  156. //
  157. // Logout
  158. //
  159. if ('logout' === $action && isset($auth)) {
  160. $user->deleteFromSession(true);
  161. $auth = null;
  162. $action = 'main';
  163. $ssoLogout = $faqConfig->get('security.ssoLogoutRedirect');
  164. if ($faqConfig->get('security.ssoSupport') && !empty($ssoLogout)) {
  165. header('Location: ' . $ssoLogout);
  166. } else {
  167. header('Location: ' . $faqConfig->getDefaultUrl());
  168. }
  169. }
  170. //
  171. // Get current user and group id - default: -1
  172. //
  173. if (!is_null($user) && $user instanceof CurrentUser) {
  174. $currentUser = $user->getUserId();
  175. if ($user->perm instanceof MediumPermission) {
  176. $currentGroups = $user->perm->getUserGroups($currentUser);
  177. } else {
  178. $currentGroups = [-1];
  179. }
  180. if (0 == count($currentGroups)) {
  181. $currentGroups = [-1];
  182. }
  183. } else {
  184. $currentUser = -1;
  185. $currentGroups = [-1];
  186. }
  187. //
  188. // Use mbstring extension if available and when possible
  189. //
  190. $validMbStrings = ['ja', 'en', 'uni'];
  191. $mbLanguage = ($PMF_LANG['metaLanguage'] != 'ja') ? 'uni' : $PMF_LANG['metaLanguage'];
  192. if (function_exists('mb_language') && in_array($mbLanguage, $validMbStrings)) {
  193. mb_language($mbLanguage);
  194. mb_internal_encoding('utf-8');
  195. }
  196. //
  197. // Found a session ID in _GET or _COOKIE?
  198. //
  199. $sidGet = Filter::filterInput(INPUT_GET, PMF_GET_KEY_NAME_SESSIONID, FILTER_VALIDATE_INT);
  200. $sidCookie = Filter::filterInput(INPUT_COOKIE, Session::PMF_COOKIE_NAME_SESSIONID, FILTER_VALIDATE_INT);
  201. $faqSession = new Session($faqConfig);
  202. $faqSession->setCurrentUser($user);
  203. // Note: do not track internal calls
  204. $internal = false;
  205. if (isset($_SERVER['HTTP_USER_AGENT'])) {
  206. $internal = (strpos($_SERVER['HTTP_USER_AGENT'], 'phpMyFAQ%2F') === 0);
  207. }
  208. if (!$internal) {
  209. if (is_null($sidGet) && is_null($sidCookie)) {
  210. // Create a per-site unique SID
  211. try {
  212. $faqSession->userTracking('new_session', 0);
  213. } catch (Exception $e) {
  214. $pmfExceptions[] = $e->getMessage();
  215. }
  216. } elseif (!is_null($sidCookie)) {
  217. $faqSession->checkSessionId($sidCookie, $_SERVER['REMOTE_ADDR']);
  218. } else {
  219. $faqSession->checkSessionId($sidGet, $_SERVER['REMOTE_ADDR']);
  220. }
  221. }
  222. //
  223. // Is user tracking activated?
  224. //
  225. $sids = '';
  226. if ($faqConfig->get('main.enableUserTracking')) {
  227. if ($faqSession->getCurrentSessionId() > 0) {
  228. $faqSession->setCookie(Session::PMF_COOKIE_NAME_SESSIONID, $faqSession->getCurrentSessionId());
  229. if (is_null($sidCookie)) {
  230. $sids = sprintf('sid=%d&amp;lang=%s&amp;', $faqSession->getCurrentSessionId(), $faqLangCode);
  231. }
  232. } elseif (is_null($sidGet) || is_null($sidCookie)) {
  233. if (is_null($sidCookie)) {
  234. if (!is_null($sidGet)) {
  235. $sids = sprintf('sid=%d&amp;lang=%s&amp;', $sidGet, $faqLangCode);
  236. }
  237. }
  238. }
  239. } elseif (
  240. !$faqSession->setCookie(
  241. Session::PMF_COOKIE_NAME_SESSIONID,
  242. $faqSession->getCurrentSessionId(),
  243. $_SERVER['REQUEST_TIME'] + PMF_LANGUAGE_EXPIRED_TIME
  244. )
  245. ) {
  246. $sids = sprintf('lang=%s&amp;', $faqLangCode);
  247. }
  248. //
  249. // Found a article language?
  250. //
  251. $lang = Filter::filterInput(INPUT_POST, 'artlang', FILTER_UNSAFE_RAW);
  252. if (is_null($lang) && !Language::isASupportedLanguage($lang)) {
  253. $lang = Filter::filterInput(INPUT_GET, 'artlang', FILTER_UNSAFE_RAW);
  254. if (is_null($lang) && !Language::isASupportedLanguage($lang)) {
  255. $lang = $faqLangCode;
  256. }
  257. }
  258. //
  259. // Found a search string?
  260. //
  261. $searchTerm = Filter::filterInput(INPUT_GET, 'search', FILTER_UNSAFE_RAW);
  262. //
  263. // Create a new FAQ object
  264. //
  265. $faq = new Faq($faqConfig);
  266. $faq->setUser($currentUser)
  267. ->setGroups($currentGroups);
  268. //
  269. // Create a new Category object
  270. //
  271. $category = new Category($faqConfig, $currentGroups, true);
  272. $category->setUser($currentUser)
  273. ->setGroups($currentGroups);
  274. //
  275. // Create a new Tags object
  276. //
  277. $oTag = new Tags($faqConfig);
  278. //
  279. // Create URL
  280. //
  281. $faqSystem = new System();
  282. $faqLink = new Link($faqSystem->getSystemUri($faqConfig), $faqConfig);
  283. $currentPageUrl = $faqLink->getCurrentUrl();
  284. //
  285. // Found a record ID?
  286. //
  287. $id = Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT);
  288. if (!is_null($id)) {
  289. $faq->getRecord($id);
  290. $title = ' - ' . $faq->faqRecord['title'];
  291. $keywords = ',' . $faq->faqRecord['keywords'];
  292. $metaDescription = str_replace('"', '', strip_tags($faq->getRecordPreview($id)));
  293. $url = sprintf(
  294. '%sindex.php?%saction=faq&cat=%d&id=%d&artlang=%s',
  295. $faqConfig->getDefaultUrl(),
  296. $sids,
  297. $category->getCategoryIdFromFaq($id),
  298. $id,
  299. $lang
  300. );
  301. $faqLink = new Link($url, $faqConfig);
  302. $faqLink->itemTitle = $faq->faqRecord['title'];
  303. $currentPageUrl = $faqLink->toString(true);
  304. } else {
  305. $id = '';
  306. $title = ' - powered by phpMyFAQ ' . $faqConfig->getVersion();
  307. $keywords = '';
  308. $metaDescription = str_replace('"', '', $faqConfig->get('main.metaDescription'));
  309. }
  310. //
  311. // found a solution ID?
  312. //
  313. $solutionId = Filter::filterInput(INPUT_GET, 'solution_id', FILTER_VALIDATE_INT);
  314. if (!is_null($solutionId)) {
  315. $title = ' - powered by phpMyFAQ ' . $faqConfig->getVersion();
  316. $keywords = '';
  317. $faqData = $faq->getIdFromSolutionId($solutionId);
  318. if (is_array($faqData)) {
  319. $id = $faqData['id'];
  320. $lang = $faqData['lang'];
  321. $title = ' - ' . $faq->getRecordTitle($id);
  322. $keywords = ',' . $faq->getRecordKeywords($id);
  323. $metaDescription = str_replace('"', '', Utils::makeShorterText(strip_tags($faqData['content']), 12));
  324. $url = sprintf(
  325. '%sindex.php?%saction=faq&cat=%d&id=%d&artlang=%s',
  326. $faqConfig->getDefaultUrl(),
  327. $sids,
  328. $faqData['category_id'],
  329. $id,
  330. $lang
  331. );
  332. $faqLink = new Link($url, $faqConfig);
  333. $faqLink->itemTitle = $faqData['question'];
  334. $currentPageUrl = $faqLink->toString(true);
  335. }
  336. }
  337. //
  338. // Handle the Tagging ID
  339. //
  340. $tag_id = Filter::filterInput(INPUT_GET, 'tagging_id', FILTER_VALIDATE_INT);
  341. if (!is_null($tag_id)) {
  342. $title = ' - ' . $oTag->getTagNameById($tag_id);
  343. $keywords = '';
  344. }
  345. //
  346. // Handle the SiteMap
  347. //
  348. $letter = Filter::filterInput(INPUT_GET, 'letter', FILTER_UNSAFE_RAW);
  349. if (!is_null($letter) && (1 == Strings::strlen($letter))) {
  350. $title = ' - ' . $letter . '...';
  351. $keywords = $letter;
  352. }
  353. //
  354. // Found a category ID?
  355. //
  356. $cat = Filter::filterInput(INPUT_GET, 'cat', FILTER_VALIDATE_INT, 0);
  357. $categoryFromId = -1;
  358. if (is_numeric($id) && $id > 0) {
  359. $categoryFromId = $category->getCategoryIdFromFaq($id);
  360. }
  361. if ($categoryFromId != -1 && $cat == 0) {
  362. $cat = $categoryFromId;
  363. }
  364. $category->transform(0);
  365. $category->collapseAll();
  366. if ($cat != 0) {
  367. $category->expandTo($cat);
  368. }
  369. if (isset($cat) && ($cat != 0) && ($id == '') && isset($category->categoryName[$cat]['name'])) {
  370. $title = ' - ' . $category->categoryName[$cat]['name'];
  371. $metaDescription = $category->categoryName[$cat]['description'];
  372. }
  373. //
  374. // Found an action request?
  375. //
  376. if (!isset(Link::$allowedActionParameters[$action])) {
  377. $action = 'main';
  378. }
  379. //
  380. // Select the template for the requested page
  381. //
  382. if ($action !== 'main') {
  383. $includeTemplate = $action . '.html';
  384. $includePhp = $action . '.php';
  385. $renderUri = '?sid=' . $faqSession->getCurrentSessionId();
  386. } else {
  387. if (isset($solutionId) && is_numeric($solutionId)) {
  388. // show the record with the solution ID
  389. $includeTemplate = 'faq.html';
  390. $includePhp = 'faq.php';
  391. } else {
  392. $includeTemplate = 'startpage.html';
  393. $includePhp = 'startpage.php';
  394. }
  395. $renderUri = '?sid=' . $faqSession->getCurrentSessionId();
  396. }
  397. //
  398. // Set sidebar column
  399. //
  400. if (($action === 'faq') || ($action === 'show') || ($action === 'main')) {
  401. $sidebarTemplate = 'sidebar-tagcloud.html';
  402. } else {
  403. $sidebarTemplate = 'sidebar-empty.html';
  404. }
  405. //
  406. // Check if FAQ should be secured
  407. //
  408. if ($faqConfig->get('security.enableLoginOnly')) {
  409. if ($auth) {
  410. $indexSet = 'index.html';
  411. } else {
  412. switch ($action) {
  413. case 'register':
  414. case 'thankyou':
  415. $indexSet = 'new-user.page.html';
  416. break;
  417. case 'password':
  418. $indexSet = 'password.page.html';
  419. break;
  420. default:
  421. $indexSet = 'login.page.html';
  422. break;
  423. }
  424. }
  425. } else {
  426. $indexSet = 'index.html';
  427. }
  428. //
  429. // phpMyFAQ installation is in maintenance mode
  430. //
  431. if ($faqConfig->get('main.maintenanceMode')) {
  432. $indexSet = 'maintenance.page.html';
  433. }
  434. //
  435. // Load template files and set template variables
  436. //
  437. $template = new Template(
  438. [
  439. 'index' => $indexSet,
  440. 'sidebar' => $sidebarTemplate,
  441. 'mainPageContent' => $includeTemplate,
  442. ],
  443. new TemplateHelper($faqConfig),
  444. $faqConfig->get('main.templateSet')
  445. );
  446. $categoryRelation = new CategoryRelation($faqConfig);
  447. $categoryHelper = new HelperCategory();
  448. $categoryHelper->setCategory($category);
  449. $categoryHelper->setConfiguration($faqConfig);
  450. $categoryHelper->setCategoryRelation($categoryRelation);
  451. $keywordsArray = array_merge(explode(',', $keywords), explode(',', $faqConfig->get('main.metaKeywords')));
  452. $keywordsArray = array_filter($keywordsArray, 'strlen');
  453. shuffle($keywordsArray);
  454. $keywords = implode(',', $keywordsArray);
  455. if (!is_null($error)) {
  456. $loginMessage = '<p class="error">' . $error . '</p>';
  457. } else {
  458. $loginMessage = '';
  459. }
  460. $faqSeo = new Seo($faqConfig);
  461. $tplMainPage = [
  462. 'msgLoginUser' => $user->isLoggedIn() ? $user->getUserData('display_name') : $PMF_LANG['msgLoginUser'],
  463. 'title' => Strings::htmlspecialchars($faqConfig->getTitle() . $title),
  464. 'baseHref' => $faqSystem->getSystemUri($faqConfig),
  465. 'version' => $faqConfig->getVersion(),
  466. 'header' => Strings::htmlspecialchars(str_replace('"', '', $faqConfig->getTitle())),
  467. 'metaTitle' => Strings::htmlspecialchars(str_replace('"', '', $faqConfig->getTitle() . $title)),
  468. 'metaDescription' => Strings::htmlspecialchars($metaDescription),
  469. 'metaKeywords' => Strings::htmlspecialchars($keywords),
  470. 'metaPublisher' => $faqConfig->get('main.metaPublisher'),
  471. 'metaLanguage' => $PMF_LANG['metaLanguage'],
  472. 'metaRobots' => $faqSeo->getMetaRobots($action),
  473. 'phpmyfaqversion' => $faqConfig->getVersion(),
  474. 'stylesheet' => $PMF_LANG['dir'] == 'rtl' ? 'style.rtl' : 'style',
  475. 'currentPageUrl' => $currentPageUrl,
  476. 'action' => $action,
  477. 'dir' => $PMF_LANG['dir'],
  478. 'writeSendAdress' => '?' . $sids . 'action=search',
  479. 'searchBox' => $PMF_LANG['msgSearch'],
  480. 'searchTerm' => $searchTerm,
  481. 'categoryId' => ($cat === 0) ? '%' : (int)$cat,
  482. 'headerCategories' => $PMF_LANG['msgFullCategories'],
  483. 'msgCategory' => $PMF_LANG['msgCategory'],
  484. 'showCategories' => $categoryHelper->renderNavigation($cat),
  485. 'topCategories' => $categoryHelper->renderMainCategories(),
  486. 'msgExportAllFaqs' => $PMF_LANG['msgExportAllFaqs'],
  487. 'languageBox' => $PMF_LANG['msgLanguageSubmit'],
  488. 'renderUri' => $renderUri,
  489. 'switchLanguages' => LanguageHelper::renderSelectLanguage($faqLangCode, true),
  490. 'copyright' => 'powered with ❤️ and ☕️ by <a href="https://www.phpmyfaq.de" target="_blank">phpMyFAQ</a> ' .
  491. $faqConfig->getVersion(),
  492. 'registerUser' => $faqConfig->get('security.enableRegistration') ? '<a href="?action=register">' .
  493. $PMF_LANG['msgRegistration'] . '</a>' : '',
  494. 'sendPassword' => '<a href="?action=password">' . $PMF_LANG['lostPassword'] . '</a>',
  495. 'msgFullName' => $PMF_LANG['ad_user_loggedin'] . $user->getLogin(),
  496. 'msgLoginName' => $user->getUserData('display_name'),
  497. 'loginHeader' => $PMF_LANG['msgLoginUser'],
  498. 'loginMessage' => $loginMessage,
  499. 'writeLoginPath' => $faqSystem->getSystemUri($faqConfig) . '?' . Filter::getFilteredQueryString(),
  500. 'faqloginaction' => $action,
  501. 'login' => $PMF_LANG['ad_auth_ok'],
  502. 'username' => $PMF_LANG['ad_auth_user'],
  503. 'password' => $PMF_LANG['ad_auth_passwd'],
  504. 'rememberMe' => $PMF_LANG['rememberMe'],
  505. 'headerChangePassword' => $PMF_LANG['ad_passwd_cop'],
  506. 'msgUsername' => $PMF_LANG['ad_auth_user'],
  507. 'msgEmail' => $PMF_LANG['ad_entry_email'],
  508. 'msgSubmit' => $PMF_LANG['msgNewContentSubmit'],
  509. 'loginPageMessage' => $PMF_LANG['loginPageMessage'],
  510. 'msgAdvancedSearch' => $PMF_LANG['msgAdvancedSearch']
  511. ];
  512. $template->parseBlock(
  513. 'index',
  514. 'categoryListSection',
  515. [
  516. 'showCategories' => $categoryHelper->renderNavigation($cat),
  517. 'categoryDropDown' => $categoryHelper->renderCategoryDropDown(),
  518. ]
  519. );
  520. if ('main' == $action || 'show' == $action) {
  521. $template->parseBlock(
  522. 'index',
  523. 'globalSearchBox',
  524. [
  525. 'writeSendAdress' => '?' . $sids . 'action=search',
  526. 'searchBox' => $PMF_LANG['msgSearch'],
  527. 'categoryId' => ($cat === 0) ? '%' : (int)$cat,
  528. 'msgSearch' => sprintf(
  529. '<a class="help" href="./index.php?action=search">%s</a>',
  530. $PMF_LANG['msgAdvancedSearch']
  531. ),
  532. ]
  533. );
  534. }
  535. if ($faqConfig->get('main.enableRewriteRules')) {
  536. $tplNavigation = [
  537. 'msgSearch' => '<a class="nav-link" href="./search.html">' . $PMF_LANG['msgAdvancedSearch'] . '</a>',
  538. 'msgAddContent' => '<a class="nav-link" href="' . $faqSystem->getSystemUri($faqConfig) . 'addcontent.html">' .
  539. $PMF_LANG['msgAddContent'] . '</a>',
  540. 'msgQuestion' => '<a class="nav-link" href="./ask.html">' . $PMF_LANG['msgQuestion'] . '</a>',
  541. 'msgOpenQuestions' => '<a class="nav-link" href="./open-questions.html">' . $PMF_LANG['msgOpenQuestions'] .
  542. '</a>',
  543. 'msgContact' => '<a href="./contact.html">' . $PMF_LANG['msgContact'] . '</a>',
  544. 'msgGlossary' => '<a href="./glossary.html">' . $PMF_LANG['ad_menu_glossary'] . '</a>',
  545. 'privacyLink' => sprintf(
  546. '<a target="_blank" href="%s">%s</a>',
  547. $faqConfig->get('main.privacyURL'),
  548. $PMF_LANG['msgPrivacyNote']
  549. ),
  550. 'backToHome' => '<a href="./index.html">' . $PMF_LANG['msgHome'] . '</a>',
  551. 'allCategories' => '<a class="nav-link" href="./showcat.html">' . $PMF_LANG['msgShowAllCategories'] . '</a>',
  552. 'faqOverview' => '<a href="./overview.html">' . $PMF_LANG['faqOverview'] . '</a>',
  553. 'showSitemap' => '<a href="./sitemap/A/' . $faqLangCode . '.html">' . $PMF_LANG['msgSitemap'] . '</a>',
  554. 'msgUserRemoval' => '<a href="./request-removal.html">' . $PMF_LANG['msgUserRemoval'] . '</a>'
  555. ];
  556. } else {
  557. $tplNavigation = [
  558. 'msgSearch' => '<a class="nav-link" href="index.php?' . $sids . 'action=search">' .
  559. $PMF_LANG['msgAdvancedSearch'] . '</a>',
  560. 'msgAddContent' => '<a class="nav-link" href="index.php?' . $sids . 'action=add&cat=' . $cat . '">' .
  561. $PMF_LANG['msgAddContent'] . '</a>',
  562. 'msgQuestion' => '<a class="nav-link" href="index.php?' . $sids . 'action=ask&category_id=' . $cat . '">' .
  563. $PMF_LANG['msgQuestion'] . '</a>',
  564. 'msgOpenQuestions' => '<a class="nav-link" href="index.php?' . $sids . 'action=open-questions">' .
  565. $PMF_LANG['msgOpenQuestions'] . '</a>',
  566. 'msgContact' => '<a href="index.php?' . $sids . 'action=contact">' . $PMF_LANG['msgContact'] . '</a>',
  567. 'msgGlossary' => '<a href="index.php?' . $sids . 'action=glossary">' . $PMF_LANG['ad_menu_glossary'] . '</a>',
  568. 'privacyLink' => sprintf(
  569. '<a target="_blank" href="%s">%s</a>',
  570. $faqConfig->get('main.privacyURL'),
  571. $PMF_LANG['msgPrivacyNote']
  572. ),
  573. 'allCategories' => '<a class="nav-link" href="index.php?' . $sids . 'action=show">' .
  574. $PMF_LANG['msgShowAllCategories'] . '</a>',
  575. 'faqOverview' => '<a href="index.php?' . $sids . 'action=overview">' . $PMF_LANG['faqOverview'] . '</a>',
  576. 'backToHome' => '<a href="index.php?' . $sids . '">' . $PMF_LANG['msgHome'] . '</a>',
  577. 'showSitemap' => '<a href="index.php?' . $sids . 'action=sitemap&amp;lang=' . $faqLangCode . '">' .
  578. $PMF_LANG['msgSitemap'] . '</a>',
  579. 'msgUserRemoval' => '<a href="index.php?' . $sids . 'action=request-removal">' . $PMF_LANG['msgUserRemoval'] .
  580. '</a>',
  581. ];
  582. }
  583. $tplNavigation['faqHome'] = $faqConfig->getDefaultUrl();
  584. $tplNavigation['activeSearch'] = ('search' == $action) ? 'active' : '';
  585. $tplNavigation['activeAllCategories'] = ('show' == $action) ? 'active' : '';
  586. $tplNavigation['activeAddContent'] = ('add' == $action) ? 'active' : '';
  587. $tplNavigation['activeAddQuestion'] = ('ask' == $action) ? 'active' : '';
  588. $tplNavigation['activeOpenQuestions'] = ('open-questions' == $action) ? 'active' : '';
  589. $tplNavigation['activeLogin'] = ('login' == $action) ? 'active' : '';
  590. //
  591. // Show login box or logged-in user information
  592. //
  593. if (isset($auth)) {
  594. if ($user->perm->hasPermission($user->getUserId(), 'viewadminlink') || $user->isSuperAdmin()) {
  595. $adminSection = sprintf(
  596. '<a class="dropdown-item" href="./admin/index.php">%s</a>',
  597. $PMF_LANG['adminSection']
  598. );
  599. } else {
  600. $adminSection = '';
  601. }
  602. if ($faqConfig->get('ldap.ldapSupport')) {
  603. $userControlDropdown = '';
  604. } else {
  605. $userControlDropdown = '<a class="dropdown-item" href="?action=ucp">' . $PMF_LANG['headerUserControlPanel'] .
  606. '</a>';
  607. }
  608. $template->parseBlock(
  609. 'index',
  610. 'userloggedIn',
  611. [
  612. 'msgUserControl' => $adminSection,
  613. 'msgLoginName' => $user->getUserData('display_name'), // @deprecated
  614. 'msgUserControlDropDown' => $userControlDropdown,
  615. 'msgUserRemoval' => '<a class="dropdown-item" href="?action=request-removal">' .
  616. $PMF_LANG['ad_menu_RequestRemove'] . '</a>',
  617. 'msgLogoutUser' => '<a class="dropdown-item" href="?action=logout">' . $PMF_LANG['ad_menu_logout'] . '</a>',
  618. 'activeUserControl' => ('ucp' == $action) ? 'active' : ''
  619. ]
  620. );
  621. } else {
  622. if ($faqConfig->get('main.maintenanceMode')) {
  623. $msgLoginUser = '<a class="dropdown-item" href="./admin/">%s</a>';
  624. } else {
  625. $msgLoginUser = '<a class="dropdown-item" href="?action=login">%s</a>';
  626. }
  627. $template->parseBlock(
  628. 'index',
  629. 'notLoggedIn',
  630. [
  631. 'msgRegisterUser' => $faqConfig->get('security.enableRegistration')
  632. ?
  633. '<a class="dropdown-item" href="?action=register">' . $PMF_LANG['msgRegisterUser'] . '</a>'
  634. :
  635. '',
  636. 'msgLoginUser' => sprintf($msgLoginUser, $PMF_LANG['msgLoginUser']),
  637. 'activeRegister' => ('register' == $action) ? 'active' : '',
  638. 'activeLogin' => ('login' == $action) ? 'active' : '',
  639. ]
  640. );
  641. }
  642. $template->parse(
  643. 'sidebar',
  644. [
  645. 'writeTagCloudHeader' => $PMF_LANG['msg_tags'],
  646. 'writeTags' => $oTag->renderTagCloud(),
  647. 'msgAllCatArticles' => $PMF_LANG['msgAllCatArticles'],
  648. 'allCatArticles' => $faq->getRecordsWithoutPagingByCategoryId($cat)
  649. ]
  650. );
  651. if (DEBUG) {
  652. $template->parseBlock(
  653. 'index',
  654. 'debugMode',
  655. [
  656. 'debugQueries' => $faqConfig->getDb()->log(),
  657. ]
  658. );
  659. }
  660. //
  661. // Redirect old "action=artikel" URLs via 301 to new location
  662. //
  663. if ('artikel' === $action) {
  664. $url = sprintf(
  665. '%sindex.php?action=faq&cat=%d&id=%d&artlang=%s',
  666. $faqConfig->getDefaultUrl(),
  667. $category->getCategoryIdFromFaq($id),
  668. $id,
  669. $lang
  670. );
  671. $http->setStatus(301);
  672. $http->redirect($url);
  673. exit();
  674. }
  675. //
  676. // Include requested PHP file
  677. //
  678. require $includePhp;
  679. //
  680. // Get main template, set main variables
  681. //
  682. $template->parse('index', array_merge($tplMainPage, $tplNavigation));
  683. $template->merge('sidebar', 'index');
  684. $template->merge('mainPageContent', 'index');
  685. //
  686. // Send headers and print template
  687. //
  688. $http->setConfiguration($faqConfig);
  689. $http->setContentType('text/html');
  690. $http->addHeader();
  691. $http->startCompression();
  692. //
  693. // Check for 404 HTTP status code
  694. //
  695. if ($http->getStatusCode() === 404 || $action === '404') {
  696. $template = new Template(
  697. [
  698. 'index' => '404.html',
  699. 'mainPageContent' => ''
  700. ],
  701. new TemplateHelper($faqConfig),
  702. $faqConfig->get('main.templateSet')
  703. );
  704. $template->parse('index', array_merge($tplMainPage, $tplNavigation));
  705. }
  706. $template->render();
  707. $faqConfig->getDb()->close();