2 declare(strict_types
=1);
4 use wcf\acp\form\MasterPasswordForm
;
5 use wcf\acp\form\MasterPasswordInitForm
;
6 use wcf\data\menu\Menu
;
7 use wcf\data\menu\MenuCache
;
8 use wcf\system\application\ApplicationHandler
;
9 use wcf\system\cache\builder\ACPSearchProviderCacheBuilder
;
10 use wcf\system\event\EventHandler
;
11 use wcf\system\exception\AJAXException
;
12 use wcf\system\exception\PermissionDeniedException
;
13 use wcf\system\exception\SystemException
;
14 use wcf\system\request\LinkHandler
;
15 use wcf\system\request\RouteHandler
;
16 use wcf\system\session\ACPSessionFactory
;
17 use wcf\system\session\SessionHandler
;
18 use wcf\system\template\ACPTemplateEngine
;
19 use wcf\util\FileUtil
;
20 use wcf\util\HeaderUtil
;
23 * Extends WCF class with functions for the ACP.
26 * @copyright 2001-2018 WoltLab GmbH
27 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
28 * @package WoltLabSuite\Core\System
30 class WCFACP
extends WCF
{
35 protected static $inRescueMode;
38 * URL to WCF within rescue mode
41 protected static $rescueModePageURL;
43 /** @noinspection PhpMissingParentConstructorInspection */
45 * Calls all init functions of the WCF and the WCFACP class.
47 public function __construct() {
48 // add autoload directory
49 self
::$autoloadDirectories['wcf'] = WCF_DIR
. 'lib/';
51 // define tmp directory
52 if (!defined('TMP_DIR')) define('TMP_DIR', FileUtil
::getTempFolder());
54 // start initialization
59 $this->initLanguage();
61 $this->initCronjobs();
62 $this->initCoreObjects();
64 // prevent application loading during setup
66 $this->initApplications();
69 $this->initBlacklist();
72 EventHandler
::getInstance()->fireAction($this, 'initialized');
76 * Returns the main menu object.
78 * @return Menu|null menu object
81 public function getFrontendMenu() {
82 return MenuCache
::getInstance()->getMainMenu();
86 * Returns true if ACP is currently in rescue mode.
90 public static function inRescueMode() {
91 if (self
::$inRescueMode === null) {
92 self
::$inRescueMode = false;
94 if (PACKAGE_ID
&& isset($_SERVER['HTTP_HOST'])) {
95 self
::$inRescueMode = true;
97 foreach (ApplicationHandler
::getInstance()->getApplications() as $application) {
98 if ($application->domainName
=== $_SERVER['HTTP_HOST']) {
99 self
::$inRescueMode = false;
104 if (self
::$inRescueMode) {
105 self
::$rescueModePageURL = RouteHandler
::getProtocol() . $_SERVER['HTTP_HOST'] . RouteHandler
::getPath(['acp']);
110 return self
::$inRescueMode;
114 * Returns URL for rescue mode page.
118 public static function getRescueModePageURL() {
119 if (self
::inRescueMode()) {
120 return self
::$rescueModePageURL;
127 * Does the user authentication.
129 protected function initAuth() {
130 // this is a work-around since neither RequestHandler
131 // nor RouteHandler are populated right now
132 $pathInfo = RouteHandler
::getPathInfo();
134 if (self
::inRescueMode()) {
135 if (!preg_match('~^/?rescue-mode/~', $pathInfo)) {
136 $redirectURI = self
::$rescueModePageURL . 'acp/index.php?rescue-mode/';
138 HeaderUtil
::redirect($redirectURI);
142 else if (empty($pathInfo) ||
!preg_match('~^/?(acp-?captcha|login|logout)/~i', $pathInfo)) {
143 if (WCF
::getUser()->userID
== 0) {
144 // work-around for AJAX-requests within ACP
145 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
146 throw new AJAXException(WCF
::getLanguage()->getDynamicVariable('wcf.ajax.error.sessionExpired'), AJAXException
::SESSION_EXPIRED
, '');
149 // build redirect path
150 $application = ApplicationHandler
::getInstance()->getActiveApplication();
151 if ($application === null) {
152 throw new SystemException("You have aborted the installation, therefore this installation is unusable. You are required to reinstall the software.");
155 HeaderUtil
::redirect(
156 LinkHandler
::getInstance()->getLink('Login', [
157 'url' => RouteHandler
::getProtocol() . $_SERVER['HTTP_HOST'] . WCF
::getSession()->requestURI
163 // work-around for AJAX-requests within ACP
164 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
166 WCF
::getSession()->checkPermissions(['admin.general.canUseAcp']);
168 catch (PermissionDeniedException
$e) {
169 throw new AJAXException(self
::getLanguage()->getDynamicVariable('wcf.ajax.error.permissionDenied'), AJAXException
::INSUFFICIENT_PERMISSIONS
, $e->getTraceAsString());
173 WCF
::getSession()->checkPermissions(['admin.general.canUseAcp']);
176 // force debug mode if in ACP and authenticated
177 self
::$overrideDebugMode = true;
185 protected function initSession() {
186 self
::$sessionObj = SessionHandler
::getInstance();
187 self
::$sessionObj->setCookieSuffix('_acp');
189 $factory = new ACPSessionFactory();
192 self
::$sessionObj->setHasValidCookie($factory->hasValidCookie());
198 protected function initTPL() {
199 self
::$tplObj = ACPTemplateEngine
::getInstance();
200 self
::getTPL()->setLanguageID(self
::getLanguage()->languageID
);
201 $this->assignDefaultTemplateVariables();
207 protected function assignDefaultTemplateVariables() {
208 parent
::assignDefaultTemplateVariables();
210 // base tag is determined on runtime
211 $host = RouteHandler
::getHost();
212 $path = RouteHandler
::getPath();
214 // available acp search providers
215 $availableAcpSearchProviders = [];
216 foreach (ACPSearchProviderCacheBuilder
::getInstance()->getData() as $searchProvider) {
217 $availableAcpSearchProviders[$searchProvider->providerName
] = self
::getLanguage()->get('wcf.acp.search.provider.'.$searchProvider->providerName
);
219 asort($availableAcpSearchProviders);
221 self
::getTPL()->assign([
222 'baseHref' => $host . $path,
223 'availableAcpSearchProviders' => $availableAcpSearchProviders
228 * Initializes the active package.
230 protected function initPackage() {
231 // define active package id
232 if (!defined('PACKAGE_ID')) {
233 define('PACKAGE_ID', 1);
238 * Checks whether the active user has entered the valid master password.
240 public static function checkMasterPassword() {
241 if (defined('MODULE_MASTER_PASSWORD') && MODULE_MASTER_PASSWORD
== 1 && !WCF
::getSession()->getVar('masterPassword')) {
242 if (file_exists(WCF_DIR
.'acp/masterPassword.inc.php')) {
243 require_once(WCF_DIR
.'acp/masterPassword.inc.php');
245 if (defined('MASTER_PASSWORD')) {
246 $form = new MasterPasswordForm();
251 $form = new MasterPasswordInitForm();