diff --git a/core/default_settings/default_settings.php b/core/default_settings/default_settings.php index 362e769bd7..7900fe69ec 100644 --- a/core/default_settings/default_settings.php +++ b/core/default_settings/default_settings.php @@ -124,7 +124,7 @@ $sql .= "lower(default_setting_category) = :default_setting_category "; $parameters['default_setting_category'] = strtolower($default_setting_category); } - $database = new database; + $database = database::new(); $num_rows = $database->select($sql, $parameters ?? null, 'column'); //get the list @@ -148,7 +148,6 @@ } $sql .= order_by($order_by, $order, 'default_setting_category, default_setting_subcategory, default_setting_order', 'asc'); //$sql .= limit_offset($rows_per_page, $offset ?? ''); //$offset is always null - $database = new database; $default_settings = $database->select($sql, $parameters ?? null, 'all'); unset($sql, $parameters); @@ -173,7 +172,6 @@ $sql .= ") as quantity "; $sql .= "from v_default_settings as d1 "; $sql .= "order by d1.default_setting_category asc "; - $database = new database; $rows = $database->select($sql, $parameters ?? null, 'all'); if (!empty($rows) && @sizeof($rows) != 0) { foreach ($rows as $row) { @@ -462,7 +460,6 @@ $sql = "select * from v_menus "; $sql .= "where menu_uuid = :menu_uuid "; $parameters['menu_uuid'] = $row['default_setting_value']; - $database = new database; $sub_result = $database->select($sql, $parameters ?? null, 'all'); foreach ($sub_result as &$sub_row) { echo $sub_row["menu_language"]." - ".$sub_row["menu_name"]."\n"; diff --git a/resources/classes/config.php b/resources/classes/config.php index 4e404de0cd..e127f0b2bc 100644 --- a/resources/classes/config.php +++ b/resources/classes/config.php @@ -1,155 +1,345 @@ configuration = []; + + //check if the config file was found + if (empty($file)) { + //locate the conf file + $file = self::find(); + } + + //remember the fullpath and filename + $this->file = $file; + + //load the conf file + if (file_exists($file)) { + $this->read(); + } + + //set the server variables + $this->define_project_paths(); } /** - * Determine whether the config file exists - * @var string $db_type - type of database - * @var string $db_name - name of the database - * @var string $db_username - username to access the database - * @var string $db_password - password to access the database - * @var string $db_host - hostname of the database server - * @var string $db_path - path of the database file - * @var string $db_port - network port to connect to the database - * @var bool $db_secure - whether or not to connect with SSL - * @var string $db_cert_authority - location of certificate authority + * Magic method to allow backward compatibility for variables such as db_type. + *
This will allow using config object with the syntax of:
+ * $config = new config();
+ * $db_type = $config->db_type;
Note:
+ * The InvalidArgumentException is thrown if there is no such variable accessed such as:
+ * $config = new config();
+ * $db_function = $config->db_function();
+ *
This is ensure that any invalid code is detected and fixed.
+ * @param string $name Name of the object property + * @return string Returns the value as a string */ - public function get() { - //find the config_path - $config_path = $this->find(); + public function __get(string $name): string { + switch($name) { + case 'db_type': + case 'db_driver': + return $this->configuration['database.0.type'] ?? ''; + case 'db_path': + case 'path': + return $this->configuration['database.0.path'] ?? ''; + case 'db_host': + return $this->configuration['database.0.host'] ?? ''; + case 'db_port': + return $this->configuration['database.0.port'] ?? ''; + case 'db_name': + return $this->configuration['database.0.name'] ?? ''; + case 'db_sslmode': + return $this->configuration['database.0.sslmode'] ?? 'prefer'; + case 'db_cert_authority': + return $this->configuration['database.0.cert_authority'] ?? ''; + case 'db_secure': + return $this->configuration['database.0.secure'] ?? 'false'; + case 'db_username': + case 'username': + return $this->configuration['database.0.username'] ?? ''; + case 'db_password': + case 'password': + return $this->configuration['database.0.password'] ?? ''; + case 'db_file': + return $this->configuration['database.0.file'] ?? ''; + case 'config_path': + return $this->path(); + case 'config_filename': + return $this->filename(); + case 'config_path_and_filename': + case 'config_file': + return $this->path_and_filename(); + default: + if (property_exists($this, $name)) { + return $this->{$name}; + } + elseif (array_key_exists($name, $this->configuration)) { + return $this->configuration[$name]; + } + } + return ""; + } - //add the document root to the include path - $conf = parse_ini_file($config_path); - set_include_path($conf['document.root']); + /** + * Returns the string representation of the configuration file + * @return string configuration + */ + public function __toString(): string { + $string_builder = ""; + foreach ($this->configuration as $key => $value) { + $string_builder .= "$key = '$value'\n"; + } + return $string_builder; + } - //check if the config file exists - $config_exists = file_exists($config_path) ? true : false; - + // loads the config.conf file + public function read() { + + //check if include is needed + if (substr($this->file, 0, -4) === '.php') { + //allow global variables to be set in the old config.php file + global $db_type, $db_host, $db_port, $db_name, $db_username, $db_password, $db_path; + global $db_sslmode, $db_secure, $db_cert_authority; + + //load the config.php file + require_once $this->file; + + //convert the old properties to the new standard + if (isset($db_type)) { + $this->configuration['database.0.type'] = $db_type; + } else { + $this->configuration['database.0.type'] = 'pgsql'; + } + if (isset($db_path)) { + $this->configuration['database.0.path'] = $db_path; + } else { + $this->configuration['database.0.path'] = ''; + } + if (isset($db_host)) { + $this->configuration['database.0.host'] = $db_host; + } + if (isset($db_port)) { + $this->configuration['database.0.port'] = $db_port; + } + if (isset($db_name)) { + $this->configuration['database.0.name'] = $db_name; + } + if (isset($db_username)) { + $this->configuration['database.0.username'] = $db_username; + } + if (isset($db_password)) { + $this->configuration['database.0.password'] = $db_password; + } + if (isset($db_sslmode)) { + $this->configuration['database.0.sslmode'] = $db_sslmode; + } else { + $this->configuration['database.0.sslmode'] = 'prefer'; + } + if (isset($db_secure)) { + $this->configuration['database.0.secure'] = $db_secure; + } + if (isset($db_cert_authority)) { + $this->configuration['database.0.cert_authority'] = $db_cert_authority; + } + + //remove from the global namespace + unset($db_type, $db_host, $db_port, $db_name, $db_username, $db_password, $db_sslmode, $db_secure, $db_cert_authority); + } + else { + //save the loaded and parsed conf file to the object + $this->configuration = parse_ini_file($this->file); + } + + } + + // set project paths if not already defined + private function define_project_paths() { + // Load the document root + $doc_root = $this->get('document.root', '/var/www/fusionpbx'); + $doc_path = $this->get('document.path', ''); //set the server variables and define project path constant - $_SERVER["DOCUMENT_ROOT"] = $conf['document.root']; - $_SERVER["PROJECT_ROOT"] = $conf['document.root']; - $_SERVER["PROJECT_PATH"] = $conf['project.path']; - if (isset($conf['project.path'])) { - $_SERVER["PROJECT_ROOT"] = $conf['document.root'].'/'.$conf['project.path']; - if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $conf['document.root'].'/'.$conf['project.path']); } - if (!defined('PROJECT_PATH')) { define("PROJECT_PATH", $conf['project.path']); } + if (!empty($doc_path)) { + if (!defined('PROJECT_PATH')) { define("PROJECT_PATH", $doc_path); } + if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $doc_root.'/'.$doc_path); } } else { - if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $conf['document.root']); } if (!defined('PROJECT_PATH')) { define("PROJECT_PATH", ''); } + if (!defined('PROJECT_ROOT')) { define("PROJECT_ROOT", $doc_root); } } - //add the database settings - $this->db_type = $conf['database.0.type']; - $this->db_name = $conf['database.0.name']; - $this->db_username = $conf['database.0.username']; - $this->db_password = $conf['database.0.password']; - $this->db_sslmode = $conf['database.0.sslmode'] ?? ''; - $this->db_secure = $conf['database.0.secure'] ?? ''; - $this->db_cert_authority = $conf['database.0.db_cert_authority'] ?? ''; - $this->db_host = $conf['database.0.host']; - $this->db_path = $conf['database.0.path'] ?? ''; - $this->db_port = $conf['database.0.port']; + // internal definitions to the framework + $_SERVER["PROJECT_PATH"] = PROJECT_PATH; + $_SERVER["PROJECT_ROOT"] = PROJECT_ROOT; + // tell php where the framework is + $_SERVER["DOCUMENT_ROOT"] = PROJECT_ROOT; + + // have php search for any libraries in the now defined root + set_include_path(PROJECT_ROOT); } /** - * Find the path to the config.php + * Find the path to the config.conf file * @var string $config_path - full path to the config.php file */ - public function find() { + public static function find(): string { + //define the file variable + $file = ""; //find the file - if (file_exists("/etc/fusionpbx/config.conf")) { - $this->config_path = "/etc/fusionpbx/config.conf"; - } - elseif (file_exists("/usr/local/etc/fusionpbx/config.conf")) { - $this->config_path = "/usr/local/etc/fusionpbx/config.conf"; - } - elseif (file_exists($_SERVER["PROJECT_ROOT"]."/resources/config.php")) { - $this->config_path = $_SERVER["PROJECT_ROOT"]."/resources/config.php"; - } - elseif (file_exists("/etc/fusionpbx/config.php")) { - $this->config_path = "/etc/fusionpbx/config.php"; - } - elseif (file_exists("/usr/local/etc/fusionpbx/config.php")) { - $this->config_path = "/usr/local/etc/fusionpbx/config.php"; - } - else { - $this->config_path = ''; - } - - //return the path - return $this->config_path; + if (file_exists("/etc/fusionpbx/config.conf")) { + $file = "/etc/fusionpbx/config.conf"; + } + elseif (file_exists("/usr/local/etc/fusionpbx/config.conf")) { + $file = "/usr/local/etc/fusionpbx/config.conf"; + } + elseif (file_exists("/etc/fusionpbx/config.php")) { + $file = "/etc/fusionpbx/config.php"; + } + elseif (file_exists("/usr/local/etc/fusionpbx/config.php")) { + $file = "/usr/local/etc/fusionpbx/config.php"; + } + elseif (file_exists(dirname(__DIR__, 2) . "/resources/config.php")) { + //use the current web directory to find it as a last resort + $file = "/var/www/fusionpbx/resources/config.php"; + } + return $file; } /** - * Determine whether the config file exists + * Get a configuration value using a key in the configuration file + * @param string|null $key Match key on the left hand side of the '=' in the config file. If $key is null the default value is returned + * @param string $default_value if no matching key is found, then this value will be returned + * @return string returns a value in the config.conf file or an empty string */ - public function exists() { - $this->find(); - if (!empty($this->config_path)) { - return true; + public function get(string $key, string $default_value = ''): string { + if (!empty($this->__get($key))) { + return $this->__get($key); } - else { - return false; + return $default_value; + } + + /** + * Returns the config path or an empty string + * @return string + */ + public function path(): string { + return dirname($this->file); + } + + /** + * Returns the file name only of the configuration file + * @return string + */ + public function filename(): string { + return basename($this->file); + } + + /** + * Returns the path and the file name + * @return string + */ + public function path_and_filename(): string { + return $this->file; + } + + /** + * Returns if the config class has a loaded configuration or not + * @return bool True if configuration has loaded and false if it is empty + */ + public function is_empty(): bool { + return count($this->configuration) === 0; + } + + /** + * Returns the array of configuration settings + * @return array + */ + public function configuration(): array { + return $this->configuration; + } + + /** + * Ensures the configuration file is loaded only once + * @return config + */ + public static function load(?string $file = ''): config { + if (self::$config === null) { + self::$config = new config($file); } + return self::$config; } } -/* -$config = new config; -$config_exists = $config->exists(); -$config_path = $config->find(); -$config->get(); -$db_type = $config->db_type; -$db_name = $config->db_name; -$db_username = $config->db_username; -$db_password = $config->db_password; -$db_host = $config->db_host; -$db_path = $config->db_path; -$db_port = $config->db_port; -echo "config_path: ".$config_path."\n"; -if ($config_exists) { - echo "config_exists: true\n"; -} else { - echo "config_exists: false\n"; -} -echo "db_type: ".$db_type."\n"; -echo "db_name: ".$db_name."\n"; -echo "db_username: ".$db_username."\n"; -echo "db_password: ".$db_password."\n"; -echo "db_host: ".$db_host."\n"; -echo "db_path: ".$db_path."\n"; -echo "db_port: ".$db_port."\n"; -*/ -?> +/* +//Examples: +//~~~~~~~~ +$config = new config; +echo "Config path: " . $config->path() . "\n"; +echo "Config file: " . $config->filename() . "\n"; +echo "Full path and filename: " . $config->path_and_filename() . "\n"; + +// show old style configuration options +echo "db_type: ".$config->db_type."\n"; +echo "db_name: ".$config->db_name."\n"; +echo "db_username: ".$config->db_username."\n"; +echo "db_password: ".$config->db_password."\n"; +echo "db_host: ".$config->db_host."\n"; +echo "db_path: ".$config->db_path."\n"; +echo "db_port: ".$config->db_port."\n"; + +// use current style configuration options even on old config.php +echo "database.0.type: " . $config->get('database.0.type') . "\n"; + +// use a default value +echo "admin.name: " . $config->value('admin.name', 'admin') . "\n"; + +// get all configuration options by printing the object +echo "config settings: " . $config . "\n"; + +// save the configuration options to a file +file_put_contents('/etc/fusionpbx/config.conf', $config); + +// get all configuration options as an array +var_dump($config->configuration()); + +//*/ diff --git a/resources/classes/database.php b/resources/classes/database.php index cbdfa28096..732caca5e8 100644 --- a/resources/classes/database.php +++ b/resources/classes/database.php @@ -256,24 +256,61 @@ */ public $message; + /** + * Config object used to get the database connection params + * @var config + */ + private $config; + + /** + * SSL Mode used to connect to the database + * @var string prefer or verify-ca. Default is 'prefer' + */ + public $ssl_mode; + + /** + * Singleton type class + * @var database + */ + private $database; + /** * Called when the object is created + * @param array $params Optional */ public function __construct(array $params = []) { - //set the domain_uuid - if (isset($params['domain_uuid']) && is_uuid($params['domain_uuid'])) { - $this->domain_uuid = $domain_uuid; + if (isset($params['config'])) { + $config = $params['config']; } - elseif (isset($_SESSION['domain_uuid']) && is_uuid($_SESSION['domain_uuid'])) { - $this->domain_uuid = $_SESSION['domain_uuid']; + else { + $config = new config(); } - //set the user_uuid - if (isset($params['user_uuid']) && is_uuid($params['user_uuid'])) { - $this->user_uuid = $user_uuid; + //driver and type point to the same value + $this->driver = $config->get('database.0.type', 'pgsql'); + $this->driver = $config->get('database.0.type', 'pgsql'); + $this->type = $config->get('database.0.type', 'pgsql'); + $this->host = $config->get('database.0.host', '127.0.0.1'); + $this->port = $config->get('database.0.port', '5432'); + $this->username = $config->get('database.0.username', 'fusionpbx'); + $this->password = $config->get('database.0.password', 'fusionpbx'); + $this->db_name = $config->get('database.0.name', 'fusionpbx'); + $this->db_secure = $config->get('database.0.secure', ''); + $this->db_cert_authority = $config->get('database.0.cert_authority', ''); + $this->ssl_mode = $config->get('database.0.ssl_mode', ''); + + //save the reference to the single instance of the config to this object + $this->config = $config; + + //connect to the database now + $this->connect(); + + if (!isset($this->domain_uuid) && isset($_SESSION['domain_uuid'])) { + $this->domain_uuid = $_SESSION['domain_uuid']; } - elseif (isset($_SESSION['user_uuid']) && is_uuid($_SESSION['user_uuid'])) { - $this->user_uuid = $_SESSION['user_uuid']; + //allow passed domain_uuid in the constructor to override the session domain + if (isset($params['domain_uuid'])) { + $this->domain_uuid = $params['domain_uuid']; } } @@ -420,9 +457,6 @@ */ public function connect() { - //includes files - require dirname(__DIR__, 2) . "/resources/require.php"; - //get the database connection settings //$db_type = $conf['database.0.type']; //$db_host = $conf['database.0.host']; @@ -523,7 +557,7 @@ if (!empty($this->host)) { if (empty($this->port)) { $this->port = "5432"; } if ($this->db_secure === true) { - $this->db = new PDO("pgsql:host=$this->host port=$this->port dbname=$this->db_name user=$this->username password=$this->password sslmode=verify-ca sslrootcert=$this->db_cert_authority"); + $this->db = new PDO("pgsql:host=$this->host port=$this->port dbname=$this->db_name user=$this->username password=$this->password sslmode=$this->ssl_mode sslrootcert=$this->db_cert_authority"); } else { $this->db = new PDO("pgsql:host=$this->host port=$this->port dbname=$this->db_name user=$this->username password=$this->password"); @@ -669,8 +703,12 @@ //if unable to connect to the database if (!$this->db) { + $backtrace = debug_backtrace(); echo "Connection Failed"; + print_r($backtrace); + echo ""; exit; } @@ -3043,9 +3081,11 @@ * @see database::connect() */ public static function new() { - $db = new database(); - $db->connect(); - return $db; + if (self::$database === null) + self::$database = new database(); + self::$database->connect(); + } + return self::$database; } } //class database @@ -3111,4 +3151,4 @@ echo $database->count(); */ -?> \ No newline at end of file +?> diff --git a/resources/classes/domains.php b/resources/classes/domains.php index bedc63dd91..549fbd7413 100644 --- a/resources/classes/domains.php +++ b/resources/classes/domains.php @@ -607,8 +607,7 @@ if (!class_exists('domains')) { //get the variables $config = new config; - $config_path = $config->find(); - $config->get(); + $config_path = $config->config_file; //get the list of installed apps from the core and app directories (note: GLOB_BRACE doesn't work on some systems) $config_list_1 = glob($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH."/*/*/app_config.php"); diff --git a/resources/functions.php b/resources/functions.php index 71f33e2f1f..e5c30bbf88 100644 --- a/resources/functions.php +++ b/resources/functions.php @@ -324,7 +324,8 @@ if (!function_exists('permission_exists')) { function permission_exists($permission_name, $operator = 'or') { - $permission = new permissions; + $database = database::new(); + $permission = new permissions($database); return $permission->exists($permission_name); }