PageRenderTime 36ms CodeModel.GetById 2ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/phpmyfaq/index.php

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