diff --git a/include/api.php b/include/api.php index 8b938508bd..3cadb485de 100644 --- a/include/api.php +++ b/include/api.php @@ -162,6 +162,7 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY * @brief Login API user * * @param App $a App + * @throws ForbiddenException * @throws InternalServerErrorException * @throws UnauthorizedException * @hook 'authenticate' @@ -170,8 +171,6 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY * 'password' => password from login form * 'authenticated' => return status, * 'user_record' => return authenticated user record - * @hook 'logged_in' - * array $user logged user record */ function api_login(App $a) { @@ -182,7 +181,7 @@ function api_login(App $a) list($consumer, $token) = $oauth1->verify_request($request); if (!is_null($token)) { $oauth1->loginUser($token->uid); - Hook::callAll('logged_in', $a->user); + Session::set('allow_api', true); return; } echo __FILE__.__LINE__.__FUNCTION__ . "
";
diff --git a/mod/community.php b/mod/community.php
index d29fa729dd..81857c6d3a 100644
--- a/mod/community.php
+++ b/mod/community.php
@@ -17,14 +17,6 @@ use Friendica\Database\DBA;
 use Friendica\Model\Item;
 use Friendica\Model\User;
 
-function community_init(App $a)
-{
-	if (!local_user()) {
-		unset($_SESSION['theme']);
-		unset($_SESSION['mobile-theme']);
-	}
-}
-
 function community_content(App $a, $update = 0)
 {
 	$o = '';
diff --git a/mod/manage.php b/mod/manage.php
index 09f553c61d..a1ca87e963 100644
--- a/mod/manage.php
+++ b/mod/manage.php
@@ -70,24 +70,8 @@ function manage_post(App $a) {
 	if (!DBA::isResult($user)) {
 		return;
 	}
-	unset($_SESSION['authenticated']);
-	unset($_SESSION['uid']);
-	unset($_SESSION['visitor_id']);
-	unset($_SESSION['administrator']);
-	unset($_SESSION['cid']);
-	unset($_SESSION['theme']);
-	unset($_SESSION['mobile-theme']);
-	unset($_SESSION['page_flags']);
-	unset($_SESSION['return_path']);
-	if (!empty($_SESSION['submanage'])) {
-		unset($_SESSION['submanage']);
-	}
-	if (!empty($_SESSION['sysmsg'])) {
-		unset($_SESSION['sysmsg']);
-	}
-	if (!empty($_SESSION['sysmsg_info'])) {
-		unset($_SESSION['sysmsg_info']);
-	}
+
+	Session::clear();
 
 	Session::setAuthenticatedForUser($a, $user, true, true);
 
diff --git a/mod/search.php b/mod/search.php
index 9ac5950224..b28ad7b0e9 100644
--- a/mod/search.php
+++ b/mod/search.php
@@ -76,10 +76,6 @@ function search_init(App $a) {
 		}
 
 		$a->page['aside'] .= search_saved_searches();
-
-	} else {
-		unset($_SESSION['theme']);
-		unset($_SESSION['mobile-theme']);
 	}
 }
 
diff --git a/mod/uimport.php b/mod/uimport.php
index 22a3161559..436802265b 100644
--- a/mod/uimport.php
+++ b/mod/uimport.php
@@ -41,14 +41,6 @@ function uimport_content(App $a)
 		}
 	}
 
-
-	if (!empty($_SESSION['theme'])) {
-		unset($_SESSION['theme']);
-	}
-	if (!empty($_SESSION['mobile-theme'])) {
-		unset($_SESSION['mobile-theme']);
-	}
-
 	$tpl = Renderer::getMarkupTemplate("uimport.tpl");
 	return Renderer::replaceMacros($tpl, [
 		'$regbutt' => L10n::t('Import'),
diff --git a/src/App.php b/src/App.php
index c7305c8c1d..c6ed818dd1 100644
--- a/src/App.php
+++ b/src/App.php
@@ -92,10 +92,10 @@ class App
 	 */
 	private $baseURL;
 
-	/**
-	 * @var string The name of the current theme
-	 */
+	/** @var string The name of the current theme */
 	private $currentTheme;
+	/** @var string The name of the current mobile theme */
+	private $currentMobileTheme;
 
 	/**
 	 * @var Configuration The config
@@ -450,10 +450,10 @@ class App
 	}
 
 	/**
-	 * Returns the current theme name.
+	 * Returns the current theme name. May be overriden by the mobile theme name.
 	 *
-	 * @return string the name of the current theme
-	 * @throws HTTPException\InternalServerErrorException
+	 * @return string
+	 * @throws Exception
 	 */
 	public function getCurrentTheme()
 	{
@@ -461,6 +461,16 @@ class App
 			return '';
 		}
 
+		// Specific mobile theme override
+		if (($this->mode->isMobile() || $this->mode->isTablet()) && Core\Session::get('show-mobile', true)) {
+			$user_mobile_theme = $this->getCurrentMobileTheme();
+
+			// --- means same mobile theme as desktop
+			if (!empty($user_mobile_theme) && $user_mobile_theme !== '---') {
+				return $user_mobile_theme;
+			}
+		}
+
 		if (!$this->currentTheme) {
 			$this->computeCurrentTheme();
 		}
@@ -468,13 +478,37 @@ class App
 		return $this->currentTheme;
 	}
 
+	/**
+	 * Returns the current mobile theme name.
+	 *
+	 * @return string
+	 * @throws Exception
+	 */
+	public function getCurrentMobileTheme()
+	{
+		if ($this->mode->isInstall()) {
+			return '';
+		}
+
+		if (is_null($this->currentMobileTheme)) {
+			$this->computeCurrentMobileTheme();
+		}
+
+		return $this->currentMobileTheme;
+	}
+
 	public function setCurrentTheme($theme)
 	{
 		$this->currentTheme = $theme;
 	}
 
+	public function setCurrentMobileTheme($theme)
+	{
+		$this->currentMobileTheme = $theme;
+	}
+
 	/**
-	 * Computes the current theme name based on the node settings, the user settings and the device type
+	 * Computes the current theme name based on the node settings, the page owner settings and the user settings
 	 *
 	 * @throws Exception
 	 */
@@ -486,7 +520,7 @@ class App
 		}
 
 		// Sane default
-		$this->currentTheme = $system_theme;
+		$this->setCurrentTheme($system_theme);
 
 		$page_theme = null;
 		// Find the theme that belongs to the user whose stuff we are looking at
@@ -499,24 +533,7 @@ class App
 			}
 		}
 
-		$user_theme = Core\Session::get('theme', $system_theme);
-
-		// Specific mobile theme override
-		if (($this->is_mobile || $this->is_tablet) && Core\Session::get('show-mobile', true)) {
-			$system_mobile_theme = $this->config->get('system', 'mobile-theme');
-			$user_mobile_theme   = Core\Session::get('mobile-theme', $system_mobile_theme);
-
-			// --- means same mobile theme as desktop
-			if (!empty($user_mobile_theme) && $user_mobile_theme !== '---') {
-				$user_theme = $user_mobile_theme;
-			}
-		}
-
-		if ($page_theme) {
-			$theme_name = $page_theme;
-		} else {
-			$theme_name = $user_theme;
-		}
+		$theme_name = $page_theme ?: Core\Session::get('theme', $system_theme);
 
 		$theme_name = Strings::sanitizeFilePathItem($theme_name);
 		if ($theme_name
@@ -524,7 +541,40 @@ class App
 		    && (file_exists('view/theme/' . $theme_name . '/style.css')
 		        || file_exists('view/theme/' . $theme_name . '/style.php'))
 		) {
-			$this->currentTheme = $theme_name;
+			$this->setCurrentTheme($theme_name);
+		}
+	}
+
+	/**
+	 * Computes the current mobile theme name based on the node settings, the page owner settings and the user settings
+	 */
+	private function computeCurrentMobileTheme()
+	{
+		$system_mobile_theme = $this->config->get('system', 'mobile-theme', '');
+
+		// Sane default
+		$this->setCurrentMobileTheme($system_mobile_theme);
+
+		$page_mobile_theme = null;
+		// Find the theme that belongs to the user whose stuff we are looking at
+		if ($this->profile_uid && ($this->profile_uid != local_user())) {
+			// Allow folks to override user themes and always use their own on their own site.
+			// This works only if the user is on the same server
+			if (!Core\PConfig::get(local_user(), 'system', 'always_my_theme')) {
+				$page_mobile_theme = Core\PConfig::get($this->profile_uid, 'system', 'mobile-theme');
+			}
+		}
+
+		$mobile_theme_name = $page_mobile_theme ?: Core\Session::get('mobile-theme', $system_mobile_theme);
+
+		$mobile_theme_name = Strings::sanitizeFilePathItem($mobile_theme_name);
+		if ($mobile_theme_name == '---'
+			||
+			in_array($mobile_theme_name, Theme::getAllowedList())
+			&& (file_exists('view/theme/' . $mobile_theme_name . '/style.css')
+				|| file_exists('view/theme/' . $mobile_theme_name . '/style.php'))
+		) {
+			$this->setCurrentMobileTheme($mobile_theme_name);
 		}
 	}
 
@@ -534,7 +584,7 @@ class App
 	 * Provide a sane default if nothing is chosen or the specified theme does not exist.
 	 *
 	 * @return string
-	 * @throws HTTPException\InternalServerErrorException
+	 * @throws Exception
 	 */
 	public function getCurrentThemeStylesheetPath()
 	{
@@ -587,7 +637,11 @@ class App
 	 *
 	 * This probably should change to limit the size of this monster method.
 	 *
-	 * @param App\Module $module The determined module
+	 * @param App\Module     $module The determined module
+	 * @param App\Router     $router
+	 * @param PConfiguration $pconfig
+	 * @throws HTTPException\InternalServerErrorException
+	 * @throws \ImagickException
 	 */
 	public function runFrontend(App\Module $module, App\Router $router, PConfiguration $pconfig)
 	{
@@ -733,8 +787,7 @@ class App
 			$module = $module->determineClass($this->args, $router, $this->config);
 
 			// Let the module run it's internal process (init, get, post, ...)
-			$module->run($this->l10n, $this, $this->logger, $this->getCurrentTheme(), $_SERVER, $_POST);
-
+			$module->run($this->l10n, $this, $this->logger, $_SERVER, $_POST);
 		} catch (HTTPException $e) {
 			ModuleHTTPException::rawContent($e);
 		}
diff --git a/src/App/Module.php b/src/App/Module.php
index 5ef4093600..9a24c55544 100644
--- a/src/App/Module.php
+++ b/src/App/Module.php
@@ -138,7 +138,7 @@ class Module
 	 *
 	 * @return Module The determined module of this call
 	 *
-	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+	 * @throws \Exception
 	 */
 	public function determineClass(Arguments $args, Router $router, Core\Config\Configuration $config)
 	{
@@ -186,13 +186,12 @@ class Module
 	 * @param Core\L10n\L10n  $l10n         The L10n instance
 	 * @param App             $app          The whole Friendica app (for method arguments)
 	 * @param LoggerInterface $logger       The Friendica logger
-	 * @param string          $currentTheme The chosen theme
 	 * @param array           $server       The $_SERVER variable
 	 * @param array           $post         The $_POST variables
 	 *
 	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
 	 */
-	public function run(Core\L10n\L10n $l10n, App $app, LoggerInterface $logger, string $currentTheme, array $server, array $post)
+	public function run(Core\L10n\L10n $l10n, App $app, LoggerInterface $logger, array $server, array $post)
 	{
 		if ($this->printNotAllowedAddon) {
 			info($l10n->t("You must be logged in to use addons. "));
@@ -232,17 +231,6 @@ class Module
 		// This endpoint doesn't need any theme initialization or other comparable stuff.
 		call_user_func([$this->module_class, 'rawContent']);
 
-		// Load current theme info after module has been initialized as theme could have been set in module
-		$theme_info_file = 'view/theme/' . $currentTheme . '/theme.php';
-		if (file_exists($theme_info_file)) {
-			require_once $theme_info_file;
-		}
-
-		if (function_exists(str_replace('-', '_', $currentTheme) . '_init')) {
-			$func = str_replace('-', '_', $currentTheme) . '_init';
-			$func($app);
-		}
-
 		if ($server['REQUEST_METHOD'] === 'POST') {
 			Core\Hook::callAll($this->module . '_mod_post', $post);
 			call_user_func([$this->module_class, 'post']);
diff --git a/src/App/Page.php b/src/App/Page.php
index 0bccbd7396..ea94f9cfef 100644
--- a/src/App/Page.php
+++ b/src/App/Page.php
@@ -364,6 +364,18 @@ class Page implements ArrayAccess
 		 */
 		$this->initContent($module, $mode);
 
+		// Load current theme info after module has been initialized as theme could have been set in module
+		$currentTheme = $app->getCurrentTheme();
+		$theme_info_file = 'view/theme/' . $currentTheme . '/theme.php';
+		if (file_exists($theme_info_file)) {
+			require_once $theme_info_file;
+		}
+
+		if (function_exists(str_replace('-', '_', $currentTheme) . '_init')) {
+			$func = str_replace('-', '_', $currentTheme) . '_init';
+			$func($app);
+		}
+
 		/* Create the page head after setting the language
 		 * and getting any auth credentials.
 		 *
diff --git a/src/Core/Session.php b/src/Core/Session.php
index b44ff3e2ea..3a0da3ab08 100644
--- a/src/Core/Session.php
+++ b/src/Core/Session.php
@@ -99,6 +99,14 @@ class Session
 		unset($_SESSION[$name]);
 	}
 
+	/**
+	 * Clears the current session array
+	 */
+	public static function clear()
+	{
+		$_SESSION = [];
+	}
+
 	/**
 	 * @brief Sets the provided user's authenticated session
 	 *
@@ -107,6 +115,7 @@ class Session
 	 * @param bool  $login_initial
 	 * @param bool  $interactive
 	 * @param bool  $login_refresh
+	 * @throws \Friendica\Network\HTTPException\ForbiddenException
 	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
 	 */
 	public static function setAuthenticatedForUser(App $a, array $user_record, $login_initial = false, $interactive = false, $login_refresh = false)
diff --git a/src/Model/Profile.php b/src/Model/Profile.php
index cf39a02a91..67c6a0eb68 100644
--- a/src/Model/Profile.php
+++ b/src/Model/Profile.php
@@ -20,6 +20,7 @@ use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
 use Friendica\Core\Session;
 use Friendica\Core\System;
+use Friendica\Core\Theme;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Protocol\Diaspora;
@@ -189,11 +190,10 @@ class Profile
 		$a->page['title'] = $a->profile['name'] . ' @ ' . Config::get('config', 'sitename');
 
 		if (!$profiledata && !PConfig::get(local_user(), 'system', 'always_my_theme')) {
-			$_SESSION['theme'] = $a->profile['theme'];
+			$a->setCurrentTheme($a->profile['theme']);
+			$a->setCurrentMobileTheme($a->profile['mobile-theme']);
 		}
 
-		$_SESSION['mobile-theme'] = $a->profile['mobile-theme'];
-
 		/*
 		* load/reload current theme info
 		*/
diff --git a/src/Module/Directory.php b/src/Module/Directory.php
index 7d75e4d477..1cdd971e8a 100644
--- a/src/Module/Directory.php
+++ b/src/Module/Directory.php
@@ -34,9 +34,6 @@ class Directory extends BaseModule
 		if (local_user()) {
 			$app->page['aside'] .= Widget::findPeople();
 			$app->page['aside'] .= Widget::follow();
-		} else {
-			unset($_SESSION['theme']);
-			unset($_SESSION['mobile-theme']);
 		}
 
 		$output = '';
diff --git a/src/Module/Home.php b/src/Module/Home.php
index 673701c28d..5a1dccde2a 100644
--- a/src/Module/Home.php
+++ b/src/Module/Home.php
@@ -14,14 +14,6 @@ class Home extends BaseModule
 {
 	public static function content()
 	{
-		if (!empty($_SESSION['theme'])) {
-			unset($_SESSION['theme']);
-		}
-
-		if (!empty($_SESSION['mobile-theme'])) {
-			unset($_SESSION['mobile-theme']);
-		}
-
 		$app = self::getApp();
 		$config = $app->getConfig();
 
diff --git a/src/Module/Login.php b/src/Module/Login.php
index 966ded57fa..40e376aeb1 100644
--- a/src/Module/Login.php
+++ b/src/Module/Login.php
@@ -32,9 +32,6 @@ class Login extends BaseModule
 	{
 		$a = self::getApp();
 
-		Session::remove('theme');
-		Session::remove('mobile-theme');
-
 		if (local_user()) {
 			$a->internalRedirect();
 		}
diff --git a/src/Module/Register.php b/src/Module/Register.php
index 51287053fd..1aabb84393 100644
--- a/src/Module/Register.php
+++ b/src/Module/Register.php
@@ -61,13 +61,6 @@ class Register extends BaseModule
 			}
 		}
 
-		if (!empty($_SESSION['theme'])) {
-			unset($_SESSION['theme']);
-		}
-		if (!empty($_SESSION['mobile-theme'])) {
-			unset($_SESSION['mobile-theme']);
-		}
-
 		$username   = defaults($_REQUEST, 'username'  , '');
 		$email      = defaults($_REQUEST, 'email'     , '');
 		$openid_url = defaults($_REQUEST, 'openid_url', '');
diff --git a/src/Network/FKOAuth1.php b/src/Network/FKOAuth1.php
index 33fdf0ac22..eb13290577 100644
--- a/src/Network/FKOAuth1.php
+++ b/src/Network/FKOAuth1.php
@@ -4,12 +4,10 @@
  */
 namespace Friendica\Network;
 
-use Friendica\Core\Hook;
+use Friendica\BaseObject;
 use Friendica\Core\Logger;
-use Friendica\Core\PConfig;
-use Friendica\Core\System;
+use Friendica\Core\Session;
 use Friendica\Database\DBA;
-use Friendica\Util\DateTimeFormat;
 use OAuthServer;
 use OAuthSignatureMethod_HMAC_SHA1;
 use OAuthSignatureMethod_PLAINTEXT;
@@ -32,12 +30,13 @@ class FKOAuth1 extends OAuthServer
 	/**
 	 * @param string $uid user id
 	 * @return void
+	 * @throws HTTPException\ForbiddenException
 	 * @throws HTTPException\InternalServerErrorException
 	 */
 	public function loginUser($uid)
 	{
 		Logger::log("FKOAuth1::loginUser $uid");
-		$a = \get_app();
+		$a = BaseObject::getApp();
 		$record = DBA::selectFirst('user', [], ['uid' => $uid, 'blocked' => 0, 'account_expired' => 0, 'account_removed' => 0, 'verified' => 1]);
 
 		if (!DBA::isResult($record)) {
@@ -45,31 +44,7 @@ class FKOAuth1 extends OAuthServer
 			header('HTTP/1.0 401 Unauthorized');
 			die('This api requires login');
 		}
-		$_SESSION['uid'] = $record['uid'];
-		$_SESSION['theme'] = $record['theme'];
-		$_SESSION['mobile-theme'] = PConfig::get($record['uid'], 'system', 'mobile_theme');
-		$_SESSION['authenticated'] = 1;
-		$_SESSION['page_flags'] = $record['page-flags'];
-		$_SESSION['my_url'] = System::baseUrl() . '/profile/' . $record['nickname'];
-		$_SESSION['addr'] = $_SERVER['REMOTE_ADDR'];
-		$_SESSION["allow_api"] = true;
 
-		$a->user = $record;
-
-		if (strlen($a->user['timezone'])) {
-			date_default_timezone_set($a->user['timezone']);
-			$a->timezone = $a->user['timezone'];
-		}
-
-		$contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => 1]);
-		if (DBA::isResult($contact)) {
-			$a->contact = $contact;
-			$a->cid = $contact['id'];
-			$_SESSION['cid'] = $a->cid;
-		}
-
-		DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]);
-
-		Hook::callAll('logged_in', $a->user);
+		Session::setAuthenticatedForUser($a, $record, true);
 	}
 }