From 065340dc320a165f90b0a1f81e104ebfd1aee087 Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Fri, 5 Oct 2018 22:36:09 +0200
Subject: [PATCH] Creating Friendica\App\Mode for encapsulating the App Mode

---
 bin/auth_ejabberd.php               |   2 +-
 index.php                           |  12 ++--
 src/App.php                         |  72 ++-----------------
 src/App/Mode.php                    | 103 ++++++++++++++++++++++++++++
 src/Core/Config.php                 |  10 +--
 src/Core/Console/ArchiveContact.php |   2 +-
 src/Core/Console/Cache.php          |   2 +-
 src/Core/Console/Config.php         |   4 +-
 src/Core/PConfig.php                |  10 +--
 9 files changed, 128 insertions(+), 89 deletions(-)
 create mode 100644 src/App/Mode.php

diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php
index 7ad28c96f5..55917bf6d9 100755
--- a/bin/auth_ejabberd.php
+++ b/bin/auth_ejabberd.php
@@ -54,7 +54,7 @@ require_once "include/dba.php";
 
 $a = new App(dirname(__DIR__));
 
-if ($a->mode === App::MODE_NORMAL) {
+if (App\Mode::isNormal()) {
 	$oAuth = new ExAuth();
 	$oAuth->readStdin();
 }
\ No newline at end of file
diff --git a/index.php b/index.php
index bccdebe7b0..0785faf585 100644
--- a/index.php
+++ b/index.php
@@ -36,7 +36,7 @@ $a->backend = false;
 require_once "include/dba.php";
 
 // Missing DB connection: ERROR
-if ($a->mode & App::MODE_LOCALCONFIGPRESENT && !($a->mode & App::MODE_DBAVAILABLE)) {
+if (App\Mode::has(App\Mode::LOCALCONFIGPRESENT) && !App\Mode::has(App\Mode::DBAVAILABLE)) {
 	System::httpExit(500, ['title' => 'Error 500 - Internal Server Error', 'description' => 'Apologies but the website is unavailable at the moment.']);
 }
 
@@ -48,7 +48,7 @@ if ($a->isMaxProcessesReached() || $a->isMaxLoadReached()) {
 	System::httpExit(503, ['title' => 'Error 503 - Service Temporarily Unavailable', 'description' => 'System is currently overloaded. Please try again later.']);
 }
 
-if (!$a->isInstallMode()) {
+if (!App\Mode::isInstall()) {
 	if (Config::get('system', 'force_ssl') && ($a->get_scheme() == "http")
 		&& (intval(Config::get('system', 'ssl_policy')) == SSL_POLICY_FULL)
 		&& (substr(System::baseUrl(), 0, 8) == "https://")
@@ -107,7 +107,7 @@ if (!empty($_SESSION['language']) && $_SESSION['language'] !== $lang) {
 	L10n::loadTranslationTable($lang);
 }
 
-if (!empty($_GET['zrl']) && $a->mode == App::MODE_NORMAL) {
+if (!empty($_GET['zrl']) && App\Mode::isNormal()) {
 	$a->query_string = Profile::stripZrls($a->query_string);
 	if (!local_user()) {
 		// Only continue when the given profile link seems valid
@@ -130,7 +130,7 @@ if (!empty($_GET['zrl']) && $a->mode == App::MODE_NORMAL) {
 	}
 }
 
-if (!empty($_GET['owt']) && $a->mode == App::MODE_NORMAL) {
+if (!empty($_GET['owt']) && App\Mode::isNormal()) {
 	$token = $_GET['owt'];
 	$a->query_string = Profile::stripQueryParam($a->query_string, 'owt');
 	Profile::openWebAuthInit($token);
@@ -167,7 +167,7 @@ $_SESSION['last_updated'] = defaults($_SESSION, 'last_updated', []);
 // but we need "view" module for stylesheet
 if ($a->isInstallMode() && $a->module!="view") {
 	$a->module = 'install';
-} elseif (!($a->mode & App::MODE_MAINTENANCEDISABLED) && $a->module != "view") {
+} elseif (!App\Mode::has(App\Mode::MAINTENANCEDISABLED) && $a->module != "view") {
 	$a->module = 'maintenance';
 } else {
 	check_url($a);
@@ -320,7 +320,7 @@ if (file_exists($theme_info_file)) {
 
 /* initialise content region */
 
-if ($a->mode == App::MODE_NORMAL) {
+if (App\Mode::isNormal()) {
 	Addon::callHooks('page_content_top', $a->page['content']);
 }
 
diff --git a/src/App.php b/src/App.php
index 7622a1a0ce..f09c030b6c 100644
--- a/src/App.php
+++ b/src/App.php
@@ -6,6 +6,7 @@ namespace Friendica;
 
 use Detection\MobileDetect;
 use Exception;
+use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
@@ -31,21 +32,6 @@ require_once 'include/text.php';
  */
 class App
 {
-	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;
 	public $query_string = '';
@@ -67,7 +53,6 @@ class App
 	public $argv;
 	public $argc;
 	public $module;
-	public $mode = App::MODE_INSTALL;
 	public $strings;
 	public $basepath;
 	public $urlpath;
@@ -326,13 +311,13 @@ class App
 
 		$this->loadDatabase();
 
-		$this->determineMode();
+		App\Mode::determine($this->basepath);
 
 		$this->determineUrlPath();
 
 		Config::load();
 
-		if ($this->mode & self::MODE_DBAVAILABLE) {
+		if (App\Mode::has(App\Mode::DBAVAILABLE)) {
 			Core\Addon::loadHooks();
 
 			$this->loadAddonConfig();
@@ -518,45 +503,6 @@ 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 = 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;
-
-		if (!DBA::connected()) {
-			return;
-		}
-
-		$this->mode |= App::MODE_DBAVAILABLE;
-
-		if (DBA::fetchFirst("SHOW TABLES LIKE 'config'") === false) {
-			return;
-		}
-
-		$this->mode |= App::MODE_DBCONFIGAVAILABLE;
-
-		if (Config::get('system', 'maintenance')) {
-			return;
-		}
-
-		$this->mode |= App::MODE_MAINTENANCEDISABLED;
-	}
-
 	public function loadDatabase()
 	{
 		if (DBA::connected()) {
@@ -596,16 +542,6 @@ class App
 		$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);
-	}
-
 	/**
 	 * @brief Returns the base filesystem path of the App
 	 *
@@ -1467,7 +1403,7 @@ class App
 	 */
 	public function getCurrentTheme()
 	{
-		if ($this->isInstallMode()) {
+		if (App\Mode::isInstall()) {
 			return '';
 		}
 
diff --git a/src/App/Mode.php b/src/App/Mode.php
new file mode 100644
index 0000000000..189573e378
--- /dev/null
+++ b/src/App/Mode.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Friendica\App;
+
+use Friendica\Core\Config;
+use Friendica\Database\DBA;
+
+/**
+ * Mode of the current Friendica Node
+ *
+ * @package Friendica\App
+ */
+class Mode
+{
+	const LOCALCONFIGPRESENT = 1;
+	const DBAVAILABLE = 2;
+	const DBCONFIGAVAILABLE = 4;
+	const MAINTENANCEDISABLED = 8;
+
+	/***
+	 * @var int the mode of this Application
+	 *
+	 * Default is 0 (= not set)
+	 */
+	private static $mode = 0;
+
+	/**
+	 * 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
+	 *
+	 * @param string $basepath the Basepath of the Application
+	 *
+	 */
+	public static function determine($basepath)
+	{
+		self::$mode = 0;
+
+		if (!file_exists($basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')
+			&& !file_exists($basepath . DIRECTORY_SEPARATOR . '.htconfig.php')) {
+			return;
+		}
+
+		self::$mode |= Mode::LOCALCONFIGPRESENT;
+
+		if (!DBA::connected()) {
+			return;
+		}
+
+		self::$mode |= Mode::DBAVAILABLE;
+
+		if (DBA::fetchFirst("SHOW TABLES LIKE 'config'") === false) {
+			return;
+		}
+
+		self::$mode |= Mode::DBCONFIGAVAILABLE;
+
+		if (Config::get('system', 'maintenance')) {
+			return;
+		}
+
+		self::$mode |= Mode::MAINTENANCEDISABLED;
+	}
+
+	/**
+	 * Checks, if the Friendica Node has the given mode
+	 *
+	 * @param int $mode A mode to test
+	 *
+	 * @return bool returns true, if the mode is set
+	 */
+	public static function has($mode)
+	{
+		return self::$mode & $mode;
+	}
+
+
+	/**
+	 * Install mode is when the local config file is missing or the DB schema hasn't been installed yet.
+	 *
+	 * @return bool
+	 */
+	public static function isInstall()
+	{
+		return !self::has(Mode::LOCALCONFIGPRESENT) ||
+			!self::has(MODE::DBCONFIGAVAILABLE);
+	}
+
+	/**
+	 * Normal mode is when the local config file is set, the DB schema is installed and the maintenance mode is off.
+	 *
+	 * @return bool
+	 */
+	public static function isNormal()
+	{
+		return self::has(Mode::LOCALCONFIGPRESENT) &&
+			self::has(Mode::DBAVAILABLE) &&
+			self::has(Mode::DBCONFIGAVAILABLE) &&
+			self::has(Mode::MAINTENANCEDISABLED);
+	}
+}
diff --git a/src/Core/Config.php b/src/Core/Config.php
index f71522d068..f2b0d12ab0 100644
--- a/src/Core/Config.php
+++ b/src/Core/Config.php
@@ -31,7 +31,7 @@ class Config extends BaseObject
 	public static function init()
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return;
 		}
 
@@ -55,7 +55,7 @@ class Config extends BaseObject
 	public static function load($family = "config")
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return;
 		}
 
@@ -88,7 +88,7 @@ class Config extends BaseObject
 	public static function get($family, $key, $default_value = null, $refresh = false)
 	{
 		// Database isn't ready or populated yet, fallback to file config
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return self::getApp()->getConfigValue($family, $key, $default_value);
 		}
 
@@ -116,7 +116,7 @@ class Config extends BaseObject
 	public static function set($family, $key, $value)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return false;
 		}
 
@@ -141,7 +141,7 @@ class Config extends BaseObject
 	public static function delete($family, $key)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return false;
 		}
 
diff --git a/src/Core/Console/ArchiveContact.php b/src/Core/Console/ArchiveContact.php
index acdacbed1d..8a6bc1f7bf 100644
--- a/src/Core/Console/ArchiveContact.php
+++ b/src/Core/Console/ArchiveContact.php
@@ -56,7 +56,7 @@ HELP;
 			throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
 		}
 
-		if ($a->mode === App::MODE_INSTALL) {
+		if (App\Mode::isInstall()) {
 			throw new RuntimeException('Friendica isn\'t properly installed yet.');
 		}
 
diff --git a/src/Core/Console/Cache.php b/src/Core/Console/Cache.php
index d0bc427dee..2d3508894a 100644
--- a/src/Core/Console/Cache.php
+++ b/src/Core/Console/Cache.php
@@ -65,7 +65,7 @@ HELP;
 			$this->out('Options: ' . var_export($this->options, true));
 		}
 
-		if (!($a->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			$this->out('Database isn\'t ready or populated yet, database cache won\'t be available');
 		}
 
diff --git a/src/Core/Console/Config.php b/src/Core/Console/Config.php
index db436b8394..d67f6cbb96 100644
--- a/src/Core/Console/Config.php
+++ b/src/Core/Console/Config.php
@@ -84,7 +84,7 @@ HELP;
 			throw new CommandArgsException('Too many arguments');
 		}
 
-		if (!($a->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			$this->out('Database isn\'t ready or populated yet, showing file config only');
 		}
 
@@ -143,7 +143,7 @@ HELP;
 		if (count($this->args) == 0) {
 			Core\Config::load();
 
-			if (Core\Config::get('system', 'config_adapter') == 'jit' && $a->mode & App::MODE_DBCONFIGAVAILABLE) {
+			if (Core\Config::get('system', 'config_adapter') == 'jit' && App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 				$this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only');
 			}
 
diff --git a/src/Core/PConfig.php b/src/Core/PConfig.php
index 2b66189300..3c48a568cb 100644
--- a/src/Core/PConfig.php
+++ b/src/Core/PConfig.php
@@ -30,7 +30,7 @@ class PConfig extends BaseObject
 	public static function init($uid)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return;
 		}
 
@@ -55,7 +55,7 @@ class PConfig extends BaseObject
 	public static function load($uid, $family)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return;
 		}
 
@@ -84,7 +84,7 @@ class PConfig extends BaseObject
 	public static function get($uid, $family, $key, $default_value = null, $refresh = false)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return;
 		}
 
@@ -113,7 +113,7 @@ class PConfig extends BaseObject
 	public static function set($uid, $family, $key, $value)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return false;
 		}
 
@@ -139,7 +139,7 @@ class PConfig extends BaseObject
 	public static function delete($uid, $family, $key)
 	{
 		// Database isn't ready or populated yet
-		if (!(self::getApp()->mode & App::MODE_DBCONFIGAVAILABLE)) {
+		if (!App\Mode::has(App\Mode::DBCONFIGAVAILABLE)) {
 			return false;
 		}