]> git.mxchange.org Git - friendica.git/blobdiff - src/App.php
Merge pull request #5828 from nupplaphil/mode_class
[friendica.git] / src / App.php
index ac86b2f6c7d9b6a8eb5493bf23cf7449fa3ceef1..9a09bcfce0ba8d425599c7ff735d75daa3c788b0 100644 (file)
@@ -4,16 +4,13 @@
  */
 namespace Friendica;
 
+use Detection\MobileDetect;
+use Exception;
 use Friendica\Core\Config;
 use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
-use Friendica\Database\DBM;
-use dba;
-
-use Detection\MobileDetect;
-
-use Exception;
+use Friendica\Database\DBA;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -34,10 +31,6 @@ require_once 'include/text.php';
  */
 class App
 {
-       const MODE_NORMAL = 0;
-       const MODE_INSTALL = 1;
-       const MODE_MAINTENANCE = 2;
-
        public $module_loaded = false;
        public $module_class = null;
        public $query_string = '';
@@ -59,7 +52,6 @@ class App
        public $argv;
        public $argc;
        public $module;
-       public $mode = App::MODE_NORMAL;
        public $strings;
        public $basepath;
        public $urlpath;
@@ -88,6 +80,41 @@ class App
        public $force_max_items = 0;
        public $theme_events_in_profile = true;
 
+       public $stylesheets = [];
+       public $footerScripts = [];
+
+       /**
+        * Register a stylesheet file path to be included in the <head> tag of every page.
+        * Inclusion is done in App->initHead().
+        * The path can be absolute or relative to the Friendica installation base folder.
+        *
+        * @see App->initHead()
+        *
+        * @param string $path
+        */
+       public function registerStylesheet($path)
+       {
+               $url = str_replace($this->get_basepath() . DIRECTORY_SEPARATOR, '', $path);
+
+               $this->stylesheets[] = trim($url, '/');
+       }
+
+       /**
+        * Register a javascript file path to be included in the <footer> tag of every page.
+        * Inclusion is done in App->initFooter().
+        * The path can be absolute or relative to the Friendica installation base folder.
+        *
+        * @see App->initFooter()
+        *
+        * @param string $path
+        */
+       public function registerFooterScript($path)
+       {
+               $url = str_replace($this->get_basepath() . DIRECTORY_SEPARATOR, '', $path);
+
+               $this->footerScripts[] = trim($url, '/');
+       }
+
        /**
         * @brief An array for all theme-controllable parameters
         *
@@ -132,6 +159,8 @@ class App
         * @brief App constructor.
         *
         * @param string $basepath Path to the app base folder
+        *
+        * @throws Exception if the Basepath is not usable
         */
        public function __construct($basepath)
        {
@@ -139,17 +168,9 @@ class App
                        throw new Exception('Basepath ' . $basepath . ' isn\'t usable.');
                }
 
-               $this->basepath = rtrim($basepath, DIRECTORY_SEPARATOR);
-
-               $this->determineUrlPath();
-
-               $this->loadConfigFiles();
-
-               $this->loadDatabase();
-
-               $this->determineMode();
+               BaseObject::setApp($this);
 
-               $this->loadDefaultTimezone();
+               $this->basepath = rtrim($basepath, DIRECTORY_SEPARATOR);
 
                $this->performance['start'] = microtime(true);
                $this->performance['database'] = 0;
@@ -172,21 +193,7 @@ class App
                $this->callstack['rendering'] = [];
                $this->callstack['parser'] = [];
 
-               $this->page = [
-                       'aside' => '',
-                       'bottom' => '',
-                       'content' => '',
-                       'end' => '',
-                       'footer' => '',
-                       'htmlhead' => '',
-                       'nav' => '',
-                       'page_title' => '',
-                       'right_aside' => '',
-                       'template' => '',
-                       'title' => ''
-               ];
-
-               $this->process_id = System::processID('log');
+               $this->reload();
 
                set_time_limit(0);
 
@@ -293,9 +300,56 @@ class App
                $this->register_template_engine('Friendica\Render\FriendicaSmartyEngine');
        }
 
+       /**
+        * Reloads the whole app instance
+        */
+       public function reload()
+       {
+               // The order of the following calls is important to ensure proper initialization
+               $this->loadConfigFiles();
+
+               $this->loadDatabase();
+
+               App\Mode::determine($this->basepath);
+
+               $this->determineUrlPath();
+
+               Config::load();
+
+               if (App\Mode::has(App\Mode::DBAVAILABLE)) {
+                       Core\Addon::loadHooks();
+
+                       $this->loadAddonConfig();
+               }
+
+               $this->loadDefaultTimezone();
+
+               $this->page = [
+                       'aside' => '',
+                       'bottom' => '',
+                       'content' => '',
+                       'footer' => '',
+                       'htmlhead' => '',
+                       'nav' => '',
+                       'page_title' => '',
+                       'right_aside' => '',
+                       'template' => '',
+                       'title' => ''
+               ];
+
+               $this->process_id = System::processID('log');
+       }
+
+       /**
+        * Load the configuration files
+        *
+        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
+        * expected local.ini.php
+        */
        private function loadConfigFiles()
        {
-               $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'defaults.ini.php');
+               $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.ini.php');
+               $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'settings.ini.php');
 
                // Legacy .htconfig.php support
                if (file_exists($this->basepath . DIRECTORY_SEPARATOR . '.htpreconfig.php')) {
@@ -308,6 +362,15 @@ class App
                        $a = $this;
 
                        include $this->basepath . DIRECTORY_SEPARATOR . '.htconfig.php';
+
+                       $this->setConfigValue('database', 'hostname', $db_host);
+                       $this->setConfigValue('database', 'username', $db_user);
+                       $this->setConfigValue('database', 'password', $db_pass);
+                       $this->setConfigValue('database', 'database', $db_data);
+                       if (isset($a->config['system']['db_charset'])) {
+                               $this->setConfigValue('database', 'charset', $a->config['system']['db_charset']);
+                       }
+
                        unset($db_host, $db_user, $db_pass, $db_data);
 
                        if (isset($default_timezone)) {
@@ -319,14 +382,37 @@ class App
                                $this->setConfigValue('system', 'pidfile', $pidfile);
                                unset($pidfile);
                        }
+
+                       if (isset($lang)) {
+                               $this->setConfigValue('system', 'language', $lang);
+                               unset($lang);
+                       }
                }
 
                if (file_exists($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')) {
-                       $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php');
+                       $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php', true);
                }
        }
 
-       public function loadConfigFile($filepath)
+       /**
+        * Tries to load the specified configuration file into the App->config array.
+        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+        *
+        * The config format is INI and the template for configuration files is the following:
+        *
+        * <?php return <<<INI
+        *
+        * [section]
+        * key = value
+        *
+        * INI;
+        * // Keep this line
+        *
+        * @param type $filepath
+        * @param bool $overwrite Force value overwrite if the config key already exists
+        * @throws Exception
+        */
+       public function loadConfigFile($filepath, $overwrite = false)
        {
                if (!file_exists($filepath)) {
                        throw new Exception('Error parsing non-existent config file ' . $filepath);
@@ -340,24 +426,41 @@ class App
                        throw new Exception('Error parsing config file ' . $filepath);
                }
 
-               foreach($config as $category => $values) {
-                       foreach($values as $key => $value) {
-                               $this->setConfigValue($category, $key, $value);
+               foreach ($config as $category => $values) {
+                       foreach ($values as $key => $value) {
+                               if ($overwrite) {
+                                       $this->setConfigValue($category, $key, $value);
+                               } else {
+                                       $this->setDefaultConfigValue($category, $key, $value);
+                               }
                        }
                }
        }
 
+       /**
+        * Loads addons configuration files
+        *
+        * First loads all activated addons default configuration throught the load_config hook, then load the local.ini.php
+        * again to overwrite potential local addon configuration.
+        */
        private function loadAddonConfig()
        {
                // Loads addons default config
                Core\Addon::callHooks('load_config');
 
-               // Load the local config file again in case there are overwritten addon config
-               if (file_exists($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')) {
-                       $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php');
+               // Load the local addon config file to overwritten default addon config values
+               if (file_exists($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'addon.ini.php')) {
+                       $this->loadConfigFile($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'addon.ini.php', true);
                }
        }
 
+       /**
+        * Loads the default timezone
+        *
+        * Include support for legacy $default_timezone
+        *
+        * @global string $default_timezone
+        */
        private function loadDefaultTimezone()
        {
                if ($this->getConfigValue('system', 'default_timezone')) {
@@ -373,8 +476,7 @@ class App
        }
 
        /**
-        * Figure out if we are running at the top of a domain
-        * or in a sub-directory and adjust accordingly
+        * Figure out if we are running at the top of a domain or in a sub-directory and adjust accordingly
         */
        private function determineUrlPath()
        {
@@ -385,8 +487,14 @@ class App
                 *
                 * To get /path/to/friendica we perform dirname() for as many levels as there are slashes in the QUERY_STRING
                 */
-               if (!empty($_SERVER['SCRIPT_URL']) && !empty($_SERVER['QUERY_STRING'])) {
-                       $path = trim(dirname($_SERVER['SCRIPT_URL'], substr_count(trim($_SERVER['QUERY_STRING'], '/'), '/') + 1), '/');
+               if (!empty($_SERVER['SCRIPT_URL'])) {
+                       // Module
+                       if (!empty($_SERVER['QUERY_STRING'])) {
+                               $path = trim(dirname($_SERVER['SCRIPT_URL'], substr_count(trim($_SERVER['QUERY_STRING'], '/'), '/') + 1), '/');
+                       } else {
+                               // Root page
+                               $path = trim($_SERVER['SCRIPT_URL'], '/');
+                       }
 
                        if ($path && $path != $this->urlpath) {
                                $this->urlpath = $path;
@@ -394,31 +502,9 @@ class App
                }
        }
 
-       private function determineMode()
-       {
-               $this->mode = App::MODE_INSTALL;
-
-               // Missing DB connection
-               if (!\dba::connected()) {
-                       return;
-               }
-
-               // Working DB connection, missing tables
-               if (\dba::fetch_first("SHOW TABLES LIKE 'config'") === false) {
-                       return;
-               }
-
-               // Maintenance mode check
-               if (Config::get('system', 'maintenance')) {
-                       $this->mode = App::MODE_MAINTENANCE;
-               } else {
-                       $this->mode = App::MODE_NORMAL;
-               }
-       }
-
        public function loadDatabase()
        {
-               if (\dba::connected()) {
+               if (DBA::connected()) {
                        return;
                }
 
@@ -430,35 +516,29 @@ class App
 
                // Use environment variables for mysql if they are set beforehand
                if (!empty(getenv('MYSQL_HOST'))
-                       && !empty(getenv('MYSQL_PORT'))
                        && (!empty(getenv('MYSQL_USERNAME')) || !empty(getenv('MYSQL_USER')))
-                       && !empty(getenv('MYSQL_PASSWORD'))
+                       && getenv('MYSQL_PASSWORD') !== false
                        && !empty(getenv('MYSQL_DATABASE')))
                {
-                       $db_host = getenv('MYSQL_HOST') . ':' . getenv('MYSQL_PORT');
-
+                       $db_host = getenv('MYSQL_HOST');
+                       if (!empty(getenv('MYSQL_PORT'))) {
+                               $db_host .= ':' . getenv('MYSQL_PORT');
+                       }
                        if (!empty(getenv('MYSQL_USERNAME'))) {
                                $db_user = getenv('MYSQL_USERNAME');
-                       } elseif (!empty(getenv('MYSQL_USER'))) {
+                       } else {
                                $db_user = getenv('MYSQL_USER');
                        }
-
-                       $db_pass = getenv('MYSQL_PASSWORD');
+                       $db_pass = (string) getenv('MYSQL_PASSWORD');
                        $db_data = getenv('MYSQL_DATABASE');
-               }elseif (file_exists($this->basepath . DIRECTORY_SEPARATOR . '.htconfig.php')) {
-                       $a = new \stdClass();
-                       include $this->basepath . DIRECTORY_SEPARATOR . '.htconfig.php';
-                       $charset = isset($a->config["system"]["db_charset"]) ? $a->config["system"]["db_charset"] : $charset;
-
-                       unset($a);
                }
 
                $stamp1 = microtime(true);
 
-               \dba::connect($db_host, $db_user, $db_pass, $db_data, $charset);
+               DBA::connect($db_host, $db_user, $db_pass, $db_data, $charset);
                unset($db_host, $db_user, $db_pass, $db_data, $charset);
 
-               $this->save_timestamp($stamp1, "network");
+               $this->save_timestamp($stamp1, 'network');
        }
 
        /**
@@ -551,7 +631,7 @@ class App
                        $this->hostname = Config::get('config', 'hostname');
                }
 
-               return $scheme . '://' . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
+               return $scheme . '://' . $this->hostname . (!empty($this->urlpath) ? '/' . $this->urlpath : '' );
        }
 
        /**
@@ -579,7 +659,7 @@ class App
                                $hostname .= ':' . $parsed['port'];
                        }
                        if (x($parsed, 'path')) {
-                               $this->path = trim($parsed['path'], '\\/');
+                               $this->urlpath = trim($parsed['path'], '\\/');
                        }
 
                        if (file_exists($this->basepath . DIRECTORY_SEPARATOR . '.htpreconfig.php')) {
@@ -607,7 +687,7 @@ class App
 
        public function get_path()
        {
-               return $this->path;
+               return $this->urlpath;
        }
 
        public function set_pager_total($n)
@@ -627,7 +707,17 @@ class App
                $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage'];
        }
 
-       public function init_pagehead()
+       /**
+        * Initializes App->page['htmlhead'].
+        *
+        * Includes:
+        * - Page title
+        * - Favicons
+        * - Registered stylesheets (through App->registerStylesheet())
+        * - Infinite scroll data
+        * - head.tpl template
+        */
+       public function initHead()
        {
                $interval = ((local_user()) ? PConfig::get(local_user(), 'system', 'update_interval') : 40000);
 
@@ -648,24 +738,14 @@ class App
                        $this->page['title'] = $this->config['sitename'];
                }
 
-               /* put the head template at the beginning of page['htmlhead']
-                * since the code added by the modules frequently depends on it
-                * being first
-                */
-               if (!isset($this->page['htmlhead'])) {
-                       $this->page['htmlhead'] = '';
-               }
-
-               // If we're using Smarty, then doing replace_macros() will replace
-               // any unrecognized variables with a blank string. Since we delay
-               // replacing $stylesheet until later, we need to replace it now
-               // with another variable name
-               if ($this->theme['template_engine'] === 'smarty3') {
-                       $stylesheet = $this->get_template_ldelim('smarty3') . '$stylesheet' . $this->get_template_rdelim('smarty3');
+               if (!empty($this->theme['stylesheet'])) {
+                       $stylesheet = $this->theme['stylesheet'];
                } else {
-                       $stylesheet = '$stylesheet';
+                       $stylesheet = $this->getCurrentThemeStylesheetPath();
                }
 
+               $this->registerStylesheet($stylesheet);
+
                $shortcut_icon = Config::get('system', 'shortcut_icon');
                if ($shortcut_icon == '') {
                        $shortcut_icon = 'images/friendica-32.png';
@@ -677,9 +757,15 @@ class App
                }
 
                // get data wich is needed for infinite scroll on the network page
-               $invinite_scroll = infinite_scroll_data($this->module);
+               $infinite_scroll = infinite_scroll_data($this->module);
+
+               Core\Addon::callHooks('head', $this->page['htmlhead']);
 
                $tpl = get_markup_template('head.tpl');
+               /* put the head template at the beginning of page['htmlhead']
+                * since the code added by the modules frequently depends on it
+                * being first
+                */
                $this->page['htmlhead'] = replace_macros($tpl, [
                        '$baseurl'         => $this->get_baseurl(),
                        '$local_user'      => local_user(),
@@ -690,21 +776,56 @@ class App
                        '$update_interval' => $interval,
                        '$shortcut_icon'   => $shortcut_icon,
                        '$touch_icon'      => $touch_icon,
-                       '$stylesheet'      => $stylesheet,
-                       '$infinite_scroll' => $invinite_scroll,
+                       '$infinite_scroll' => $infinite_scroll,
                        '$block_public'    => intval(Config::get('system', 'block_public')),
+                       '$stylesheets'     => $this->stylesheets,
                ]) . $this->page['htmlhead'];
        }
 
-       public function init_page_end()
+       /**
+        * Initializes App->page['footer'].
+        *
+        * Includes:
+        * - Javascript homebase
+        * - Mobile toggle link
+        * - Registered footer scripts (through App->registerFooterScript())
+        * - footer.tpl template
+        */
+       public function initFooter()
        {
-               if (!isset($this->page['end'])) {
-                       $this->page['end'] = '';
+               // If you're just visiting, let javascript take you home
+               if (!empty($_SESSION['visitor_home'])) {
+                       $homebase = $_SESSION['visitor_home'];
+               } elseif (local_user()) {
+                       $homebase = 'profile/' . $this->user['nickname'];
+               }
+
+               if (isset($homebase)) {
+                       $this->page['footer'] .= '<script>var homebase="' . $homebase . '";</script>' . "\n";
+               }
+
+               /*
+                * Add a "toggle mobile" link if we're using a mobile device
+                */
+               if ($this->is_mobile || $this->is_tablet) {
+                       if (isset($_SESSION['show-mobile']) && !$_SESSION['show-mobile']) {
+                               $link = 'toggle_mobile?address=' . curPageURL();
+                       } else {
+                               $link = 'toggle_mobile?off=1&address=' . curPageURL();
+                       }
+                       $this->page['footer'] .= replace_macros(get_markup_template("toggle_mobile_footer.tpl"), [
+                               '$toggle_link' => $link,
+                               '$toggle_text' => Core\L10n::t('toggle mobile')
+                       ]);
                }
-               $tpl = get_markup_template('end.tpl');
-               $this->page['end'] = replace_macros($tpl, [
-                       '$baseurl' => $this->get_baseurl()
-               ]) . $this->page['end'];
+
+               Core\Addon::callHooks('footer', $this->page['footer']);
+
+               $tpl = get_markup_template('footer.tpl');
+               $this->page['footer'] = replace_macros($tpl, [
+                       '$baseurl' => $this->get_baseurl(),
+                       '$footerScripts' => $this->footerScripts,
+               ]) . $this->page['footer'];
        }
 
        public function set_curl_code($code)
@@ -913,7 +1034,7 @@ class App
         *
         * @return bool Is the limit reached?
         */
-       public function max_processes_reached()
+       public function isMaxProcessesReached()
        {
                // Deactivated, needs more investigating if this check really makes sense
                return false;
@@ -935,7 +1056,7 @@ class App
                        }
                }
 
-               $processlist = DBM::processlist();
+               $processlist = DBA::processlist();
                if ($processlist['list'] != '') {
                        logger('Processcheck: Processes: ' . $processlist['amount'] . ' - Processlist: ' . $processlist['list'], LOGGER_DEBUG);
 
@@ -968,7 +1089,11 @@ class App
 
                $meminfo = [];
                foreach ($memdata as $line) {
-                       list($key, $val) = explode(':', $line);
+                       $data = explode(':', $line);
+                       if (count($data) != 2) {
+                               continue;
+                       }
+                       list($key, $val) = $data;
                        $meminfo[$key] = (int) trim(str_replace('kB', '', $val));
                        $meminfo[$key] = (int) ($meminfo[$key] / 1024);
                }
@@ -993,7 +1118,7 @@ class App
         *
         * @return bool Is the load reached?
         */
-       public function maxload_reached()
+       public function isMaxLoadReached()
        {
                if ($this->is_backend()) {
                        $process = 'backend';
@@ -1019,19 +1144,30 @@ class App
                return false;
        }
 
-       public function proc_run($args)
+       /**
+        * Executes a child process with 'proc_open'
+        *
+        * @param string $command The command to execute
+        * @param array  $args    Arguments to pass to the command ( [ 'key' => value, 'key2' => value2, ... ]
+        */
+       public function proc_run($command, $args)
        {
                if (!function_exists('proc_open')) {
                        return;
                }
 
-               array_unshift($args, $this->getConfigValue('config', 'php_path', 'php'));
+               $cmdline = $this->getConfigValue('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
 
-               for ($x = 0; $x < count($args); $x ++) {
-                       $args[$x] = escapeshellarg($args[$x]);
-               }
+               foreach ($args as $key => $value) {
+                       if (!is_null($value) && is_bool($value) && !$value) {
+                               continue;
+                       }
 
-               $cmdline = implode(' ', $args);
+                       $cmdline .= ' --' . $key;
+                       if (!is_null($value) && !is_bool($value)) {
+                               $cmdline .= ' ' . $value;
+                       }
+               }
 
                if ($this->min_memory_reached()) {
                        return;
@@ -1123,6 +1259,20 @@ class App
                return $return;
        }
 
+       /**
+        * Sets a default value in the config cache. Ignores already existing keys.
+        *
+        * @param string $cat Config category
+        * @param string $k   Config key
+        * @param mixed  $v   Default value to set
+        */
+       private function setDefaultConfigValue($cat, $k, $v)
+       {
+               if (!isset($this->config[$cat][$k])) {
+                       $this->setConfigValue($cat, $k, $v);
+               }
+       }
+
        /**
         * Sets a value in the config cache. Accepts raw output from the config table
         *
@@ -1200,11 +1350,11 @@ class App
                // Only arrays are serialized in database, so we have to unserialize sparingly
                $value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
 
-               if (!isset($this->config[$uid])) {
+               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
                        $this->config[$uid] = [];
                }
 
-               if (!isset($this->config[$uid][$cat])) {
+               if (!isset($this->config[$uid][$cat]) || !is_array($this->config[$uid][$cat])) {
                        $this->config[$uid][$cat] = [];
                }
 
@@ -1252,7 +1402,7 @@ class App
         */
        public function getCurrentTheme()
        {
-               if ($this->mode == App::MODE_INSTALL) {
+               if (App\Mode::isInstall()) {
                        return '';
                }
 
@@ -1286,22 +1436,18 @@ class App
                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
-                       $user = dba::selectFirst('user', ['theme'], ['uid' => $this->profile_uid]);
-                       if (DBM::is_result($user) && !PConfig::get(local_user(), 'system', 'always_my_theme')) {
+                       $user = DBA::selectFirst('user', ['theme'], ['uid' => $this->profile_uid]);
+                       if (DBA::isResult($user) && !PConfig::get(local_user(), 'system', 'always_my_theme')) {
                                $page_theme = $user['theme'];
                        }
                }
 
-               if (!empty($_SESSION)) {
-                       $user_theme = defaults($_SESSION, 'theme', $system_theme);
-               } else {
-                       $user_theme = $system_theme;
-               }
+               $user_theme = Core\Session::get('theme', $system_theme);
 
                // Specific mobile theme override
-               if (($this->is_mobile || $this->is_tablet) && defaults($_SESSION, 'show-mobile', true)) {
+               if (($this->is_mobile || $this->is_tablet) && Core\Session::get('show-mobile', true)) {
                        $system_mobile_theme = Config::get('system', 'mobile-theme');
-                       $user_mobile_theme = defaults($_SESSION, 'mobile-theme', $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 !== '---') {