]> git.mxchange.org Git - friendica.git/blobdiff - src/App.php
Little fixes (#5414)
[friendica.git] / src / App.php
index 652b048260bf835e0006e076c96ead8e17e8f27b..e1843e5737dc99f318bf3f590d8e658a13c9c917 100644 (file)
@@ -34,9 +34,20 @@ require_once 'include/text.php';
  */
 class App
 {
-       const MODE_NORMAL = 0;
-       const MODE_INSTALL = 1;
-       const MODE_MAINTENANCE = 2;
+       const MODE_LOCALCONFIGPRESENT = 1;
+       const MODE_DBAVAILABLE = 2;
+       const MODE_DBCONFIGAVAILABLE = 4;
+       const MODE_MAINTENANCEDISABLED = 8;
+
+       /**
+        * @deprecated since version 2008.08 Use App->isInstallMode() instead to check for install mode.
+        */
+       const MODE_INSTALL = 0;
+
+       /**
+        * @deprecated since version 2008.08 Use the precise mode constant to check for a specific capability instead.
+        */
+       const MODE_NORMAL = App::MODE_LOCALCONFIGPRESENT | App::MODE_DBAVAILABLE | App::MODE_DBCONFIGAVAILABLE | App::MODE_MAINTENANCEDISABLED;
 
        public $module_loaded = false;
        public $module_class = null;
@@ -59,7 +70,7 @@ class App
        public $argv;
        public $argc;
        public $module;
-       public $mode = App::MODE_NORMAL;
+       public $mode = App::MODE_INSTALL;
        public $strings;
        public $basepath;
        public $urlpath;
@@ -139,17 +150,9 @@ class App
                        throw new Exception('Basepath ' . $basepath . ' isn\'t usable.');
                }
 
-               $this->basepath = rtrim($basepath, DIRECTORY_SEPARATOR);
-
-               $this->determineUrlPath();
-
-               $this->loadConfigFiles();
+               BaseObject::setApp($this);
 
-               $this->loadDatabase();
-
-               $this->determineMode();
-
-               $this->loadDefaultTimezone();
+               $this->basepath = rtrim($basepath, DIRECTORY_SEPARATOR);
 
                $this->performance['start'] = microtime(true);
                $this->performance['database'] = 0;
@@ -172,6 +175,25 @@ class App
                $this->callstack['rendering'] = [];
                $this->callstack['parser'] = [];
 
+               // The order of the following calls is important to ensure proper initialization
+               $this->loadConfigFiles();
+
+               $this->loadDatabase();
+
+               $this->determineMode();
+
+               $this->determineUrlPath();
+
+               Config::load();
+
+               if ($this->mode & self::MODE_DBAVAILABLE) {
+                       Core\Addon::loadHooks();
+
+                       $this->loadAddonConfig();
+               }
+
+               $this->loadDefaultTimezone();
+
                $this->page = [
                        'aside' => '',
                        'bottom' => '',
@@ -293,9 +315,16 @@ class App
                $this->register_template_engine('Friendica\Render\FriendicaSmartyEngine');
        }
 
+       /**
+        * 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 +337,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,6 +357,11 @@ 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')) {
@@ -326,6 +369,23 @@ class App
                }
        }
 
+       /**
+        * Tries to load the specified configuration file into the App->config array.
+        * Overwrites previously set values.
+        *
+        * 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
+        * @throws Exception
+        */
        public function loadConfigFile($filepath)
        {
                if (!file_exists($filepath)) {
@@ -340,24 +400,37 @@ class App
                        throw new Exception('Error parsing config file ' . $filepath);
                }
 
-               foreach($config as $category => $values) {
-                       foreach($values as $key => $value) {
+               foreach ($config as $category => $values) {
+                       foreach ($values as $key => $value) {
                                $this->setConfigValue($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');
                }
        }
 
+       /**
+        * 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 +446,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 +457,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,26 +472,43 @@ class App
                }
        }
 
+       /**
+        * Sets the App mode
+        *
+        * - App::MODE_INSTALL    : Either the database connection can't be established or the config table doesn't exist
+        * - App::MODE_MAINTENANCE: The maintenance mode has been set
+        * - App::MODE_NORMAL     : Normal run with all features enabled
+        *
+        * @return type
+        */
        private function determineMode()
        {
-               $this->mode = App::MODE_INSTALL;
+               $this->mode = 0;
+
+               if (!file_exists($this->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')
+                       && !file_exists($this->basepath . DIRECTORY_SEPARATOR . '.htconfig.php')) {
+                       return;
+               }
+
+               $this->mode |= App::MODE_LOCALCONFIGPRESENT;
 
-               // Missing DB connection
                if (!\dba::connected()) {
                        return;
                }
 
-               // Working DB connection, missing tables
+               $this->mode |= App::MODE_DBAVAILABLE;
+
                if (\dba::fetch_first("SHOW TABLES LIKE 'config'") === false) {
                        return;
                }
 
-               // Maintenance mode check
+               $this->mode |= App::MODE_DBCONFIGAVAILABLE;
+
                if (Config::get('system', 'maintenance')) {
-                       $this->mode = App::MODE_MAINTENANCE;
-               } else {
-                       $this->mode = App::MODE_NORMAL;
+                       return;
                }
+
+               $this->mode |= App::MODE_MAINTENANCEDISABLED;
        }
 
        public function loadDatabase()
@@ -430,27 +525,21 @@ 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);
@@ -458,7 +547,17 @@ class App
                \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');
+       }
+
+       /**
+        * Install mode is when the local config file is missing or the DB schema hasn't been installed yet.
+        *
+        * @return bool
+        */
+       public function isInstallMode()
+       {
+               return !($this->mode & App::MODE_LOCALCONFIGPRESENT) || !($this->mode & App::MODE_DBCONFIGAVAILABLE);
        }
 
        /**
@@ -913,7 +1012,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;
@@ -993,7 +1092,7 @@ class App
         *
         * @return bool Is the load reached?
         */
-       public function maxload_reached()
+       public function isMaxLoadReached()
        {
                if ($this->is_backend()) {
                        $process = 'backend';
@@ -1252,7 +1351,7 @@ class App
         */
        public function getCurrentTheme()
        {
-               if ($this->mode == App::MODE_INSTALL) {
+               if ($this->isInstallMode()) {
                        return '';
                }