<?php
+declare(strict_types=1);
namespace wcf\system;
use wcf\data\application\Application;
use wcf\data\option\OptionEditor;
use wcf\system\exception\SystemException;
use wcf\system\language\LanguageFactory;
use wcf\system\package\PackageInstallationDispatcher;
+use wcf\system\registry\RegistryHandler;
use wcf\system\request\Request;
use wcf\system\request\RequestHandler;
use wcf\system\session\SessionFactory;
}
// define current woltlab suite version
-define('WCF_VERSION', '3.0.13');
+define('WCF_VERSION', '3.1.2 pl 2');
+
+// define current API version
+define('WSC_API_VERSION', 2018);
// define current unix timestamp
define('TIME_NOW', time());
* It holds the database connection, access to template and language engine.
*
* @author Marcel Werk
- * @copyright 2001-2017 WoltLab GmbH
+ * @copyright 2001-2018 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package WoltLabSuite\Core\System
*/
class WCF {
+ /**
+ * list of supported legacy API versions
+ * @var integer[]
+ */
+ private static $supportedLegacyApiVersions = [2017];
+
/**
* list of currently loaded applications
* @var Application[]
}
}
- // execute shutdown actions of user storage handler
+ // execute shutdown actions of storage handlers
+ RegistryHandler::getInstance()->shutdown();
UserStorageHandler::getInstance()->shutdown();
}
catch (\Exception $exception) {
* @param \Exception $e
*/
public static final function handleException($e) {
+ // backwards compatibility
+ if ($e instanceof IPrintableException) {
+ $e->show();
+ exit;
+ }
+
if (ob_get_level()) {
- // discard any output generated before the exception occured, prevents exception
+ // discard any output generated before the exception occurred, prevents exception
// being hidden inside HTML elements and therefore not visible in browser output
//
// ob_get_level() can return values > 1, if the PHP setting `output_buffering` is on
// Especially the `identity` value appears to be unrecognized by some of them, hence
// we'll just gzip the output of the exception to prevent them from tampering.
// This part is copied from `HeaderUtil` in order to isolate the exception handler!
- if (HTTP_ENABLE_GZIP && !defined('HTTP_DISABLE_GZIP')) {
- if (function_exists('gzcompress') && !@ini_get('zlib.output_compression') && !@ini_get('output_handler') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
- if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip')) {
+ if (defined('HTTP_ENABLE_GZIP') && HTTP_ENABLE_GZIP && !defined('HTTP_DISABLE_GZIP')) {
+ if (function_exists('gzcompress') && !@ini_get('zlib.output_compression') && !@ini_get('output_handler') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
+ if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false) {
@header('Content-Encoding: x-gzip');
}
else {
}
}
- // backwards compatibility
- if ($e instanceof IPrintableException) {
- $e->show();
- exit;
- }
-
@header('HTTP/1.1 503 Service Unavailable');
try {
\wcf\functions\exception\printThrowable($e);
echo "\n\nwas handled.</pre>";
exit;
}
- catch (\Exception $e2) {
- echo "<pre>An Exception was thrown while handling an Exception:\n\n";
- echo preg_replace('/Database->__construct\(.*\)/', 'Database->__construct(...)', $e2);
- echo "\n\nwas thrown while:\n\n";
- echo preg_replace('/Database->__construct\(.*\)/', 'Database->__construct(...)', $e);
- echo "\n\nwas handled.</pre>";
- exit;
- }
}
/**
self::$autoloadDirectories[$abbreviation] = $packageDir . 'lib/';
$className = $abbreviation.'\system\\'.strtoupper($abbreviation).'Core';
+
+ // class was not found, possibly the app was moved, but `packageDir` has not been adjusted
+ if (!class_exists($className)) {
+ // check if both the Core and the app are on the same domain
+ $coreApp = ApplicationHandler::getInstance()->getApplicationByID(1);
+ if ($coreApp->domainName === $application->domainName) {
+ // resolve the relative path and use it to construct the autoload directory
+ $relativePath = FileUtil::getRelativePath($coreApp->domainPath, $application->domainPath);
+ if ($relativePath !== './') {
+ $packageDir = FileUtil::getRealPath(WCF_DIR.$relativePath);
+ self::$autoloadDirectories[$abbreviation] = $packageDir . 'lib/';
+
+ if (class_exists($className)) {
+ // the class can now be found, update the `packageDir` value
+ (new PackageEditor($package))->update(['packageDir' => $relativePath]);
+ }
+ }
+ }
+ }
+
if (class_exists($className) && is_subclass_of($className, IApplication::class)) {
// include config file
$configPath = $packageDir . PackageInstallationDispatcher::CONFIG_FILE;
return null;
}
+ /**
+ * Returns the invoked application.
+ *
+ * @return Application
+ * @since 3.1
+ */
+ public static function getActiveApplication() {
+ return ApplicationHandler::getInstance()->getActiveApplication();
+ }
+
/**
* Loads an application on runtime, do not use this outside the package installation.
*
public function getFavicon() {
$activeApplication = ApplicationHandler::getInstance()->getActiveApplication();
$wcf = ApplicationHandler::getInstance()->getWCF();
+ $favicon = StyleHandler::getInstance()->getStyle()->getRelativeFavicon();
if ($activeApplication->domainName !== $wcf->domainName) {
- if (file_exists(WCF_DIR.'images/favicon.ico')) {
- $favicon = file_get_contents(WCF_DIR.'images/favicon.ico');
+ if (file_exists(WCF_DIR.$favicon)) {
+ $favicon = file_get_contents(WCF_DIR.$favicon);
return 'data:image/x-icon;base64,' . base64_encode($favicon);
}
}
- return self::getPath() . 'images/favicon.ico';
+ return self::getPath() . $favicon;
+ }
+
+ /**
+ * Returns true if the desktop notifications should be enabled.
+ *
+ * @return boolean
+ */
+ public function useDesktopNotifications() {
+ if (!ENABLE_DESKTOP_NOTIFICATIONS) {
+ return false;
+ }
+ else if (ApplicationHandler::getInstance()->isMultiDomainSetup()) {
+ $application = ApplicationHandler::getInstance()->getApplicationByID(DESKTOP_NOTIFICATION_PACKAGE_ID);
+ // mismatch, default to Core
+ if ($application === null) $application = ApplicationHandler::getInstance()->getApplicationByID(1);
+
+ $currentApplication = ApplicationHandler::getInstance()->getActiveApplication();
+ if ($currentApplication->domainName != $application->domainName) {
+ // different domain
+ return false;
+ }
+ }
+
+ return true;
}
/**
return self::getActiveRequest()->isLandingPage();
}
+ /**
+ * Returns true if the given API version is currently supported.
+ *
+ * @param integer $apiVersion
+ * @return boolean
+ */
+ public static function isSupportedApiVersion($apiVersion) {
+ return ($apiVersion == WSC_API_VERSION) || in_array($apiVersion, self::$supportedLegacyApiVersions);
+ }
+
+ /**
+ * Returns the list of supported legacy API versions.
+ *
+ * @return integer[]
+ */
+ public static function getSupportedLegacyApiVersions() {
+ return self::$supportedLegacyApiVersions;
+ }
+
/**
* Initialises the cronjobs.
*/