mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2025-12-30 00:53:50 +00:00
Documentation, format class, no modification. (#7628)
This commit is contained in:
@@ -27,8 +27,6 @@
|
|||||||
/**
|
/**
|
||||||
* authentication
|
* authentication
|
||||||
*
|
*
|
||||||
* @method validate uses authentication plugins to check if a user is authorized to login
|
|
||||||
* @method get_domain used to get the domain name from the URL or username and then sets both domain_name and domain_uuid
|
|
||||||
*/
|
*/
|
||||||
class authentication {
|
class authentication {
|
||||||
|
|
||||||
@@ -71,168 +69,172 @@ class authentication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* validate uses authentication plugins to check if a user is authorized to login
|
* validate uses authentication plugins to check if a user is authorized to login
|
||||||
|
*
|
||||||
* @return array|false [plugin] => last plugin used to authenticate the user [authorized] => true or false
|
* @return array|false [plugin] => last plugin used to authenticate the user [authorized] => true or false
|
||||||
*/
|
*/
|
||||||
public function validate() {
|
public function validate() {
|
||||||
|
|
||||||
//set default return array as null
|
//set default return array as null
|
||||||
$result = null;
|
$result = null;
|
||||||
|
|
||||||
//use a login message when a login attempt fails
|
//use a login message when a login attempt fails
|
||||||
$failed_login_message = null;
|
$failed_login_message = null;
|
||||||
|
|
||||||
//get the domain_name and domain_uuid
|
//get the domain_name and domain_uuid
|
||||||
if (!isset($this->domain_name) || !isset($this->domain_uuid)) {
|
if (!isset($this->domain_name) || !isset($this->domain_uuid)) {
|
||||||
$this->get_domain();
|
$this->get_domain();
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a settings object to pass to plugins
|
//create a settings object to pass to plugins
|
||||||
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid]);
|
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid]);
|
||||||
|
|
||||||
//set the default authentication method to the database
|
//set the default authentication method to the database
|
||||||
if (empty($_SESSION['authentication']['methods']) || !is_array($_SESSION['authentication']['methods'])) {
|
if (empty($_SESSION['authentication']['methods']) || !is_array($_SESSION['authentication']['methods'])) {
|
||||||
$_SESSION['authentication']['methods'][] = 'database';
|
$_SESSION['authentication']['methods'][] = 'database';
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the database as the default plugin
|
//set the database as the default plugin
|
||||||
if (!isset($_SESSION['authentication']['methods'])) {
|
if (!isset($_SESSION['authentication']['methods'])) {
|
||||||
$_SESSION['authentication']['methods'][] = 'database';
|
$_SESSION['authentication']['methods'][] = 'database';
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if contacts app exists
|
//check if contacts app exists
|
||||||
$contacts_exists = file_exists(dirname(__DIR__, 4) . '/core/contacts/');
|
$contacts_exists = file_exists(dirname(__DIR__, 4) . '/core/contacts/');
|
||||||
|
|
||||||
//use the authentication plugins
|
//use the authentication plugins
|
||||||
foreach ($_SESSION['authentication']['methods'] as $name) {
|
foreach ($_SESSION['authentication']['methods'] as $name) {
|
||||||
//already processed the plugin move to the next plugin
|
//already processed the plugin move to the next plugin
|
||||||
if (!empty($_SESSION['authentication']['plugin'][$name]['authorized']) && $_SESSION['authentication']['plugin'][$name]['authorized']) {
|
if (!empty($_SESSION['authentication']['plugin'][$name]['authorized']) && $_SESSION['authentication']['plugin'][$name]['authorized']) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//prepare variables
|
||||||
|
$class_name = "plugin_" . $name;
|
||||||
|
$base = __DIR__ . "/plugins";
|
||||||
|
$plugin = $base . "/" . $name . ".php";
|
||||||
|
|
||||||
|
//process the plugin
|
||||||
|
if (file_exists($plugin)) {
|
||||||
|
//run the plugin
|
||||||
|
$object = new $class_name();
|
||||||
|
$object->domain_name = $this->domain_name;
|
||||||
|
$object->domain_uuid = $this->domain_uuid;
|
||||||
|
if ($name == 'database' && isset($this->key)) {
|
||||||
|
$object->key = $this->key;
|
||||||
|
}
|
||||||
|
if ($name == 'database' && isset($this->username)) {
|
||||||
|
$object->username = $this->username;
|
||||||
|
$object->password = $this->password;
|
||||||
|
}
|
||||||
|
//initialize the plugin send the authentication object and settings
|
||||||
|
$array = $object->$name($this, $this->settings);
|
||||||
|
|
||||||
|
//build a result array
|
||||||
|
if (!empty($array) && is_array($array)) {
|
||||||
|
$result['plugin'] = $array["plugin"];
|
||||||
|
$result['domain_name'] = $array["domain_name"];
|
||||||
|
$result['username'] = $array["username"];
|
||||||
|
$result['user_uuid'] = $array["user_uuid"];
|
||||||
|
$result['contact_uuid'] = $array["contact_uuid"];
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$result["contact_organization"] = $array["contact_organization"] ?? '';
|
||||||
|
$result["contact_name_given"] = $array["contact_name_given"] ?? '';
|
||||||
|
$result["contact_name_family"] = $array["contact_name_family"] ?? '';
|
||||||
|
$result["contact_image"] = $array["contact_image"] ?? '';
|
||||||
|
}
|
||||||
|
$result['domain_uuid'] = $array["domain_uuid"];
|
||||||
|
$result['authorized'] = $array["authorized"];
|
||||||
|
|
||||||
|
//set the domain_uuid
|
||||||
|
$this->domain_uuid = $array["domain_uuid"];
|
||||||
|
|
||||||
|
//set the user_uuid
|
||||||
|
$this->user_uuid = $array["user_uuid"];
|
||||||
|
|
||||||
|
//save the result to the authentication plugin
|
||||||
|
$_SESSION['authentication']['plugin'][$name] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//prepare variables
|
//plugin authorized false
|
||||||
$class_name = "plugin_".$name;
|
if (!$result['authorized']) {
|
||||||
$base = __DIR__ . "/plugins";
|
break;
|
||||||
$plugin = $base."/".$name.".php";
|
|
||||||
|
|
||||||
//process the plugin
|
|
||||||
if (file_exists($plugin)) {
|
|
||||||
//run the plugin
|
|
||||||
$object = new $class_name();
|
|
||||||
$object->domain_name = $this->domain_name;
|
|
||||||
$object->domain_uuid = $this->domain_uuid;
|
|
||||||
if ($name == 'database' && isset($this->key)) {
|
|
||||||
$object->key = $this->key;
|
|
||||||
}
|
|
||||||
if ($name == 'database' && isset($this->username)) {
|
|
||||||
$object->username = $this->username;
|
|
||||||
$object->password = $this->password;
|
|
||||||
}
|
|
||||||
//initialize the plugin send the authentication object and settings
|
|
||||||
$array = $object->$name($this, $this->settings);
|
|
||||||
|
|
||||||
//build a result array
|
|
||||||
if (!empty($array) && is_array($array)) {
|
|
||||||
$result['plugin'] = $array["plugin"];
|
|
||||||
$result['domain_name'] = $array["domain_name"];
|
|
||||||
$result['username'] = $array["username"];
|
|
||||||
$result['user_uuid'] = $array["user_uuid"];
|
|
||||||
$result['contact_uuid'] = $array["contact_uuid"];
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$result["contact_organization"] = $array["contact_organization"] ?? '';
|
|
||||||
$result["contact_name_given"] = $array["contact_name_given"] ?? '';
|
|
||||||
$result["contact_name_family"] = $array["contact_name_family"] ?? '';
|
|
||||||
$result["contact_image"] = $array["contact_image"] ?? '';
|
|
||||||
}
|
|
||||||
$result['domain_uuid'] = $array["domain_uuid"];
|
|
||||||
$result['authorized'] = $array["authorized"];
|
|
||||||
|
|
||||||
//set the domain_uuid
|
|
||||||
$this->domain_uuid = $array["domain_uuid"];
|
|
||||||
|
|
||||||
//set the user_uuid
|
|
||||||
$this->user_uuid = $array["user_uuid"];
|
|
||||||
|
|
||||||
//save the result to the authentication plugin
|
|
||||||
$_SESSION['authentication']['plugin'][$name] = $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//plugin authorized false
|
|
||||||
if (!$result['authorized']) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//make sure all plugins are in the array
|
//make sure all plugins are in the array
|
||||||
if (!empty($_SESSION['authentication']['methods'])) {
|
if (!empty($_SESSION['authentication']['methods'])) {
|
||||||
foreach ($_SESSION['authentication']['methods'] as $name) {
|
foreach ($_SESSION['authentication']['methods'] as $name) {
|
||||||
if (!isset($_SESSION['authentication']['plugin'][$name]['authorized'])) {
|
if (!isset($_SESSION['authentication']['plugin'][$name]['authorized'])) {
|
||||||
$_SESSION['authentication']['plugin'][$name]['plugin'] = $name;
|
$_SESSION['authentication']['plugin'][$name]['plugin'] = $name;
|
||||||
$_SESSION['authentication']['plugin'][$name]['domain_name'] = $_SESSION['domain_name'];
|
$_SESSION['authentication']['plugin'][$name]['domain_name'] = $_SESSION['domain_name'];
|
||||||
$_SESSION['authentication']['plugin'][$name]['domain_uuid'] = $_SESSION['domain_uuid'];
|
$_SESSION['authentication']['plugin'][$name]['domain_uuid'] = $_SESSION['domain_uuid'];
|
||||||
$_SESSION['authentication']['plugin'][$name]['username'] = $_SESSION['username'];
|
$_SESSION['authentication']['plugin'][$name]['username'] = $_SESSION['username'];
|
||||||
$_SESSION['authentication']['plugin'][$name]['user_uuid'] = $_SESSION['user_uuid'];
|
$_SESSION['authentication']['plugin'][$name]['user_uuid'] = $_SESSION['user_uuid'];
|
||||||
$_SESSION['authentication']['plugin'][$name]['user_email'] = $_SESSION['user_email'];
|
$_SESSION['authentication']['plugin'][$name]['user_email'] = $_SESSION['user_email'];
|
||||||
$_SESSION['authentication']['plugin'][$name]['authorized'] = false;
|
$_SESSION['authentication']['plugin'][$name]['authorized'] = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//debug information
|
//debug information
|
||||||
//view_array($_SESSION['authentication'], false);
|
//view_array($_SESSION['authentication'], false);
|
||||||
|
|
||||||
//set authorized to false if any authentication method failed
|
//set authorized to false if any authentication method failed
|
||||||
$authorized = false;
|
$authorized = false;
|
||||||
$plugin_name = '';
|
$plugin_name = '';
|
||||||
if (is_array($_SESSION['authentication']['plugin'])) {
|
if (is_array($_SESSION['authentication']['plugin'])) {
|
||||||
foreach($_SESSION['authentication']['plugin'] as $row) {
|
foreach ($_SESSION['authentication']['plugin'] as $row) {
|
||||||
$plugin_name = $row['plugin'];
|
$plugin_name = $row['plugin'];
|
||||||
if ($row["authorized"]) {
|
if ($row["authorized"]) {
|
||||||
$authorized = true;
|
$authorized = true;
|
||||||
}
|
} else {
|
||||||
else {
|
$authorized = false;
|
||||||
$authorized = false;
|
$failed_login_message = "Authentication plugin '$plugin_name' blocked login attempt";
|
||||||
$failed_login_message = "Authentication plugin '$plugin_name' blocked login attempt";
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//user is authorized - get user settings, check user cidr
|
//user is authorized - get user settings, check user cidr
|
||||||
if ($authorized) {
|
if ($authorized) {
|
||||||
//get the cidr restrictions from global, domain, and user default settings
|
//get the cidr restrictions from global, domain, and user default settings
|
||||||
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
|
$this->settings = new settings(['database' => $this->database, 'domain_uuid' => $this->domain_uuid, 'user_uuid' => $this->user_uuid]);
|
||||||
$cidr_list = $this->settings->get('domain', 'cidr', []);
|
$cidr_list = $this->settings->get('domain', 'cidr', []);
|
||||||
if (check_cidr($cidr_list, $_SERVER['REMOTE_ADDR'])) {
|
if (check_cidr($cidr_list, $_SERVER['REMOTE_ADDR'])) {
|
||||||
//user passed the cidr check
|
//user passed the cidr check
|
||||||
self::create_user_session($result, $this->settings);
|
self::create_user_session($result, $this->settings);
|
||||||
} else {
|
} else {
|
||||||
//user failed the cidr check - no longer authorized
|
//user failed the cidr check - no longer authorized
|
||||||
$authorized = false;
|
$authorized = false;
|
||||||
$failed_login_message = "CIDR blocked login attempt";
|
$failed_login_message = "CIDR blocked login attempt";
|
||||||
$_SESSION['authentication']['plugin'][$name]['authorized'] = false;
|
$_SESSION['authentication']['plugin'][$name]['authorized'] = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//set a session variable to indicate whether or not we are authorized
|
//set a session variable to indicate whether or not we are authorized
|
||||||
$_SESSION['authorized'] = $authorized;
|
$_SESSION['authorized'] = $authorized;
|
||||||
|
|
||||||
//log the attempt
|
//log the attempt
|
||||||
user_logs::add($_SESSION['authentication']['plugin'][$name], $failed_login_message);
|
user_logs::add($_SESSION['authentication']['plugin'][$name], $failed_login_message);
|
||||||
|
|
||||||
//return the result
|
//return the result
|
||||||
return $result ?? false;
|
return $result ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a valid user session in the superglobal $_SESSION.
|
* Creates a valid user session in the superglobal $_SESSION.
|
||||||
* <p>The $result must be a validated user with the appropriate variables set.<br>
|
* <p>The $result must be a validated user with the appropriate variables set.<br>
|
||||||
* The associative array
|
* The associative array
|
||||||
* @global database $database
|
*
|
||||||
* @global string $conf
|
* @param array|bool $result Associative array containing: domain_uuid, domain_name, user_uuid, username. Contact
|
||||||
* @param array|bool $result Associative array containing: domain_uuid, domain_name, user_uuid, username. Contact keys can be empty, but should still be present. They include: contact_uuid, contact_name_given, contact_name_family, contact_image.
|
* keys can be empty, but should still be present. They include: contact_uuid,
|
||||||
* @param settings $settings From the settings object
|
* contact_name_given, contact_name_family, contact_image.
|
||||||
|
* @param settings $settings From the settings object
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @global string $conf
|
||||||
|
* @global database $database
|
||||||
*/
|
*/
|
||||||
public static function create_user_session($result = [], $settings = null): void {
|
public static function create_user_session($result = [], $settings = null): void {
|
||||||
|
|
||||||
@@ -248,8 +250,8 @@ class authentication {
|
|||||||
$required_keys = [
|
$required_keys = [
|
||||||
'domain_uuid' => true,
|
'domain_uuid' => true,
|
||||||
'domain_name' => true,
|
'domain_name' => true,
|
||||||
'user_uuid' => true,
|
'user_uuid' => true,
|
||||||
'username' => true,
|
'username' => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Any missing required_fields are left in the $diff array.
|
// Any missing required_fields are left in the $diff array.
|
||||||
@@ -281,8 +283,8 @@ class authentication {
|
|||||||
// Set the session variables
|
// Set the session variables
|
||||||
$_SESSION["domain_uuid"] = $result["domain_uuid"];
|
$_SESSION["domain_uuid"] = $result["domain_uuid"];
|
||||||
$_SESSION["domain_name"] = $result["domain_name"];
|
$_SESSION["domain_name"] = $result["domain_name"];
|
||||||
$_SESSION["user_uuid"] = $result["user_uuid"];
|
$_SESSION["user_uuid"] = $result["user_uuid"];
|
||||||
$_SESSION["context"] = $result['domain_name'];
|
$_SESSION["context"] = $result['domain_name'];
|
||||||
|
|
||||||
// Build the session server array to validate the session
|
// Build the session server array to validate the session
|
||||||
global $conf;
|
global $conf;
|
||||||
@@ -297,19 +299,19 @@ class authentication {
|
|||||||
$_SESSION["user_hash"] = hash('sha256', implode($server_array));
|
$_SESSION["user_hash"] = hash('sha256', implode($server_array));
|
||||||
|
|
||||||
// User session array
|
// User session array
|
||||||
$_SESSION["user"]["domain_uuid"] = $result["domain_uuid"];
|
$_SESSION["user"]["domain_uuid"] = $result["domain_uuid"];
|
||||||
$_SESSION["user"]["domain_name"] = $result["domain_name"];
|
$_SESSION["user"]["domain_name"] = $result["domain_name"];
|
||||||
$_SESSION["user"]["user_uuid"] = $result["user_uuid"];
|
$_SESSION["user"]["user_uuid"] = $result["user_uuid"];
|
||||||
$_SESSION["user"]["username"] = $result["username"];
|
$_SESSION["user"]["username"] = $result["username"];
|
||||||
$_SESSION["user"]["contact_uuid"] = $result["contact_uuid"] ?? null; //contact_uuid is optional
|
$_SESSION["user"]["contact_uuid"] = $result["contact_uuid"] ?? null; //contact_uuid is optional
|
||||||
|
|
||||||
// Check for contacts
|
// Check for contacts
|
||||||
if (file_exists($project_root . '/core/contacts/')) {
|
if (file_exists($project_root . '/core/contacts/')) {
|
||||||
$_SESSION["user"]["contact_organization"] = $result["contact_organization"] ?? null;
|
$_SESSION["user"]["contact_organization"] = $result["contact_organization"] ?? null;
|
||||||
$_SESSION["user"]["contact_name"] = trim(($result["contact_name_given"] ?? '') . ' ' . ($result["contact_name_family"] ?? ''));
|
$_SESSION["user"]["contact_name"] = trim(($result["contact_name_given"] ?? '') . ' ' . ($result["contact_name_family"] ?? ''));
|
||||||
$_SESSION["user"]["contact_name_given"] = $result["contact_name_given"] ?? null;
|
$_SESSION["user"]["contact_name_given"] = $result["contact_name_given"] ?? null;
|
||||||
$_SESSION["user"]["contact_name_family"] = $result["contact_name_family"] ?? null;
|
$_SESSION["user"]["contact_name_family"] = $result["contact_name_family"] ?? null;
|
||||||
$_SESSION["user"]["contact_image"] = !empty($result["contact_image"]) && is_uuid($result["contact_image"]) ? $result["contact_image"] : null;
|
$_SESSION["user"]["contact_image"] = !empty($result["contact_image"]) && is_uuid($result["contact_image"]) ? $result["contact_image"] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//empty the permissions
|
//empty the permissions
|
||||||
@@ -334,19 +336,19 @@ class authentication {
|
|||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
//get the user settings
|
//get the user settings
|
||||||
$sql = "select * from v_user_settings ";
|
$sql = "select * from v_user_settings ";
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
$sql .= "and user_uuid = :user_uuid ";
|
$sql .= "and user_uuid = :user_uuid ";
|
||||||
$sql .= "and user_setting_enabled = true ";
|
$sql .= "and user_setting_enabled = true ";
|
||||||
$parameters['domain_uuid'] = $result["domain_uuid"];
|
$parameters['domain_uuid'] = $result["domain_uuid"];
|
||||||
$parameters['user_uuid'] = $result["user_uuid"];
|
$parameters['user_uuid'] = $result["user_uuid"];
|
||||||
$user_settings = $database->select($sql, $parameters, 'all');
|
$user_settings = $database->select($sql, $parameters, 'all');
|
||||||
|
|
||||||
//store user settings in the session when available
|
//store user settings in the session when available
|
||||||
if (is_array($user_settings)) {
|
if (is_array($user_settings)) {
|
||||||
foreach ($user_settings as $row) {
|
foreach ($user_settings as $row) {
|
||||||
$name = $row['user_setting_name'];
|
$name = $row['user_setting_name'];
|
||||||
$category = $row['user_setting_category'];
|
$category = $row['user_setting_category'];
|
||||||
$subcategory = $row['user_setting_subcategory'];
|
$subcategory = $row['user_setting_subcategory'];
|
||||||
if (isset($row['user_setting_value'])) {
|
if (isset($row['user_setting_value'])) {
|
||||||
if (empty($subcategory)) {
|
if (empty($subcategory)) {
|
||||||
@@ -378,27 +380,27 @@ class authentication {
|
|||||||
$_SESSION['user']['extension'] = [];
|
$_SESSION['user']['extension'] = [];
|
||||||
|
|
||||||
//get the user extension list
|
//get the user extension list
|
||||||
$sql = "select ";
|
$sql = "select ";
|
||||||
$sql .= "e.extension_uuid, ";
|
$sql .= "e.extension_uuid, ";
|
||||||
$sql .= "e.extension, ";
|
$sql .= "e.extension, ";
|
||||||
$sql .= "e.number_alias, ";
|
$sql .= "e.number_alias, ";
|
||||||
$sql .= "e.user_context, ";
|
$sql .= "e.user_context, ";
|
||||||
$sql .= "e.outbound_caller_id_name, ";
|
$sql .= "e.outbound_caller_id_name, ";
|
||||||
$sql .= "e.outbound_caller_id_number, ";
|
$sql .= "e.outbound_caller_id_number, ";
|
||||||
$sql .= "e.description ";
|
$sql .= "e.description ";
|
||||||
$sql .= "from ";
|
$sql .= "from ";
|
||||||
$sql .= "v_extension_users as u, ";
|
$sql .= "v_extension_users as u, ";
|
||||||
$sql .= "v_extensions as e ";
|
$sql .= "v_extensions as e ";
|
||||||
$sql .= "where ";
|
$sql .= "where ";
|
||||||
$sql .= "e.domain_uuid = :domain_uuid ";
|
$sql .= "e.domain_uuid = :domain_uuid ";
|
||||||
$sql .= "and e.extension_uuid = u.extension_uuid ";
|
$sql .= "and e.extension_uuid = u.extension_uuid ";
|
||||||
$sql .= "and u.user_uuid = :user_uuid ";
|
$sql .= "and u.user_uuid = :user_uuid ";
|
||||||
$sql .= "and e.enabled = 'true' ";
|
$sql .= "and e.enabled = 'true' ";
|
||||||
$sql .= "order by ";
|
$sql .= "order by ";
|
||||||
$sql .= "e.extension asc ";
|
$sql .= "e.extension asc ";
|
||||||
$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
|
$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
|
||||||
$parameters['user_uuid'] = $_SESSION['user_uuid'];
|
$parameters['user_uuid'] = $_SESSION['user_uuid'];
|
||||||
$extensions = $database->select($sql, $parameters, 'all');
|
$extensions = $database->select($sql, $parameters, 'all');
|
||||||
if (!empty($extensions)) {
|
if (!empty($extensions)) {
|
||||||
foreach ($extensions as $x => $row) {
|
foreach ($extensions as $x => $row) {
|
||||||
//set the destination
|
//set the destination
|
||||||
@@ -408,18 +410,18 @@ class authentication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//build the user array
|
//build the user array
|
||||||
$_SESSION['user']['extension'][$x]['user'] = $row['extension'];
|
$_SESSION['user']['extension'][$x]['user'] = $row['extension'];
|
||||||
$_SESSION['user']['extension'][$x]['number_alias'] = $row['number_alias'];
|
$_SESSION['user']['extension'][$x]['number_alias'] = $row['number_alias'];
|
||||||
$_SESSION['user']['extension'][$x]['destination'] = $destination;
|
$_SESSION['user']['extension'][$x]['destination'] = $destination;
|
||||||
$_SESSION['user']['extension'][$x]['extension_uuid'] = $row['extension_uuid'];
|
$_SESSION['user']['extension'][$x]['extension_uuid'] = $row['extension_uuid'];
|
||||||
$_SESSION['user']['extension'][$x]['outbound_caller_id_name'] = $row['outbound_caller_id_name'];
|
$_SESSION['user']['extension'][$x]['outbound_caller_id_name'] = $row['outbound_caller_id_name'];
|
||||||
$_SESSION['user']['extension'][$x]['outbound_caller_id_number'] = $row['outbound_caller_id_number'];
|
$_SESSION['user']['extension'][$x]['outbound_caller_id_number'] = $row['outbound_caller_id_number'];
|
||||||
$_SESSION['user']['extension'][$x]['user_context'] = $row['user_context'];
|
$_SESSION['user']['extension'][$x]['user_context'] = $row['user_context'];
|
||||||
$_SESSION['user']['extension'][$x]['description'] = $row['description'];
|
$_SESSION['user']['extension'][$x]['description'] = $row['description'];
|
||||||
|
|
||||||
//set the context
|
//set the context
|
||||||
$_SESSION['user']['user_context'] = $row["user_context"];
|
$_SESSION['user']['user_context'] = $row["user_context"];
|
||||||
$_SESSION['user_context'] = $row["user_context"];
|
$_SESSION['user_context'] = $row["user_context"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,81 +453,81 @@ class authentication {
|
|||||||
public function get_domain() {
|
public function get_domain() {
|
||||||
|
|
||||||
//get the domain from the url
|
//get the domain from the url
|
||||||
$this->domain_name = $_SERVER["HTTP_HOST"];
|
$this->domain_name = $_SERVER["HTTP_HOST"];
|
||||||
|
|
||||||
//get the domain name from the http value
|
//get the domain name from the http value
|
||||||
if (!empty($_REQUEST["domain_name"])) {
|
if (!empty($_REQUEST["domain_name"])) {
|
||||||
$this->domain_name = $_REQUEST["domain_name"];
|
$this->domain_name = $_REQUEST["domain_name"];
|
||||||
}
|
}
|
||||||
|
|
||||||
//remote port number from the domain name
|
//remote port number from the domain name
|
||||||
$domain_array = explode(":", $this->domain_name);
|
$domain_array = explode(":", $this->domain_name);
|
||||||
if (count($domain_array) > 1) {
|
if (count($domain_array) > 1) {
|
||||||
$domain_name = $domain_array[0];
|
$domain_name = $domain_array[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the username
|
//if the username
|
||||||
if (!empty($_REQUEST["username"])) {
|
if (!empty($_REQUEST["username"])) {
|
||||||
$_SESSION['username'] = $_REQUEST["username"];
|
$_SESSION['username'] = $_REQUEST["username"];
|
||||||
}
|
}
|
||||||
|
|
||||||
//set a default value for unqiue
|
//set a default value for unqiue
|
||||||
$_SESSION["users"]["unique"]["text"] = $this->settings->get('users', 'unique', '');
|
$_SESSION["users"]["unique"]["text"] = $this->settings->get('users', 'unique', '');
|
||||||
|
|
||||||
//get the domain name from the username
|
//get the domain name from the username
|
||||||
if (!empty($_SESSION['username']) && $this->settings->get('users', 'unique', '') != "global") {
|
if (!empty($_SESSION['username']) && $this->settings->get('users', 'unique', '') != "global") {
|
||||||
$username_array = explode("@", $_SESSION['username']);
|
$username_array = explode("@", $_SESSION['username']);
|
||||||
if (count($username_array) > 1) {
|
if (count($username_array) > 1) {
|
||||||
//get the domain name
|
//get the domain name
|
||||||
$domain_name = $username_array[count($username_array) -1];
|
$domain_name = $username_array[count($username_array) - 1];
|
||||||
|
|
||||||
//check if the domain from the username exists
|
//check if the domain from the username exists
|
||||||
$domain_exists = false;
|
$domain_exists = false;
|
||||||
foreach ($_SESSION['domains'] as $row) {
|
|
||||||
if (lower_case($row['domain_name']) == lower_case($domain_name)) {
|
|
||||||
$this->domain_uuid = $row['domain_uuid'];
|
|
||||||
$domain_exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if the domain exists then set domain_name and update the username
|
|
||||||
if ($domain_exists) {
|
|
||||||
$this->domain_name = $domain_name;
|
|
||||||
$this->username = substr($_SESSION['username'], 0, -(strlen($domain_name)+1));
|
|
||||||
//$_SESSION['domain_name'] = $domain_name;
|
|
||||||
$_SESSION['username'] = $this->username;
|
|
||||||
$_SESSION['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unset the domain name variable
|
|
||||||
unset($domain_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the domain uuid and domain settings
|
|
||||||
if (isset($this->domain_name) && !isset($this->domain_uuid)) {
|
|
||||||
foreach ($_SESSION['domains'] as $row) {
|
foreach ($_SESSION['domains'] as $row) {
|
||||||
if (lower_case($row['domain_name']) == lower_case($this->domain_name)) {
|
if (lower_case($row['domain_name']) == lower_case($domain_name)) {
|
||||||
$this->domain_uuid = $row['domain_uuid'];
|
$this->domain_uuid = $row['domain_uuid'];
|
||||||
$_SESSION['domain_uuid'] = $row['domain_uuid'];
|
$domain_exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if the domain exists then set domain_name and update the username
|
||||||
|
if ($domain_exists) {
|
||||||
|
$this->domain_name = $domain_name;
|
||||||
|
$this->username = substr($_SESSION['username'], 0, -(strlen($domain_name) + 1));
|
||||||
|
//$_SESSION['domain_name'] = $domain_name;
|
||||||
|
$_SESSION['username'] = $this->username;
|
||||||
|
$_SESSION['domain_uuid'] = $this->domain_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//unset the domain name variable
|
||||||
|
unset($domain_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the domain uuid and domain settings
|
||||||
|
if (isset($this->domain_name) && !isset($this->domain_uuid)) {
|
||||||
|
foreach ($_SESSION['domains'] as $row) {
|
||||||
|
if (lower_case($row['domain_name']) == lower_case($this->domain_name)) {
|
||||||
|
$this->domain_uuid = $row['domain_uuid'];
|
||||||
|
$_SESSION['domain_uuid'] = $row['domain_uuid'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//set the setting arrays
|
//set the setting arrays
|
||||||
$obj = new domains(['database' => $this->database]);
|
$obj = new domains(['database' => $this->database]);
|
||||||
$obj->set();
|
$obj->set();
|
||||||
|
|
||||||
//set the domain settings
|
//set the domain settings
|
||||||
if (!empty($this->domain_name) && !empty($_SESSION["domain_uuid"])) {
|
if (!empty($this->domain_name) && !empty($_SESSION["domain_uuid"])) {
|
||||||
$_SESSION['domain_name'] = $this->domain_name;
|
$_SESSION['domain_name'] = $this->domain_name;
|
||||||
$_SESSION['domain_parent_uuid'] = $_SESSION["domain_uuid"];
|
$_SESSION['domain_parent_uuid'] = $_SESSION["domain_uuid"];
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the domain name
|
//set the domain name
|
||||||
return $this->domain_name;
|
return $this->domain_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,351 +50,347 @@ class plugin_database {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* database checks the local database to authenticate the user or key
|
* database checks the local database to authenticate the user or key
|
||||||
|
*
|
||||||
* @return array [authorized] => true or false
|
* @return array [authorized] => true or false
|
||||||
*/
|
*/
|
||||||
function database(authentication $auth, settings $settings) {
|
function database(authentication $auth, settings $settings) {
|
||||||
|
|
||||||
//pre-process some settings
|
//pre-process some settings
|
||||||
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH.'/themes/default/favicon.ico');
|
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH . '/themes/default/favicon.ico');
|
||||||
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH.'/themes/default/images/logo_login.png');
|
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH . '/themes/default/images/logo_login.png');
|
||||||
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
||||||
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
||||||
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
||||||
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
||||||
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
||||||
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
||||||
$background_videos = $settings->get('theme', 'background_video', []);
|
$background_videos = $settings->get('theme', 'background_video', []);
|
||||||
$theme_background_video = (isset($background_videos[0])) ? $background_videos[0] : '';
|
$theme_background_video = (isset($background_videos[0])) ? $background_videos[0] : '';
|
||||||
$login_domain_name_visible = $settings->get('login', 'domain_name_visible', false);
|
$login_domain_name_visible = $settings->get('login', 'domain_name_visible', false);
|
||||||
$login_domain_name = $settings->get('login', 'domain_name');
|
$login_domain_name = $settings->get('login', 'domain_name');
|
||||||
$login_destination = $settings->get('login', 'destination');
|
$login_destination = $settings->get('login', 'destination');
|
||||||
$users_unique = $settings->get('users', 'unique', '');
|
$users_unique = $settings->get('users', 'unique', '');
|
||||||
|
|
||||||
//set the default login type and image
|
//set the default login type and image
|
||||||
if (empty($theme_login_type)) {
|
if (empty($theme_login_type)) {
|
||||||
$theme_login_type = 'image';
|
$theme_login_type = 'image';
|
||||||
$theme_login_image = $theme_logo;
|
$theme_login_image = $theme_logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//determine whether to show the forgot password for resetting the password
|
//determine whether to show the forgot password for resetting the password
|
||||||
$login_password_reset_enabled = false;
|
$login_password_reset_enabled = false;
|
||||||
if (!empty($settings->get('login', 'password_reset_key'))) {
|
if (!empty($settings->get('login', 'password_reset_key'))) {
|
||||||
$login_password_reset_enabled = true;
|
$login_password_reset_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if already authorized
|
//check if already authorized
|
||||||
if (isset($_SESSION['authentication']['plugin']['database']) && $_SESSION['authentication']['plugin']['database']["authorized"]) {
|
if (isset($_SESSION['authentication']['plugin']['database']) && $_SESSION['authentication']['plugin']['database']["authorized"]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//show the authentication code view
|
//show the authentication code view
|
||||||
if (empty($_REQUEST["username"]) && empty($_REQUEST["key"])) {
|
if (empty($_REQUEST["username"]) && empty($_REQUEST["key"])) {
|
||||||
|
|
||||||
//get the domain
|
//get the domain
|
||||||
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
||||||
$domain_name = $domain_array[0];
|
$domain_name = $domain_array[0];
|
||||||
|
|
||||||
//create token
|
//create token
|
||||||
//$object = new token;
|
//$object = new token;
|
||||||
//$token = $object->create('login');
|
//$token = $object->create('login');
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get(null, '/core/authentication');
|
$text = $language->get(null, '/core/authentication');
|
||||||
|
|
||||||
//initialize a template object
|
//initialize a template object
|
||||||
$view = new template();
|
$view = new template();
|
||||||
$view->engine = 'smarty';
|
$view->engine = 'smarty';
|
||||||
$view->template_dir = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/authentication/resources/views/';
|
$view->template_dir = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/authentication/resources/views/';
|
||||||
$view->cache_dir = sys_get_temp_dir();
|
$view->cache_dir = sys_get_temp_dir();
|
||||||
$view->init();
|
$view->init();
|
||||||
|
|
||||||
//add translations
|
//add translations
|
||||||
$view->assign("login_title", $text['button-login']);
|
$view->assign("login_title", $text['button-login']);
|
||||||
$view->assign("label_username", $text['label-username']);
|
$view->assign("label_username", $text['label-username']);
|
||||||
$view->assign("label_password", $text['label-password']);
|
$view->assign("label_password", $text['label-password']);
|
||||||
$view->assign("label_domain", $text['label-domain']);
|
$view->assign("label_domain", $text['label-domain']);
|
||||||
$view->assign("button_login", $text['button-login']);
|
$view->assign("button_login", $text['button-login']);
|
||||||
|
|
||||||
//assign default values to the template
|
//assign default values to the template
|
||||||
$view->assign("project_path", PROJECT_PATH);
|
$view->assign("project_path", PROJECT_PATH);
|
||||||
$view->assign("login_destination_url", $login_destination);
|
$view->assign("login_destination_url", $login_destination);
|
||||||
$view->assign("login_domain_name_visible", $login_domain_name_visible);
|
$view->assign("login_domain_name_visible", $login_domain_name_visible);
|
||||||
$view->assign("login_domain_names", $login_domain_name);
|
$view->assign("login_domain_names", $login_domain_name);
|
||||||
$view->assign("login_password_reset_enabled", $login_password_reset_enabled);
|
$view->assign("login_password_reset_enabled", $login_password_reset_enabled);
|
||||||
$view->assign("favicon", $theme_favicon);
|
$view->assign("favicon", $theme_favicon);
|
||||||
$view->assign("login_logo_width", $theme_login_logo_width);
|
$view->assign("login_logo_width", $theme_login_logo_width);
|
||||||
$view->assign("login_logo_height", $theme_login_logo_height);
|
$view->assign("login_logo_height", $theme_login_logo_height);
|
||||||
$view->assign("login_logo_source", $theme_logo);
|
$view->assign("login_logo_source", $theme_logo);
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
$view->assign("background_video", $theme_background_video);
|
$view->assign("background_video", $theme_background_video);
|
||||||
$view->assign("login_password_description", $text['label-password_description']);
|
$view->assign("login_password_description", $text['label-password_description']);
|
||||||
$view->assign("button_cancel", $text['button-cancel']);
|
$view->assign("button_cancel", $text['button-cancel']);
|
||||||
$view->assign("button_forgot_password", $text['button-forgot_password']);
|
$view->assign("button_forgot_password", $text['button-forgot_password']);
|
||||||
|
|
||||||
//assign openid values to the template
|
//assign openid values to the template
|
||||||
if ($settings->get('open_id', 'enabled', false)) {
|
if ($settings->get('open_id', 'enabled', false)) {
|
||||||
$classes = $settings->get('open_id', 'methods', []);
|
$classes = $settings->get('open_id', 'methods', []);
|
||||||
$banners = [];
|
$banners = [];
|
||||||
foreach ($classes as $open_id_class) {
|
foreach ($classes as $open_id_class) {
|
||||||
if (class_exists($open_id_class)) {
|
if (class_exists($open_id_class)) {
|
||||||
$banners[] = [
|
$banners[] = [
|
||||||
'name' => $open_id_class,
|
'name' => $open_id_class,
|
||||||
'image' => $open_id_class::get_banner_image($settings),
|
'image' => $open_id_class::get_banner_image($settings),
|
||||||
'class' => $open_id_class::get_banner_css_class($settings),
|
'class' => $open_id_class::get_banner_css_class($settings),
|
||||||
'url' => '/app/open_id/open_id.php?action=' . $open_id_class,
|
'url' => '/app/open_id/open_id.php?action=' . $open_id_class,
|
||||||
];
|
];
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count($banners) > 0) {
|
|
||||||
$view->assign('banners', $banners);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//assign user to the template
|
if (count($banners) > 0) {
|
||||||
if (!empty($_SESSION['username'])) {
|
$view->assign('banners', $banners);
|
||||||
$view->assign("username", $_SESSION['username']);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//messages
|
|
||||||
$view->assign('messages', message::html(true, ' '));
|
|
||||||
|
|
||||||
//add the token name and hash to the view
|
|
||||||
//$view->assign("token_name", $token['name']);
|
|
||||||
//$view->assign("token_hash", $token['hash']);
|
|
||||||
|
|
||||||
//show the views
|
|
||||||
$content = $view->render('login.htm');
|
|
||||||
echo $content;
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//assign user to the template
|
||||||
|
if (!empty($_SESSION['username'])) {
|
||||||
|
$view->assign("username", $_SESSION['username']);
|
||||||
|
}
|
||||||
|
|
||||||
|
//messages
|
||||||
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
|
//add the token name and hash to the view
|
||||||
|
//$view->assign("token_name", $token['name']);
|
||||||
|
//$view->assign("token_hash", $token['hash']);
|
||||||
|
|
||||||
|
//show the views
|
||||||
|
$content = $view->render('login.htm');
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
//$token = new token;
|
//$token = new token;
|
||||||
//if (!$token->validate($_SERVER['PHP_SELF'])) {
|
//if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
// message::add($text['message-invalid_token'],'negative');
|
// message::add($text['message-invalid_token'],'negative');
|
||||||
// header('Location: domains.php');
|
// header('Location: domains.php');
|
||||||
// exit;
|
// exit;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//add the authentication details
|
//add the authentication details
|
||||||
if (isset($_REQUEST["username"])) {
|
if (isset($_REQUEST["username"])) {
|
||||||
$this->username = $_REQUEST["username"];
|
$this->username = $_REQUEST["username"];
|
||||||
$_SESSION['username'] = $this->username;
|
$_SESSION['username'] = $this->username;
|
||||||
}
|
}
|
||||||
if (isset($_REQUEST["password"])) {
|
if (isset($_REQUEST["password"])) {
|
||||||
$this->password = $_REQUEST["password"];
|
$this->password = $_REQUEST["password"];
|
||||||
}
|
}
|
||||||
if (isset($_REQUEST["key"])) {
|
if (isset($_REQUEST["key"])) {
|
||||||
$this->key = $_REQUEST["key"];
|
$this->key = $_REQUEST["key"];
|
||||||
}
|
}
|
||||||
if (isset($_REQUEST["domain_name"])) {
|
if (isset($_REQUEST["domain_name"])) {
|
||||||
$domain_name = $_REQUEST["domain_name"];
|
$domain_name = $_REQUEST["domain_name"];
|
||||||
$this->domain_name = $_REQUEST["domain_name"];
|
$this->domain_name = $_REQUEST["domain_name"];
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the domain name
|
//get the domain name
|
||||||
$auth->get_domain();
|
$auth->get_domain();
|
||||||
$this->username = $_SESSION['username'] ?? null;
|
$this->username = $_SESSION['username'] ?? null;
|
||||||
//$this->domain_uuid = $_SESSION['domain_uuid'] ?? null;
|
//$this->domain_uuid = $_SESSION['domain_uuid'] ?? null;
|
||||||
//$this->domain_name = $_SESSION['domain_name'] ?? null;
|
//$this->domain_name = $_SESSION['domain_name'] ?? null;
|
||||||
|
|
||||||
//debug information
|
//debug information
|
||||||
//echo "domain_uuid: ".$this->domain_uuid."<br />\n";
|
//echo "domain_uuid: ".$this->domain_uuid."<br />\n";
|
||||||
//view_array($this->domain_uuid, false);
|
//view_array($this->domain_uuid, false);
|
||||||
//echo "domain_name: ".$this->domain_name."<br />\n";
|
//echo "domain_name: ".$this->domain_name."<br />\n";
|
||||||
//echo "username: ".$this->username."<br />\n";
|
//echo "username: ".$this->username."<br />\n";
|
||||||
|
|
||||||
//set the default status
|
//set the default status
|
||||||
$user_authorized = false;
|
$user_authorized = false;
|
||||||
|
|
||||||
//check if contacts app exists
|
//check if contacts app exists
|
||||||
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/contacts/') ? true : false;
|
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/contacts/') ? true : false;
|
||||||
|
|
||||||
//check the username and password if they don't match then redirect to the login
|
//check the username and password if they don't match then redirect to the login
|
||||||
$sql = "select ";
|
$sql = "select ";
|
||||||
$sql .= " d.domain_name, ";
|
$sql .= " d.domain_name, ";
|
||||||
$sql .= " u.user_uuid, ";
|
$sql .= " u.user_uuid, ";
|
||||||
$sql .= " u.contact_uuid, ";
|
$sql .= " u.contact_uuid, ";
|
||||||
$sql .= " u.username, ";
|
$sql .= " u.username, ";
|
||||||
$sql .= " u.password, ";
|
$sql .= " u.password, ";
|
||||||
$sql .= " u.user_email, ";
|
$sql .= " u.user_email, ";
|
||||||
$sql .= " u.salt, ";
|
$sql .= " u.salt, ";
|
||||||
$sql .= " u.api_key, ";
|
$sql .= " u.api_key, ";
|
||||||
$sql .= " u.domain_uuid ";
|
$sql .= " u.domain_uuid ";
|
||||||
$sql .= "from ";
|
$sql .= "from ";
|
||||||
$sql .= " v_domains as d, ";
|
$sql .= " v_domains as d, ";
|
||||||
$sql .= " v_users as u ";
|
$sql .= " v_users as u ";
|
||||||
$sql .= "where ";
|
$sql .= "where ";
|
||||||
$sql .= " u.domain_uuid = d.domain_uuid ";
|
$sql .= " u.domain_uuid = d.domain_uuid ";
|
||||||
$sql .= " and (";
|
$sql .= " and (";
|
||||||
$sql .= " user_type = 'default' ";
|
$sql .= " user_type = 'default' ";
|
||||||
$sql .= " or user_type is null";
|
$sql .= " or user_type is null";
|
||||||
$sql .= " ) ";
|
$sql .= " ) ";
|
||||||
if (isset($this->key) && strlen($this->key) > 30) {
|
if (isset($this->key) && strlen($this->key) > 30) {
|
||||||
$sql .= "and u.api_key = :api_key ";
|
$sql .= "and u.api_key = :api_key ";
|
||||||
$parameters['api_key'] = $this->key;
|
$parameters['api_key'] = $this->key;
|
||||||
}
|
} else {
|
||||||
else {
|
$sql .= "and (\n";
|
||||||
$sql .= "and (\n";
|
$sql .= " lower(u.username) = lower(:username)\n";
|
||||||
$sql .= " lower(u.username) = lower(:username)\n";
|
$sql .= " or lower(u.user_email) = lower(:username)\n";
|
||||||
$sql .= " or lower(u.user_email) = lower(:username)\n";
|
$sql .= ")\n";
|
||||||
$sql .= ")\n";
|
$parameters['username'] = $this->username;
|
||||||
$parameters['username'] = $this->username;
|
}
|
||||||
}
|
if ($users_unique === "global") {
|
||||||
if ($users_unique === "global") {
|
//unique username - global (example: email address)
|
||||||
//unique username - global (example: email address)
|
} else {
|
||||||
}
|
//unique username - per domain
|
||||||
else {
|
$sql .= "and u.domain_uuid = :domain_uuid ";
|
||||||
//unique username - per domain
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
$sql .= "and u.domain_uuid = :domain_uuid ";
|
}
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
$sql .= "and (user_enabled = true or user_enabled is null) ";
|
||||||
}
|
$row = $settings->database()->select($sql, $parameters, 'row');
|
||||||
$sql .= "and (user_enabled = true or user_enabled is null) ";
|
if (!empty($row) && is_array($row) && @sizeof($row) != 0) {
|
||||||
$row = $settings->database()->select($sql, $parameters, 'row');
|
|
||||||
if (!empty($row) && is_array($row) && @sizeof($row) != 0) {
|
|
||||||
|
|
||||||
//validate the password
|
//validate the password
|
||||||
$valid_password = false;
|
$valid_password = false;
|
||||||
if (isset($this->key) && strlen($this->key) > 30 && $this->key === $row["api_key"]) {
|
if (isset($this->key) && strlen($this->key) > 30 && $this->key === $row["api_key"]) {
|
||||||
|
$valid_password = true;
|
||||||
|
} elseif (substr($row["password"], 0, 1) === '$') {
|
||||||
|
if (isset($this->password) && !empty($this->password)) {
|
||||||
|
if (password_verify($this->password, $row["password"])) {
|
||||||
$valid_password = true;
|
$valid_password = true;
|
||||||
}
|
}
|
||||||
else if (substr($row["password"], 0, 1) === '$') {
|
}
|
||||||
if (isset($this->password) && !empty($this->password)) {
|
} else {
|
||||||
if (password_verify($this->password, $row["password"])) {
|
//deprecated - compare the password provided by the user with the one in the database
|
||||||
$valid_password = true;
|
if (md5($row["salt"] . $this->password) === $row["password"]) {
|
||||||
}
|
$row["password"] = crypt($this->password, '$1$' . $row['salt'] . '$');
|
||||||
}
|
$valid_password = true;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
//deprecated - compare the password provided by the user with the one in the database
|
|
||||||
if (md5($row["salt"].$this->password) === $row["password"]) {
|
|
||||||
$row["password"] = crypt($this->password, '$1$'.$row['salt'].'$');
|
|
||||||
$valid_password = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the domain and user settings
|
//set the domain and user settings
|
||||||
if ($valid_password) {
|
if ($valid_password) {
|
||||||
//set the domain_uuid
|
//set the domain_uuid
|
||||||
$this->domain_uuid = $row["domain_uuid"];
|
$this->domain_uuid = $row["domain_uuid"];
|
||||||
$this->domain_name = $row["domain_name"];
|
$this->domain_name = $row["domain_name"];
|
||||||
|
|
||||||
//set the domain session variables
|
//set the domain session variables
|
||||||
$_SESSION["domain_uuid"] = $this->domain_uuid;
|
$_SESSION["domain_uuid"] = $this->domain_uuid;
|
||||||
$_SESSION["domain_name"] = $this->domain_name;
|
$_SESSION["domain_name"] = $this->domain_name;
|
||||||
|
|
||||||
//set the domain setting
|
//set the domain setting
|
||||||
if ($users_unique === "global" && $row["domain_uuid"] !== $this->domain_uuid) {
|
if ($users_unique === "global" && $row["domain_uuid"] !== $this->domain_uuid) {
|
||||||
$domain = new domains();
|
$domain = new domains();
|
||||||
$domain->set();
|
$domain->set();
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the variables
|
//set the variables
|
||||||
$this->user_uuid = $row['user_uuid'];
|
$this->user_uuid = $row['user_uuid'];
|
||||||
$this->username = $row['username'];
|
$this->username = $row['username'];
|
||||||
$this->user_email = $row['user_email'];
|
$this->user_email = $row['user_email'];
|
||||||
$this->contact_uuid = $row['contact_uuid'];
|
$this->contact_uuid = $row['contact_uuid'];
|
||||||
|
|
||||||
//get the user contact details
|
//get the user contact details
|
||||||
if ($contacts_exists) {
|
if ($contacts_exists) {
|
||||||
unset($parameters);
|
unset($parameters);
|
||||||
$sql = "select ";
|
$sql = "select ";
|
||||||
$sql .= " c.contact_organization, ";
|
$sql .= " c.contact_organization, ";
|
||||||
$sql .= " c.contact_name_given, ";
|
$sql .= " c.contact_name_given, ";
|
||||||
$sql .= " c.contact_name_family, ";
|
$sql .= " c.contact_name_family, ";
|
||||||
$sql .= " a.contact_attachment_uuid ";
|
$sql .= " a.contact_attachment_uuid ";
|
||||||
$sql .= "from v_contacts as c ";
|
$sql .= "from v_contacts as c ";
|
||||||
$sql .= "left join v_contact_attachments as a on c.contact_uuid = a.contact_uuid ";
|
$sql .= "left join v_contact_attachments as a on c.contact_uuid = a.contact_uuid ";
|
||||||
$sql .= "where c.contact_uuid = :contact_uuid ";
|
$sql .= "where c.contact_uuid = :contact_uuid ";
|
||||||
$sql .= "and c.domain_uuid = :domain_uuid ";
|
$sql .= "and c.domain_uuid = :domain_uuid ";
|
||||||
$sql .= "and a.attachment_primary = true ";
|
$sql .= "and a.attachment_primary = true ";
|
||||||
$sql .= "and a.attachment_filename is not null ";
|
$sql .= "and a.attachment_filename is not null ";
|
||||||
$sql .= "and a.attachment_content is not null ";
|
$sql .= "and a.attachment_content is not null ";
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
$parameters['contact_uuid'] = $this->contact_uuid;
|
$parameters['contact_uuid'] = $this->contact_uuid;
|
||||||
$contact = $settings->database()->select($sql, $parameters, 'row');
|
$contact = $settings->database()->select($sql, $parameters, 'row');
|
||||||
$this->contact_organization = $contact['contact_organization'] ?? '';
|
$this->contact_organization = $contact['contact_organization'] ?? '';
|
||||||
$this->contact_name_given = $contact['contact_name_given'] ?? '';
|
$this->contact_name_given = $contact['contact_name_given'] ?? '';
|
||||||
$this->contact_name_family = $contact['contact_name_family'] ?? '';
|
$this->contact_name_family = $contact['contact_name_family'] ?? '';
|
||||||
$this->contact_image = $contact['contact_attachment_uuid'] ?? '';
|
$this->contact_image = $contact['contact_attachment_uuid'] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
//debug info
|
//debug info
|
||||||
//echo "user_uuid ".$this->user_uuid."<br />\n";
|
//echo "user_uuid ".$this->user_uuid."<br />\n";
|
||||||
//echo "username ".$this->username."<br />\n";
|
//echo "username ".$this->username."<br />\n";
|
||||||
//echo "contact_uuid ".$this->contact_uuid."<br />\n";
|
//echo "contact_uuid ".$this->contact_uuid."<br />\n";
|
||||||
|
|
||||||
//set a few session variables
|
//set a few session variables
|
||||||
$_SESSION["user_uuid"] = $row['user_uuid'];
|
$_SESSION["user_uuid"] = $row['user_uuid'];
|
||||||
$_SESSION["username"] = $row['username'];
|
$_SESSION["username"] = $row['username'];
|
||||||
$_SESSION["user_email"] = $row['user_email'];
|
$_SESSION["user_email"] = $row['user_email'];
|
||||||
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
||||||
}
|
}
|
||||||
|
|
||||||
//check to to see if the the password hash needs to be updated
|
//check to to see if the the password hash needs to be updated
|
||||||
if ($valid_password) {
|
if ($valid_password) {
|
||||||
//set the password hash cost
|
//set the password hash cost
|
||||||
$options = array('cost' => 10);
|
$options = ['cost' => 10];
|
||||||
|
|
||||||
//check if a newer hashing algorithm is available or the cost has changed
|
//check if a newer hashing algorithm is available or the cost has changed
|
||||||
if (password_needs_rehash($row["password"], PASSWORD_DEFAULT, $options)) {
|
if (password_needs_rehash($row["password"], PASSWORD_DEFAULT, $options)) {
|
||||||
|
|
||||||
//build user insert array
|
//build user insert array
|
||||||
$array = [];
|
$array = [];
|
||||||
$array['users'][0]['user_uuid'] = $this->user_uuid;
|
$array['users'][0]['user_uuid'] = $this->user_uuid;
|
||||||
$array['users'][0]['domain_uuid'] = $this->domain_uuid;
|
$array['users'][0]['domain_uuid'] = $this->domain_uuid;
|
||||||
$array['users'][0]['user_email'] = $this->user_email;
|
$array['users'][0]['user_email'] = $this->user_email;
|
||||||
$array['users'][0]['password'] = password_hash($this->password, PASSWORD_DEFAULT, $options);
|
$array['users'][0]['password'] = password_hash($this->password, PASSWORD_DEFAULT, $options);
|
||||||
$array['users'][0]['salt'] = null;
|
$array['users'][0]['salt'] = null;
|
||||||
|
|
||||||
//build user group insert array
|
//build user group insert array
|
||||||
$array['user_groups'][0]['user_group_uuid'] = uuid();
|
$array['user_groups'][0]['user_group_uuid'] = uuid();
|
||||||
$array['user_groups'][0]['domain_uuid'] = $this->domain_uuid;
|
$array['user_groups'][0]['domain_uuid'] = $this->domain_uuid;
|
||||||
$array['user_groups'][0]['group_name'] = 'user';
|
$array['user_groups'][0]['group_name'] = 'user';
|
||||||
$array['user_groups'][0]['user_uuid'] = $this->user_uuid;
|
$array['user_groups'][0]['user_uuid'] = $this->user_uuid;
|
||||||
|
|
||||||
//grant temporary permissions
|
//grant temporary permissions
|
||||||
$p = permissions::new();
|
$p = permissions::new();
|
||||||
$p->add('user_edit', 'temp');
|
$p->add('user_edit', 'temp');
|
||||||
|
|
||||||
//execute insert
|
//execute insert
|
||||||
$settings->database()->app_name = 'authentication';
|
$settings->database()->app_name = 'authentication';
|
||||||
$settings->database()->app_uuid = 'a8a12918-69a4-4ece-a1ae-3932be0e41f1';
|
$settings->database()->app_uuid = 'a8a12918-69a4-4ece-a1ae-3932be0e41f1';
|
||||||
$settings->database()->save($array);
|
$settings->database()->save($array);
|
||||||
unset($array);
|
unset($array);
|
||||||
|
|
||||||
//revoke temporary permissions
|
//revoke temporary permissions
|
||||||
$p->delete('user_edit', 'temp');
|
$p->delete('user_edit', 'temp');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//result array
|
|
||||||
if ($valid_password) {
|
|
||||||
$result["plugin"] = "database";
|
|
||||||
$result["domain_name"] = $this->domain_name;
|
|
||||||
$result["username"] = $this->username;
|
|
||||||
$result["user_uuid"] = $this->user_uuid;
|
|
||||||
$result["domain_uuid"] = $_SESSION['domain_uuid'];
|
|
||||||
$result["contact_uuid"] = $this->contact_uuid;
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$result["contact_organization"] = $this->contact_organization;
|
|
||||||
$result["contact_name_given"] = $this->contact_name_given;
|
|
||||||
$result["contact_name_family"] = $this->contact_name_family;
|
|
||||||
$result["contact_image"] = $this->contact_image;
|
|
||||||
}
|
|
||||||
$result["user_email"] = $this->user_email;
|
|
||||||
$result["sql"] = $sql;
|
|
||||||
$result["authorized"] = $valid_password;
|
|
||||||
}
|
|
||||||
|
|
||||||
//return the results
|
|
||||||
return $result ?? false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//result array
|
||||||
|
if ($valid_password) {
|
||||||
|
$result["plugin"] = "database";
|
||||||
|
$result["domain_name"] = $this->domain_name;
|
||||||
|
$result["username"] = $this->username;
|
||||||
|
$result["user_uuid"] = $this->user_uuid;
|
||||||
|
$result["domain_uuid"] = $_SESSION['domain_uuid'];
|
||||||
|
$result["contact_uuid"] = $this->contact_uuid;
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$result["contact_organization"] = $this->contact_organization;
|
||||||
|
$result["contact_name_given"] = $this->contact_name_given;
|
||||||
|
$result["contact_name_family"] = $this->contact_name_family;
|
||||||
|
$result["contact_image"] = $this->contact_image;
|
||||||
|
}
|
||||||
|
$result["user_email"] = $this->user_email;
|
||||||
|
$result["sql"] = $sql;
|
||||||
|
$result["authorized"] = $valid_password;
|
||||||
|
}
|
||||||
|
|
||||||
|
//return the results
|
||||||
|
return $result ?? false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -60,405 +60,401 @@ class plugin_email {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* time based one time password with email
|
* time based one time password with email
|
||||||
|
*
|
||||||
* @return array [authorized] => true or false
|
* @return array [authorized] => true or false
|
||||||
*/
|
*/
|
||||||
function email(authentication $auth, settings $settings) {
|
function email(authentication $auth, settings $settings) {
|
||||||
|
|
||||||
//pre-process some settings
|
//pre-process some settings
|
||||||
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH.'/themes/default/favicon.ico');
|
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH . '/themes/default/favicon.ico');
|
||||||
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH.'/themes/default/images/logo_login.png');
|
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH . '/themes/default/images/logo_login.png');
|
||||||
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
||||||
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
||||||
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
||||||
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
||||||
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
||||||
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
||||||
$background_videos = $settings->get('theme', 'background_video', null);
|
$background_videos = $settings->get('theme', 'background_video', null);
|
||||||
$theme_background_video = (isset($background_videos) && is_array($background_videos)) ? $background_videos[0] : null;
|
$theme_background_video = (isset($background_videos) && is_array($background_videos)) ? $background_videos[0] : null;
|
||||||
//$login_domain_name_visible = $settings->get('login', 'domain_name_visible');
|
//$login_domain_name_visible = $settings->get('login', 'domain_name_visible');
|
||||||
//$login_domain_name = $settings->get('login', 'domain_name');
|
//$login_domain_name = $settings->get('login', 'domain_name');
|
||||||
$login_destination = $settings->get('login', 'destination');
|
$login_destination = $settings->get('login', 'destination');
|
||||||
$users_unique = $settings->get('users', 'unique', '');
|
$users_unique = $settings->get('users', 'unique', '');
|
||||||
|
|
||||||
//get the domain
|
//get the domain
|
||||||
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
||||||
$domain_name = $domain_array[0];
|
$domain_name = $domain_array[0];
|
||||||
|
|
||||||
//use the session username
|
//use the session username
|
||||||
if (isset($_SESSION['username'])) {
|
if (isset($_SESSION['username'])) {
|
||||||
$_POST['username'] = $_SESSION['username'];
|
$_POST['username'] = $_SESSION['username'];
|
||||||
$_REQUEST['username'] = $_SESSION['username'];
|
$_REQUEST['username'] = $_SESSION['username'];
|
||||||
}
|
}
|
||||||
|
|
||||||
//request the username
|
//request the username
|
||||||
if (!isset($_POST['username']) && !isset($_POST['authentication_code'])) {
|
if (!isset($_POST['username']) && !isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get(null, '/core/authentication');
|
$text = $language->get(null, '/core/authentication');
|
||||||
|
|
||||||
//initialize a template object
|
//initialize a template object
|
||||||
$view = new template();
|
$view = new template();
|
||||||
$view->engine = 'smarty';
|
$view->engine = 'smarty';
|
||||||
$view->template_dir = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/authentication/resources/views/';
|
$view->template_dir = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/authentication/resources/views/';
|
||||||
$view->cache_dir = sys_get_temp_dir();
|
$view->cache_dir = sys_get_temp_dir();
|
||||||
$view->init();
|
$view->init();
|
||||||
|
|
||||||
//assign default values to the template
|
//assign default values to the template
|
||||||
$view->assign("project_path", PROJECT_PATH);
|
$view->assign("project_path", PROJECT_PATH);
|
||||||
$view->assign("login_destination_url", $login_destination);
|
$view->assign("login_destination_url", $login_destination);
|
||||||
$view->assign("favicon", $theme_favicon);
|
$view->assign("favicon", $theme_favicon);
|
||||||
$view->assign("login_title", $text['label-username']);
|
$view->assign("login_title", $text['label-username']);
|
||||||
$view->assign("login_username", $text['label-username']);
|
$view->assign("login_username", $text['label-username']);
|
||||||
$view->assign("login_logo_width", $theme_login_logo_width);
|
$view->assign("login_logo_width", $theme_login_logo_width);
|
||||||
$view->assign("login_logo_height", $theme_login_logo_height);
|
$view->assign("login_logo_height", $theme_login_logo_height);
|
||||||
$view->assign("login_logo_source", $theme_logo);
|
$view->assign("login_logo_source", $theme_logo);
|
||||||
$view->assign("button_login", $text['button-login']);
|
$view->assign("button_login", $text['button-login']);
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
$view->assign("background_video", $theme_background_video);
|
$view->assign("background_video", $theme_background_video);
|
||||||
|
|
||||||
//messages
|
//messages
|
||||||
$view->assign('messages', message::html(true, ' '));
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
//show the views
|
//show the views
|
||||||
$content = $view->render('username.htm');
|
$content = $view->render('username.htm');
|
||||||
echo $content;
|
echo $content;
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//show the authentication code view
|
//show the authentication code view
|
||||||
if (!isset($_POST['authentication_code'])) {
|
if (!isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
//get the username
|
//get the username
|
||||||
//if (!isset($this->username) && isset($_REQUEST['username'])) {
|
//if (!isset($this->username) && isset($_REQUEST['username'])) {
|
||||||
// $this->username = $_REQUEST['username'];
|
// $this->username = $_REQUEST['username'];
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//get the user details
|
//get the user details
|
||||||
$sql = "select user_uuid, username, user_email, contact_uuid \n";
|
$sql = "select user_uuid, username, user_email, contact_uuid \n";
|
||||||
$sql .= "from v_users\n";
|
$sql .= "from v_users\n";
|
||||||
$sql .= "where (\n";
|
$sql .= "where (\n";
|
||||||
$sql .= " username = :username\n";
|
$sql .= " username = :username\n";
|
||||||
$sql .= " or user_email = :username\n";
|
$sql .= " or user_email = :username\n";
|
||||||
$sql .= ")\n";
|
$sql .= ")\n";
|
||||||
if ($users_unique != "global") {
|
if ($users_unique != "global") {
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
$sql .= "and domain_uuid = :domain_uuid ";
|
$sql .= "and domain_uuid = :domain_uuid ";
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
|
||||||
}
|
|
||||||
$sql .= "and (user_type = 'default' or user_type is null) ";
|
|
||||||
$parameters['username'] = $_REQUEST['username'];
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
unset($parameters);
|
|
||||||
|
|
||||||
//set class variables
|
|
||||||
//if (!empty($row["user_email"])) {
|
|
||||||
// $this->user_uuid = $row['user_uuid'];
|
|
||||||
// $this->user_email = $row['user_email'];
|
|
||||||
// $this->contact_uuid = $row['contact_uuid'];
|
|
||||||
//}
|
|
||||||
|
|
||||||
//set a few session variables
|
|
||||||
$_SESSION["user_uuid"] = $row['user_uuid'];
|
|
||||||
$_SESSION["username"] = $row['username'];
|
|
||||||
$_SESSION["user_email"] = $row['user_email'];
|
|
||||||
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
|
||||||
|
|
||||||
//user not found
|
|
||||||
if (empty($row) || !is_array($row) || @sizeof($row) == 0) {
|
|
||||||
//clear submitted usernames
|
|
||||||
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
|
||||||
|
|
||||||
//clear authentication session
|
|
||||||
unset($_SESSION['authentication']);
|
|
||||||
|
|
||||||
//build the result array
|
|
||||||
$result["plugin"] = "email";
|
|
||||||
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
|
||||||
$result["authorized"] = false;
|
|
||||||
|
|
||||||
//retun the array
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//user email not found
|
|
||||||
else if (empty($row["user_email"])) {
|
|
||||||
//clear submitted usernames
|
|
||||||
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
|
||||||
|
|
||||||
//clear authentication session
|
|
||||||
unset($_SESSION['authentication']);
|
|
||||||
|
|
||||||
//build the result array
|
|
||||||
$result["plugin"] = "email";
|
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
|
||||||
$result["username"] = $_REQUEST['username'];
|
|
||||||
$result["user_uuid"] = $_SESSION["user_uuid"];
|
|
||||||
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
|
||||||
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
|
||||||
$result["authorized"] = false;
|
|
||||||
|
|
||||||
//add the failed login to user logs
|
|
||||||
user_logs::add($result);
|
|
||||||
|
|
||||||
//return the array
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//authentication code
|
|
||||||
$_SESSION["user"]["authentication"]["email"]["code"] = generate_password(6, 1);
|
|
||||||
$_SESSION["user"]["authentication"]["email"]["epoch"] = time();
|
|
||||||
|
|
||||||
//$_SESSION["authentication_address"] = $_SERVER['REMOTE_ADDR'];
|
|
||||||
//$_SESSION["authentication_date"] = 'now()';
|
|
||||||
|
|
||||||
//set the authentication code
|
|
||||||
//$sql = "update v_users \n";
|
|
||||||
//$sql .= "set auth_code = :auth_code \n";
|
|
||||||
//$sql .= "where user_uuid = :user_uuid;";
|
|
||||||
//$parameters['auth_code'] = $auth_code_hash;
|
|
||||||
//$parameters['user_uuid'] = $this->user_uuid;
|
|
||||||
//$this->database->execute($sql, $parameters);
|
|
||||||
//unset($sql);
|
|
||||||
|
|
||||||
//email settings
|
|
||||||
//$email_address = $this->user_email;
|
|
||||||
//$email_subject = 'Validation Code';
|
|
||||||
//$email_body = 'Validation Code: '.$authentication_code;
|
|
||||||
|
|
||||||
//send email with the authentication_code
|
|
||||||
//ob_start();
|
|
||||||
//$sent = !send_email($email_address, $email_subject, $email_body, $email_error, null, null, 3, 3) ? false : true;
|
|
||||||
//$response = ob_get_clean();
|
|
||||||
|
|
||||||
//get the language code
|
|
||||||
$language_code = $settings->get('domain', 'language', 'en-us');
|
|
||||||
|
|
||||||
//get the email template from the database
|
|
||||||
$sql = "select template_subject, template_body ";
|
|
||||||
$sql .= "from v_email_templates ";
|
|
||||||
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
|
||||||
$sql .= "and template_language = :template_language ";
|
|
||||||
$sql .= "and template_category = :template_category ";
|
|
||||||
$sql .= "and template_subcategory = :template_subcategory ";
|
|
||||||
$sql .= "and template_type = :template_type ";
|
|
||||||
$sql .= "and template_enabled = true ";
|
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
$parameters['template_language'] = $language_code;
|
}
|
||||||
$parameters['template_category'] = 'authentication';
|
$sql .= "and (user_type = 'default' or user_type is null) ";
|
||||||
$parameters['template_subcategory'] = 'email';
|
$parameters['username'] = $_REQUEST['username'];
|
||||||
$parameters['template_type'] = 'html';
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
unset($parameters);
|
||||||
$email_subject = $row['template_subject'];
|
|
||||||
$email_body = $row['template_body'];
|
|
||||||
unset($sql, $parameters, $row);
|
|
||||||
|
|
||||||
//replace variables in email subject
|
//set class variables
|
||||||
$email_subject = str_replace('${domain_name}', $_SESSION["domain_name"], $email_subject);
|
//if (!empty($row["user_email"])) {
|
||||||
|
// $this->user_uuid = $row['user_uuid'];
|
||||||
|
// $this->user_email = $row['user_email'];
|
||||||
|
// $this->contact_uuid = $row['contact_uuid'];
|
||||||
|
//}
|
||||||
|
|
||||||
//replace variables in email body
|
//set a few session variables
|
||||||
$email_body = str_replace('${domain_name}', $_SESSION["domain_name"], $email_body);
|
$_SESSION["user_uuid"] = $row['user_uuid'];
|
||||||
$email_body = str_replace('${auth_code}', $_SESSION["user"]["authentication"]["email"]["code"], $email_body);
|
$_SESSION["username"] = $row['username'];
|
||||||
|
$_SESSION["user_email"] = $row['user_email'];
|
||||||
|
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
||||||
|
|
||||||
//get the email from name and address
|
//user not found
|
||||||
$email_from_address = $_SESSION['email']['smtp_from']['text'];
|
if (empty($row) || !is_array($row) || @sizeof($row) == 0) {
|
||||||
$email_from_name = $_SESSION['email']['smtp_from_name']['text'];
|
//clear submitted usernames
|
||||||
|
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
||||||
|
|
||||||
//get the email send mode options: direct or email_queue
|
//clear authentication session
|
||||||
$email_send_mode = $_SESSION['authentication']['email_send_mode']['text'] ?? 'email_queue';
|
unset($_SESSION['authentication']);
|
||||||
|
|
||||||
//send the email
|
//build the result array
|
||||||
if ($email_send_mode == 'email_queue') {
|
$result["plugin"] = "email";
|
||||||
//set the variables
|
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
$email_queue_uuid = uuid();
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
$email_uuid = uuid();
|
$result["authorized"] = false;
|
||||||
$hostname = gethostname();
|
|
||||||
|
|
||||||
//add the temporary permissions
|
//retun the array
|
||||||
$p = permissions::new();
|
return $result;
|
||||||
$p->add("email_queue_add", 'temp');
|
} //user email not found
|
||||||
$p->add("email_queue_edit", 'temp');
|
elseif (empty($row["user_email"])) {
|
||||||
|
//clear submitted usernames
|
||||||
|
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
||||||
|
|
||||||
$array['email_queue'][0]["email_queue_uuid"] = $email_queue_uuid;
|
//clear authentication session
|
||||||
$array['email_queue'][0]["domain_uuid"] = $_SESSION["domain_uuid"];
|
unset($_SESSION['authentication']);
|
||||||
$array['email_queue'][0]["hostname"] = $hostname;
|
|
||||||
$array['email_queue'][0]["email_date"] = 'now()';
|
|
||||||
$array['email_queue'][0]["email_from"] = $email_from_address;
|
|
||||||
$array['email_queue'][0]["email_to"] = $_SESSION["user_email"];
|
|
||||||
$array['email_queue'][0]["email_subject"] = $email_subject;
|
|
||||||
$array['email_queue'][0]["email_body"] = $email_body;
|
|
||||||
$array['email_queue'][0]["email_status"] = 'waiting';
|
|
||||||
$array['email_queue'][0]["email_retry_count"] = 3;
|
|
||||||
$array['email_queue'][0]["email_uuid"] = $email_uuid;
|
|
||||||
$array['email_queue'][0]["email_action_before"] = null;
|
|
||||||
$array['email_queue'][0]["email_action_after"] = null;
|
|
||||||
$this->database->save($array);
|
|
||||||
$err = $this->database->message;
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//remove the temporary permission
|
//build the result array
|
||||||
$p->delete("email_queue_add", 'temp');
|
$result["plugin"] = "email";
|
||||||
$p->delete("email_queue_edit", 'temp');
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
}
|
$result["username"] = $_REQUEST['username'];
|
||||||
else {
|
$result["user_uuid"] = $_SESSION["user_uuid"];
|
||||||
//send email - direct
|
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
$email = new email;
|
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
||||||
$email->recipients = $_SESSION["user_email"];
|
$result["authorized"] = false;
|
||||||
$email->subject = $email_subject;
|
|
||||||
$email->body = $email_body;
|
|
||||||
$email->from_address = $email_from_address;
|
|
||||||
$email->from_name = $email_from_name;
|
|
||||||
//$email->attachments = $email_attachments;
|
|
||||||
$email->debug_level = 0;
|
|
||||||
$email->method = 'direct';
|
|
||||||
$sent = $email->send();
|
|
||||||
}
|
|
||||||
|
|
||||||
//debug informations
|
//add the failed login to user logs
|
||||||
//$email_response = $email->response;
|
user_logs::add($result);
|
||||||
//$email_error = $email->email_error;
|
|
||||||
//echo $email_response."<br />\n";
|
|
||||||
//echo $email_error."<br />\n";
|
|
||||||
|
|
||||||
//get the domain
|
//return the array
|
||||||
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
return $result;
|
||||||
$domain_name = $domain_array[0];
|
}
|
||||||
|
|
||||||
//create token
|
//authentication code
|
||||||
//$object = new token;
|
$_SESSION["user"]["authentication"]["email"]["code"] = generate_password(6, 1);
|
||||||
//$token = $object->create('login');
|
$_SESSION["user"]["authentication"]["email"]["epoch"] = time();
|
||||||
|
|
||||||
//add multi-lingual support
|
//$_SESSION["authentication_address"] = $_SERVER['REMOTE_ADDR'];
|
||||||
$language = new text;
|
//$_SESSION["authentication_date"] = 'now()';
|
||||||
$text = $language->get(null, '/core/authentication');
|
|
||||||
|
|
||||||
//initialize a template object
|
//set the authentication code
|
||||||
$view = new template();
|
//$sql = "update v_users \n";
|
||||||
$view->engine = 'smarty';
|
//$sql .= "set auth_code = :auth_code \n";
|
||||||
$view->template_dir = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/authentication/resources/views/';
|
//$sql .= "where user_uuid = :user_uuid;";
|
||||||
$view->cache_dir = sys_get_temp_dir();
|
//$parameters['auth_code'] = $auth_code_hash;
|
||||||
$view->init();
|
//$parameters['user_uuid'] = $this->user_uuid;
|
||||||
|
//$this->database->execute($sql, $parameters);
|
||||||
|
//unset($sql);
|
||||||
|
|
||||||
//assign default values to the template
|
//email settings
|
||||||
$view->assign("project_path", PROJECT_PATH);
|
//$email_address = $this->user_email;
|
||||||
$view->assign("login_destination_url", $login_destination);
|
//$email_subject = 'Validation Code';
|
||||||
$view->assign("favicon", $theme_favicon);
|
//$email_body = 'Validation Code: '.$authentication_code;
|
||||||
$view->assign("login_title", $text['label-verify']);
|
|
||||||
$view->assign("login_email_description", $text['label-email_description']);
|
|
||||||
$view->assign("login_authentication_code", $text['label-authentication_code']);
|
|
||||||
$view->assign("login_logo_width", $theme_login_logo_width);
|
|
||||||
$view->assign("login_logo_height", $theme_login_logo_height);
|
|
||||||
$view->assign("login_logo_source", $theme_logo);
|
|
||||||
$view->assign("button_verify", $text['label-verify']);
|
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
|
||||||
if (!empty($_SESSION['username'])) {
|
|
||||||
$view->assign("username", $_SESSION['username']);
|
|
||||||
$view->assign("button_cancel", $text['button-cancel']);
|
|
||||||
}
|
|
||||||
|
|
||||||
//messages
|
//send email with the authentication_code
|
||||||
$view->assign('messages', message::html(true, ' '));
|
//ob_start();
|
||||||
|
//$sent = !send_email($email_address, $email_subject, $email_body, $email_error, null, null, 3, 3) ? false : true;
|
||||||
|
//$response = ob_get_clean();
|
||||||
|
|
||||||
//show the views
|
//get the language code
|
||||||
$content = $view->render('email.htm');
|
$language_code = $settings->get('domain', 'language', 'en-us');
|
||||||
echo $content;
|
|
||||||
|
//get the email template from the database
|
||||||
|
$sql = "select template_subject, template_body ";
|
||||||
|
$sql .= "from v_email_templates ";
|
||||||
|
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
||||||
|
$sql .= "and template_language = :template_language ";
|
||||||
|
$sql .= "and template_category = :template_category ";
|
||||||
|
$sql .= "and template_subcategory = :template_subcategory ";
|
||||||
|
$sql .= "and template_type = :template_type ";
|
||||||
|
$sql .= "and template_enabled = true ";
|
||||||
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
|
$parameters['template_language'] = $language_code;
|
||||||
|
$parameters['template_category'] = 'authentication';
|
||||||
|
$parameters['template_subcategory'] = 'email';
|
||||||
|
$parameters['template_type'] = 'html';
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
$email_subject = $row['template_subject'];
|
||||||
|
$email_body = $row['template_body'];
|
||||||
|
unset($sql, $parameters, $row);
|
||||||
|
|
||||||
|
//replace variables in email subject
|
||||||
|
$email_subject = str_replace('${domain_name}', $_SESSION["domain_name"], $email_subject);
|
||||||
|
|
||||||
|
//replace variables in email body
|
||||||
|
$email_body = str_replace('${domain_name}', $_SESSION["domain_name"], $email_body);
|
||||||
|
$email_body = str_replace('${auth_code}', $_SESSION["user"]["authentication"]["email"]["code"], $email_body);
|
||||||
|
|
||||||
|
//get the email from name and address
|
||||||
|
$email_from_address = $_SESSION['email']['smtp_from']['text'];
|
||||||
|
$email_from_name = $_SESSION['email']['smtp_from_name']['text'];
|
||||||
|
|
||||||
|
//get the email send mode options: direct or email_queue
|
||||||
|
$email_send_mode = $_SESSION['authentication']['email_send_mode']['text'] ?? 'email_queue';
|
||||||
|
|
||||||
|
//send the email
|
||||||
|
if ($email_send_mode == 'email_queue') {
|
||||||
|
//set the variables
|
||||||
|
$email_queue_uuid = uuid();
|
||||||
|
$email_uuid = uuid();
|
||||||
|
$hostname = gethostname();
|
||||||
|
|
||||||
|
//add the temporary permissions
|
||||||
|
$p = permissions::new();
|
||||||
|
$p->add("email_queue_add", 'temp');
|
||||||
|
$p->add("email_queue_edit", 'temp');
|
||||||
|
|
||||||
|
$array['email_queue'][0]["email_queue_uuid"] = $email_queue_uuid;
|
||||||
|
$array['email_queue'][0]["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
|
$array['email_queue'][0]["hostname"] = $hostname;
|
||||||
|
$array['email_queue'][0]["email_date"] = 'now()';
|
||||||
|
$array['email_queue'][0]["email_from"] = $email_from_address;
|
||||||
|
$array['email_queue'][0]["email_to"] = $_SESSION["user_email"];
|
||||||
|
$array['email_queue'][0]["email_subject"] = $email_subject;
|
||||||
|
$array['email_queue'][0]["email_body"] = $email_body;
|
||||||
|
$array['email_queue'][0]["email_status"] = 'waiting';
|
||||||
|
$array['email_queue'][0]["email_retry_count"] = 3;
|
||||||
|
$array['email_queue'][0]["email_uuid"] = $email_uuid;
|
||||||
|
$array['email_queue'][0]["email_action_before"] = null;
|
||||||
|
$array['email_queue'][0]["email_action_after"] = null;
|
||||||
|
$this->database->save($array);
|
||||||
|
$err = $this->database->message;
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//remove the temporary permission
|
||||||
|
$p->delete("email_queue_add", 'temp');
|
||||||
|
$p->delete("email_queue_edit", 'temp');
|
||||||
|
} else {
|
||||||
|
//send email - direct
|
||||||
|
$email = new email;
|
||||||
|
$email->recipients = $_SESSION["user_email"];
|
||||||
|
$email->subject = $email_subject;
|
||||||
|
$email->body = $email_body;
|
||||||
|
$email->from_address = $email_from_address;
|
||||||
|
$email->from_name = $email_from_name;
|
||||||
|
//$email->attachments = $email_attachments;
|
||||||
|
$email->debug_level = 0;
|
||||||
|
$email->method = 'direct';
|
||||||
|
$sent = $email->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
//debug informations
|
||||||
|
//$email_response = $email->response;
|
||||||
|
//$email_error = $email->email_error;
|
||||||
|
//echo $email_response."<br />\n";
|
||||||
|
//echo $email_error."<br />\n";
|
||||||
|
|
||||||
|
//get the domain
|
||||||
|
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
||||||
|
$domain_name = $domain_array[0];
|
||||||
|
|
||||||
|
//create token
|
||||||
|
//$object = new token;
|
||||||
|
//$token = $object->create('login');
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get(null, '/core/authentication');
|
||||||
|
|
||||||
|
//initialize a template object
|
||||||
|
$view = new template();
|
||||||
|
$view->engine = 'smarty';
|
||||||
|
$view->template_dir = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/authentication/resources/views/';
|
||||||
|
$view->cache_dir = sys_get_temp_dir();
|
||||||
|
$view->init();
|
||||||
|
|
||||||
|
//assign default values to the template
|
||||||
|
$view->assign("project_path", PROJECT_PATH);
|
||||||
|
$view->assign("login_destination_url", $login_destination);
|
||||||
|
$view->assign("favicon", $theme_favicon);
|
||||||
|
$view->assign("login_title", $text['label-verify']);
|
||||||
|
$view->assign("login_email_description", $text['label-email_description']);
|
||||||
|
$view->assign("login_authentication_code", $text['label-authentication_code']);
|
||||||
|
$view->assign("login_logo_width", $theme_login_logo_width);
|
||||||
|
$view->assign("login_logo_height", $theme_login_logo_height);
|
||||||
|
$view->assign("login_logo_source", $theme_logo);
|
||||||
|
$view->assign("button_verify", $text['label-verify']);
|
||||||
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
|
if (!empty($_SESSION['username'])) {
|
||||||
|
$view->assign("username", $_SESSION['username']);
|
||||||
|
$view->assign("button_cancel", $text['button-cancel']);
|
||||||
|
}
|
||||||
|
|
||||||
|
//messages
|
||||||
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
|
//show the views
|
||||||
|
$content = $view->render('email.htm');
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if authorized then verify
|
||||||
|
if (isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
|
//check if the authentication code has expired. if expired return false
|
||||||
|
if (!empty($_SESSION["user"]) && $_SESSION["user"]["authentication"]["email"]["epoch"] + 3 > time()) {
|
||||||
|
//authentication code expired
|
||||||
|
$result["plugin"] = "email";
|
||||||
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
|
$result["username"] = $_SESSION["username"];
|
||||||
|
$result["error_message"] = 'code expired';
|
||||||
|
$result["authorized"] = false;
|
||||||
|
print_r($result);
|
||||||
|
return $result;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if authorized then verify
|
//get the user details
|
||||||
if (isset($_POST['authentication_code'])) {
|
$sql = "select user_uuid, user_email, contact_uuid\n";
|
||||||
|
$sql .= "from v_users\n";
|
||||||
|
$sql .= "where (\n";
|
||||||
|
$sql .= " username = :username\n";
|
||||||
|
$sql .= " or user_email = :username\n";
|
||||||
|
$sql .= ")\n";
|
||||||
|
if ($users_unique != "global") {
|
||||||
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
|
$sql .= "and domain_uuid = :domain_uuid ";
|
||||||
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
|
}
|
||||||
|
$parameters['username'] = $_SESSION["username"];
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
$this->user_uuid = $row['user_uuid'];
|
||||||
|
$this->user_email = $row['user_email'];
|
||||||
|
$this->contact_uuid = $row['contact_uuid'];
|
||||||
|
unset($parameters);
|
||||||
|
/*
|
||||||
|
echo 'session code = '.$_SESSION["user"]["authentication"]["email"]["code"].'<br>';
|
||||||
|
echo 'post code = '.$_POST['authentication_code'].'<br>';
|
||||||
|
exit;
|
||||||
|
*/
|
||||||
|
|
||||||
//check if the authentication code has expired. if expired return false
|
//validate the code
|
||||||
if (!empty($_SESSION["user"]) && $_SESSION["user"]["authentication"]["email"]["epoch"] + 3 > time()) {
|
if (!empty($_SESSION["user"]) && $_SESSION["user"]["authentication"]["email"]["code"] === $_POST['authentication_code']) {
|
||||||
//authentication code expired
|
$auth_valid = true;
|
||||||
$result["plugin"] = "email";
|
} else {
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
$auth_valid = false;
|
||||||
$result["username"] = $_SESSION["username"];
|
}
|
||||||
$result["error_message"] = 'code expired';
|
|
||||||
$result["authorized"] = false;
|
//clear posted authentication code
|
||||||
print_r($result);
|
unset($_POST['authentication_code']);
|
||||||
return $result;
|
|
||||||
exit;
|
//check if contacts app exists
|
||||||
|
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/contacts/') ? true : false;
|
||||||
|
|
||||||
|
//get the user details
|
||||||
|
if ($auth_valid) {
|
||||||
|
//get user data from the database
|
||||||
|
$sql = "select ";
|
||||||
|
$sql .= " u.user_uuid, ";
|
||||||
|
$sql .= " u.username, ";
|
||||||
|
$sql .= " u.user_email, ";
|
||||||
|
$sql .= " u.contact_uuid ";
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$sql .= ",";
|
||||||
|
$sql .= "c.contact_organization, ";
|
||||||
|
$sql .= "c.contact_name_given, ";
|
||||||
|
$sql .= "c.contact_name_family, ";
|
||||||
|
$sql .= "a.contact_attachment_uuid ";
|
||||||
}
|
}
|
||||||
|
$sql .= "from ";
|
||||||
//get the user details
|
$sql .= " v_users as u ";
|
||||||
$sql = "select user_uuid, user_email, contact_uuid\n";
|
if ($contacts_exists) {
|
||||||
$sql .= "from v_users\n";
|
$sql .= "left join v_contacts as c on u.contact_uuid = c.contact_uuid and u.contact_uuid is not null ";
|
||||||
$sql .= "where (\n";
|
$sql .= "left join v_contact_attachments as a on u.contact_uuid = a.contact_uuid and u.contact_uuid is not null and a.attachment_primary = true and a.attachment_filename is not null and a.attachment_content is not null ";
|
||||||
$sql .= " username = :username\n";
|
}
|
||||||
$sql .= " or user_email = :username\n";
|
$sql .= "where ";
|
||||||
$sql .= ")\n";
|
$sql .= " u.user_uuid = :user_uuid ";
|
||||||
if ($users_unique != "global") {
|
if ($users_unique != "global") {
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
$sql .= "and domain_uuid = :domain_uuid ";
|
$sql .= "and u.domain_uuid = :domain_uuid ";
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
}
|
}
|
||||||
$parameters['username'] = $_SESSION["username"];
|
$parameters['user_uuid'] = $_SESSION["user_uuid"];
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
$this->user_uuid = $row['user_uuid'];
|
|
||||||
$this->user_email = $row['user_email'];
|
|
||||||
$this->contact_uuid = $row['contact_uuid'];
|
|
||||||
unset($parameters);
|
unset($parameters);
|
||||||
/*
|
|
||||||
echo 'session code = '.$_SESSION["user"]["authentication"]["email"]["code"].'<br>';
|
|
||||||
echo 'post code = '.$_POST['authentication_code'].'<br>';
|
|
||||||
exit;
|
|
||||||
*/
|
|
||||||
|
|
||||||
//validate the code
|
//set a few session variables
|
||||||
if (!empty($_SESSION["user"]) && $_SESSION["user"]["authentication"]["email"]["code"] === $_POST['authentication_code']) {
|
//$_SESSION["username"] = $row['username']; //setting the username makes it skip the rest of the authentication
|
||||||
$auth_valid = true;
|
//$_SESSION["user_email"] = $row['user_email'];
|
||||||
}
|
//$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
||||||
else {
|
} else {
|
||||||
$auth_valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//clear posted authentication code
|
|
||||||
unset($_POST['authentication_code']);
|
|
||||||
|
|
||||||
//check if contacts app exists
|
|
||||||
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/contacts/') ? true : false;
|
|
||||||
|
|
||||||
//get the user details
|
|
||||||
if ($auth_valid) {
|
|
||||||
//get user data from the database
|
|
||||||
$sql = "select ";
|
|
||||||
$sql .= " u.user_uuid, ";
|
|
||||||
$sql .= " u.username, ";
|
|
||||||
$sql .= " u.user_email, ";
|
|
||||||
$sql .= " u.contact_uuid ";
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$sql .= ",";
|
|
||||||
$sql .= "c.contact_organization, ";
|
|
||||||
$sql .= "c.contact_name_given, ";
|
|
||||||
$sql .= "c.contact_name_family, ";
|
|
||||||
$sql .= "a.contact_attachment_uuid ";
|
|
||||||
}
|
|
||||||
$sql .= "from ";
|
|
||||||
$sql .= " v_users as u ";
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$sql .= "left join v_contacts as c on u.contact_uuid = c.contact_uuid and u.contact_uuid is not null ";
|
|
||||||
$sql .= "left join v_contact_attachments as a on u.contact_uuid = a.contact_uuid and u.contact_uuid is not null and a.attachment_primary = true and a.attachment_filename is not null and a.attachment_content is not null ";
|
|
||||||
}
|
|
||||||
$sql .= "where ";
|
|
||||||
$sql .= " u.user_uuid = :user_uuid ";
|
|
||||||
if ($users_unique != "global") {
|
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
|
||||||
$sql .= "and u.domain_uuid = :domain_uuid ";
|
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
|
||||||
}
|
|
||||||
$parameters['user_uuid'] = $_SESSION["user_uuid"];
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
unset($parameters);
|
|
||||||
|
|
||||||
//set a few session variables
|
|
||||||
//$_SESSION["username"] = $row['username']; //setting the username makes it skip the rest of the authentication
|
|
||||||
//$_SESSION["user_email"] = $row['user_email'];
|
|
||||||
//$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// //destroy session
|
// //destroy session
|
||||||
// session_unset();
|
// session_unset();
|
||||||
// session_destroy();
|
// session_destroy();
|
||||||
@@ -472,65 +468,65 @@ class plugin_email {
|
|||||||
// //exit the code
|
// //exit the code
|
||||||
// exit();
|
// exit();
|
||||||
|
|
||||||
//clear submitted usernames
|
//clear submitted usernames
|
||||||
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
||||||
|
|
||||||
//clear authentication session
|
//clear authentication session
|
||||||
unset($_SESSION['authentication']);
|
unset($_SESSION['authentication']);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
//check if user successfully logged in during the interval
|
|
||||||
//$sql = "select user_log_uuid, timestamp, user_name, user_agent, remote_address ";
|
|
||||||
$sql = "select count(*) as count ";
|
|
||||||
$sql .= "from v_user_logs ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and user_uuid = :user_uuid ";
|
|
||||||
$sql .= "and user_agent = :user_agent ";
|
|
||||||
$sql .= "and type = 'login' ";
|
|
||||||
$sql .= "and result = 'success' ";
|
|
||||||
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) > 3 ";
|
|
||||||
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) < 300 ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$parameters['user_uuid'] = $this->user_uuid;
|
|
||||||
$parameters['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
|
||||||
$user_log_count = $this->database->select($sql, $parameters, 'all');
|
|
||||||
//view_array($user_log_count);
|
|
||||||
unset($sql, $parameters);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//result array
|
|
||||||
$result["plugin"] = "email";
|
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
|
||||||
$result["username"] = $_SESSION["username"];
|
|
||||||
$result["user_uuid"] = $_SESSION["user_uuid"];
|
|
||||||
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
|
||||||
$result["contact_organization"] = $row["contact_organization"];
|
|
||||||
$result["contact_name_given"] = $row["contact_name_given"];
|
|
||||||
$result["contact_name_family"] = $row["contact_name_family"];
|
|
||||||
$result["contact_image"] = $row["contact_attachment_uuid"];
|
|
||||||
}
|
|
||||||
$result["authorized"] = $auth_valid ? true : false;
|
|
||||||
|
|
||||||
//add the failed login to user logs
|
|
||||||
if (!$auth_valid) {
|
|
||||||
user_logs::add($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
//retun the array
|
|
||||||
return $result;
|
|
||||||
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['plugin'] = "email";
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['domain_name'] = $_SESSION["domain_name"];
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['username'] = $row['username'];
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['user_uuid'] = $_SESSION["user_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['contact_uuid'] = $_SESSION["contact_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['domain_uuid'] = $_SESSION["domain_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['email']['authorized'] = $auth_valid ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//check if user successfully logged in during the interval
|
||||||
|
//$sql = "select user_log_uuid, timestamp, user_name, user_agent, remote_address ";
|
||||||
|
$sql = "select count(*) as count ";
|
||||||
|
$sql .= "from v_user_logs ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and user_uuid = :user_uuid ";
|
||||||
|
$sql .= "and user_agent = :user_agent ";
|
||||||
|
$sql .= "and type = 'login' ";
|
||||||
|
$sql .= "and result = 'success' ";
|
||||||
|
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) > 3 ";
|
||||||
|
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) < 300 ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$parameters['user_uuid'] = $this->user_uuid;
|
||||||
|
$parameters['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
$user_log_count = $this->database->select($sql, $parameters, 'all');
|
||||||
|
//view_array($user_log_count);
|
||||||
|
unset($sql, $parameters);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//result array
|
||||||
|
$result["plugin"] = "email";
|
||||||
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
|
$result["username"] = $_SESSION["username"];
|
||||||
|
$result["user_uuid"] = $_SESSION["user_uuid"];
|
||||||
|
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
||||||
|
$result["contact_organization"] = $row["contact_organization"];
|
||||||
|
$result["contact_name_given"] = $row["contact_name_given"];
|
||||||
|
$result["contact_name_family"] = $row["contact_name_family"];
|
||||||
|
$result["contact_image"] = $row["contact_attachment_uuid"];
|
||||||
|
}
|
||||||
|
$result["authorized"] = $auth_valid ? true : false;
|
||||||
|
|
||||||
|
//add the failed login to user logs
|
||||||
|
if (!$auth_valid) {
|
||||||
|
user_logs::add($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//retun the array
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['plugin'] = "email";
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['domain_name'] = $_SESSION["domain_name"];
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['username'] = $row['username'];
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['user_uuid'] = $_SESSION["user_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['contact_uuid'] = $_SESSION["contact_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['email']['authorized'] = $auth_valid ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class plugin_ldap {
|
|||||||
*/
|
*/
|
||||||
private $database;
|
private $database;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the object is created
|
* Called when the object is created
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -65,325 +65,322 @@ class plugin_totp {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* time based one time password aka totp
|
* time based one time password aka totp
|
||||||
|
*
|
||||||
* @return array [authorized] => true or false
|
* @return array [authorized] => true or false
|
||||||
*/
|
*/
|
||||||
function totp(authentication $auth, settings $settings) {
|
function totp(authentication $auth, settings $settings) {
|
||||||
|
|
||||||
//pre-process some settings
|
//pre-process some settings
|
||||||
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH.'/themes/default/favicon.ico');
|
$theme_favicon = $settings->get('theme', 'favicon', PROJECT_PATH . '/themes/default/favicon.ico');
|
||||||
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH.'/themes/default/images/logo_login.png');
|
$theme_logo = $settings->get('theme', 'logo', PROJECT_PATH . '/themes/default/images/logo_login.png');
|
||||||
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
$theme_login_type = $settings->get('theme', 'login_brand_type', '');
|
||||||
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
$theme_login_image = $settings->get('theme', 'login_brand_image', '');
|
||||||
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
$theme_login_text = $settings->get('theme', 'login_brand_text', '');
|
||||||
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
$theme_login_logo_width = $settings->get('theme', 'login_logo_width', 'auto; max-width: 300px');
|
||||||
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
$theme_login_logo_height = $settings->get('theme', 'login_logo_height', 'auto; max-height: 300px');
|
||||||
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
$theme_message_delay = 1000 * (float)$settings->get('theme', 'message_delay', 3000);
|
||||||
$background_videos = $settings->get('theme', 'background_video', null);
|
$background_videos = $settings->get('theme', 'background_video', null);
|
||||||
$theme_background_video = (isset($background_videos) && is_array($background_videos)) ? $background_videos[0] : null;
|
$theme_background_video = (isset($background_videos) && is_array($background_videos)) ? $background_videos[0] : null;
|
||||||
//$login_domain_name_visible = $settings->get('login', 'domain_name_visible');
|
//$login_domain_name_visible = $settings->get('login', 'domain_name_visible');
|
||||||
//$login_domain_name = $settings->get('login', 'domain_name');
|
//$login_domain_name = $settings->get('login', 'domain_name');
|
||||||
$login_destination = $settings->get('login', 'destination');
|
$login_destination = $settings->get('login', 'destination');
|
||||||
$users_unique = $settings->get('users', 'unique', '');
|
$users_unique = $settings->get('users', 'unique', '');
|
||||||
|
|
||||||
//get the username
|
//get the username
|
||||||
if (isset($_SESSION["username"])) {
|
if (isset($_SESSION["username"])) {
|
||||||
$this->username = $_SESSION["username"];
|
$this->username = $_SESSION["username"];
|
||||||
}
|
}
|
||||||
if (isset($_POST['username'])) {
|
if (isset($_POST['username'])) {
|
||||||
$this->username = $_POST['username'];
|
$this->username = $_POST['username'];
|
||||||
$_SESSION["username"] = $this->username;
|
$_SESSION["username"] = $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
//request the username
|
//request the username
|
||||||
if (!$this->username && !isset($_POST['authentication_code'])) {
|
if (!$this->username && !isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
//get the domain
|
//get the domain
|
||||||
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
||||||
$domain_name = $domain_array[0];
|
$domain_name = $domain_array[0];
|
||||||
|
|
||||||
//create token
|
//create token
|
||||||
//$object = new token;
|
//$object = new token;
|
||||||
//$token = $object->create('login');
|
//$token = $object->create('login');
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get(null, '/core/authentication');
|
$text = $language->get(null, '/core/authentication');
|
||||||
|
|
||||||
//initialize a template object
|
//initialize a template object
|
||||||
$view = new template();
|
$view = new template();
|
||||||
$view->engine = 'smarty';
|
$view->engine = 'smarty';
|
||||||
$view->template_dir = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/authentication/resources/views/';
|
$view->template_dir = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/authentication/resources/views/';
|
||||||
$view->cache_dir = sys_get_temp_dir();
|
$view->cache_dir = sys_get_temp_dir();
|
||||||
$view->init();
|
$view->init();
|
||||||
|
|
||||||
//assign default values to the template
|
//assign default values to the template
|
||||||
$view->assign("project_path", PROJECT_PATH);
|
$view->assign("project_path", PROJECT_PATH);
|
||||||
$view->assign("login_destination_url", $login_destination);
|
$view->assign("login_destination_url", $login_destination);
|
||||||
$view->assign("favicon", $theme_favicon);
|
$view->assign("favicon", $theme_favicon);
|
||||||
$view->assign("login_title", $text['label-username']);
|
$view->assign("login_title", $text['label-username']);
|
||||||
$view->assign("login_username", $text['label-username']);
|
$view->assign("login_username", $text['label-username']);
|
||||||
$view->assign("login_logo_width", $theme_login_logo_width);
|
$view->assign("login_logo_width", $theme_login_logo_width);
|
||||||
$view->assign("login_logo_height", $theme_login_logo_height);
|
$view->assign("login_logo_height", $theme_login_logo_height);
|
||||||
$view->assign("login_logo_source", $theme_logo);
|
$view->assign("login_logo_source", $theme_logo);
|
||||||
$view->assign("button_login", $text['button-login']);
|
$view->assign("button_login", $text['button-login']);
|
||||||
|
$view->assign("favicon", $theme_favicon);
|
||||||
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
|
|
||||||
|
//messages
|
||||||
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
|
//show the views
|
||||||
|
$content = $view->render('username.htm');
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//show the authentication code view
|
||||||
|
if (!isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
|
//get the username
|
||||||
|
if (!isset($this->username) && isset($_REQUEST['username'])) {
|
||||||
|
$this->username = $_REQUEST['username'];
|
||||||
|
$_SESSION['username'] = $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the domain name
|
||||||
|
if (!empty($_SESSION['username'])) {
|
||||||
|
$auth = new authentication;
|
||||||
|
$auth->get_domain();
|
||||||
|
$this->domain_uuid = $_SESSION['domain_uuid'];
|
||||||
|
$this->domain_name = $_SESSION['domain_name'];
|
||||||
|
$this->username = $_SESSION['username'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the user details
|
||||||
|
$sql = "select user_uuid, username, user_email, contact_uuid, user_totp_secret\n";
|
||||||
|
$sql .= "from v_users\n";
|
||||||
|
$sql .= "where (\n";
|
||||||
|
$sql .= " username = :username\n";
|
||||||
|
$sql .= " or user_email = :username\n";
|
||||||
|
$sql .= ")\n";
|
||||||
|
if (empty($_SESSION["users"]["unique"]["text"]) || $_SESSION["users"]["unique"]["text"] != "global") {
|
||||||
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
|
$sql .= "and domain_uuid = :domain_uuid ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
}
|
||||||
|
$sql .= "and (user_type = 'default' or user_type is null) ";
|
||||||
|
$parameters['username'] = $this->username;
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
if (empty($row) || !is_array($row) || @sizeof($row) == 0) {
|
||||||
|
//clear submitted usernames
|
||||||
|
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
||||||
|
|
||||||
|
//build the result array
|
||||||
|
$result["plugin"] = "totp";
|
||||||
|
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
|
$result["authorized"] = false;
|
||||||
|
|
||||||
|
//retun the array
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
unset($parameters);
|
||||||
|
|
||||||
|
//set class variables
|
||||||
|
$this->user_uuid = $row['user_uuid'];
|
||||||
|
$this->user_email = $row['user_email'];
|
||||||
|
$this->contact_uuid = $row['contact_uuid'];
|
||||||
|
$this->user_totp_secret = $row['user_totp_secret'];
|
||||||
|
|
||||||
|
//set a few session variables
|
||||||
|
$_SESSION["user_uuid"] = $row['user_uuid'];
|
||||||
|
$_SESSION["username"] = $row['username'];
|
||||||
|
$_SESSION["user_email"] = $row['user_email'];
|
||||||
|
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
||||||
|
|
||||||
|
//get the domain
|
||||||
|
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
||||||
|
$domain_name = $domain_array[0];
|
||||||
|
|
||||||
|
//create token
|
||||||
|
//$object = new token;
|
||||||
|
//$token = $object->create('login');
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get(null, '/core/authentication');
|
||||||
|
|
||||||
|
//initialize a template object
|
||||||
|
$view = new template();
|
||||||
|
$view->engine = 'smarty';
|
||||||
|
$view->template_dir = $_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/authentication/resources/views/';
|
||||||
|
$view->cache_dir = sys_get_temp_dir();
|
||||||
|
$view->init();
|
||||||
|
|
||||||
|
//assign values to the template
|
||||||
|
$view->assign("project_path", PROJECT_PATH);
|
||||||
|
$view->assign("login_destination_url", $login_destination);
|
||||||
|
$view->assign("favicon", $theme_favicon);
|
||||||
|
$view->assign("login_title", $text['label-verify']);
|
||||||
|
$view->assign("login_totp_description", $text['label-totp_description']);
|
||||||
|
$view->assign("login_authentication_code", $text['label-authentication_code']);
|
||||||
|
$view->assign("login_logo_width", $theme_login_logo_width);
|
||||||
|
$view->assign("login_logo_height", $theme_login_logo_height);
|
||||||
|
$view->assign("login_logo_source", $theme_logo);
|
||||||
|
$view->assign("favicon", $theme_favicon);
|
||||||
|
$view->assign("background_video", $theme_background_video);
|
||||||
|
if (!empty($_SESSION['username'])) {
|
||||||
|
$view->assign("username", $_SESSION['username']);
|
||||||
|
$view->assign("button_cancel", $text['button-cancel']);
|
||||||
|
}
|
||||||
|
|
||||||
|
//show the views
|
||||||
|
if (!empty($_SESSION['authentication']['plugin']['database']['authorized']) && empty($this->user_totp_secret)) {
|
||||||
|
|
||||||
|
//create the totp secret
|
||||||
|
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', false, true, true);
|
||||||
|
$user_totp_secret = $base32->encode(generate_password(20, 3));
|
||||||
|
$this->user_totp_secret = $user_totp_secret;
|
||||||
|
|
||||||
|
//add user setting to array for update
|
||||||
|
$x = 0;
|
||||||
|
$array['users'][$x]['user_uuid'] = $this->user_uuid;
|
||||||
|
$array['users'][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$array['users'][$x]['user_totp_secret'] = $this->user_totp_secret;
|
||||||
|
|
||||||
|
//add the user_edit permission
|
||||||
|
$p = permissions::new();
|
||||||
|
$p->add("user_edit", "temp");
|
||||||
|
|
||||||
|
//save the data
|
||||||
|
$this->database->save($array);
|
||||||
|
|
||||||
|
//remove the temporary permission
|
||||||
|
$p->delete("user_edit", "temp");
|
||||||
|
|
||||||
|
//qr code includes
|
||||||
|
require_once 'resources/qr_code/QRErrorCorrectLevel.php';
|
||||||
|
require_once 'resources/qr_code/QRCode.php';
|
||||||
|
require_once 'resources/qr_code/QRCodeImage.php';
|
||||||
|
|
||||||
|
//build the otp authentication url
|
||||||
|
$otpauth = "otpauth://totp/" . $this->username;
|
||||||
|
$otpauth .= "?secret=" . $this->user_totp_secret;
|
||||||
|
$otpauth .= "&issuer=" . $_SESSION['domain_name'];
|
||||||
|
|
||||||
|
//build the qr code image
|
||||||
|
try {
|
||||||
|
$code = new QRCode (-1, QRErrorCorrectLevel::H);
|
||||||
|
$code->addData($otpauth);
|
||||||
|
$code->make();
|
||||||
|
$img = new QRCodeImage ($code, $width = 210, $height = 210, $quality = 50);
|
||||||
|
$img->draw();
|
||||||
|
$image = $img->getImage();
|
||||||
|
$img->finish();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
echo $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//assign values to the template
|
||||||
|
$view->assign("totp_secret", $this->user_totp_secret);
|
||||||
|
$view->assign("totp_image", base64_encode($image));
|
||||||
|
$view->assign("totp_description", $text['description-totp']);
|
||||||
|
$view->assign("button_next", $text['button-next']);
|
||||||
$view->assign("favicon", $theme_favicon);
|
$view->assign("favicon", $theme_favicon);
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
|
|
||||||
//messages
|
//messages
|
||||||
$view->assign('messages', message::html(true, ' '));
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
//show the views
|
//render the template
|
||||||
$content = $view->render('username.htm');
|
$content = $view->render('totp_secret.htm');
|
||||||
echo $content;
|
} else {
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//show the authentication code view
|
|
||||||
if (!isset($_POST['authentication_code'])) {
|
|
||||||
|
|
||||||
//get the username
|
|
||||||
if (!isset($this->username) && isset($_REQUEST['username'])) {
|
|
||||||
$this->username = $_REQUEST['username'];
|
|
||||||
$_SESSION['username'] = $this->username;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the domain name
|
|
||||||
if (!empty($_SESSION['username'])) {
|
|
||||||
$auth = new authentication;
|
|
||||||
$auth->get_domain();
|
|
||||||
$this->domain_uuid = $_SESSION['domain_uuid'];
|
|
||||||
$this->domain_name = $_SESSION['domain_name'];
|
|
||||||
$this->username = $_SESSION['username'];
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the user details
|
|
||||||
$sql = "select user_uuid, username, user_email, contact_uuid, user_totp_secret\n";
|
|
||||||
$sql .= "from v_users\n";
|
|
||||||
$sql .= "where (\n";
|
|
||||||
$sql .= " username = :username\n";
|
|
||||||
$sql .= " or user_email = :username\n";
|
|
||||||
$sql .= ")\n";
|
|
||||||
if (empty($_SESSION["users"]["unique"]["text"]) || $_SESSION["users"]["unique"]["text"] != "global") {
|
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
|
||||||
$sql .= "and domain_uuid = :domain_uuid ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
$sql .= "and (user_type = 'default' or user_type is null) ";
|
|
||||||
$parameters['username'] = $this->username;
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
if (empty($row) || !is_array($row) || @sizeof($row) == 0) {
|
|
||||||
//clear submitted usernames
|
|
||||||
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
|
||||||
|
|
||||||
//build the result array
|
|
||||||
$result["plugin"] = "totp";
|
|
||||||
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
|
||||||
$result["authorized"] = false;
|
|
||||||
|
|
||||||
//retun the array
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
unset($parameters);
|
|
||||||
|
|
||||||
//set class variables
|
|
||||||
$this->user_uuid = $row['user_uuid'];
|
|
||||||
$this->user_email = $row['user_email'];
|
|
||||||
$this->contact_uuid = $row['contact_uuid'];
|
|
||||||
$this->user_totp_secret = $row['user_totp_secret'];
|
|
||||||
|
|
||||||
//set a few session variables
|
|
||||||
$_SESSION["user_uuid"] = $row['user_uuid'];
|
|
||||||
$_SESSION["username"] = $row['username'];
|
|
||||||
$_SESSION["user_email"] = $row['user_email'];
|
|
||||||
$_SESSION["contact_uuid"] = $row["contact_uuid"];
|
|
||||||
|
|
||||||
//get the domain
|
|
||||||
$domain_array = explode(":", $_SERVER["HTTP_HOST"]);
|
|
||||||
$domain_name = $domain_array[0];
|
|
||||||
|
|
||||||
//create token
|
|
||||||
//$object = new token;
|
|
||||||
//$token = $object->create('login');
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get(null, '/core/authentication');
|
|
||||||
|
|
||||||
//initialize a template object
|
|
||||||
$view = new template();
|
|
||||||
$view->engine = 'smarty';
|
|
||||||
$view->template_dir = $_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/authentication/resources/views/';
|
|
||||||
$view->cache_dir = sys_get_temp_dir();
|
|
||||||
$view->init();
|
|
||||||
|
|
||||||
//assign values to the template
|
//assign values to the template
|
||||||
$view->assign("project_path", PROJECT_PATH);
|
$view->assign("button_verify", $text['label-verify']);
|
||||||
$view->assign("login_destination_url", $login_destination);
|
$view->assign("message_delay", $theme_message_delay);
|
||||||
$view->assign("favicon", $theme_favicon);
|
|
||||||
$view->assign("login_title", $text['label-verify']);
|
|
||||||
$view->assign("login_totp_description", $text['label-totp_description']);
|
|
||||||
$view->assign("login_authentication_code", $text['label-authentication_code']);
|
|
||||||
$view->assign("login_logo_width", $theme_login_logo_width);
|
|
||||||
$view->assign("login_logo_height", $theme_login_logo_height);
|
|
||||||
$view->assign("login_logo_source", $theme_logo);
|
|
||||||
$view->assign("favicon", $theme_favicon);
|
|
||||||
$view->assign("background_video", $theme_background_video);
|
|
||||||
if (!empty($_SESSION['username'])) {
|
|
||||||
$view->assign("username", $_SESSION['username']);
|
|
||||||
$view->assign("button_cancel", $text['button-cancel']);
|
|
||||||
}
|
|
||||||
|
|
||||||
//show the views
|
//messages
|
||||||
if (!empty($_SESSION['authentication']['plugin']['database']['authorized']) && empty($this->user_totp_secret)) {
|
$view->assign('messages', message::html(true, ' '));
|
||||||
|
|
||||||
//create the totp secret
|
//render the template
|
||||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
|
$content = $view->render('totp.htm');
|
||||||
$user_totp_secret = $base32->encode(generate_password(20,3));
|
|
||||||
$this->user_totp_secret = $user_totp_secret;
|
|
||||||
|
|
||||||
//add user setting to array for update
|
|
||||||
$x = 0;
|
|
||||||
$array['users'][$x]['user_uuid'] = $this->user_uuid;
|
|
||||||
$array['users'][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$array['users'][$x]['user_totp_secret'] = $this->user_totp_secret;
|
|
||||||
|
|
||||||
//add the user_edit permission
|
|
||||||
$p = permissions::new();
|
|
||||||
$p->add("user_edit", "temp");
|
|
||||||
|
|
||||||
//save the data
|
|
||||||
$this->database->save($array);
|
|
||||||
|
|
||||||
//remove the temporary permission
|
|
||||||
$p->delete("user_edit", "temp");
|
|
||||||
|
|
||||||
//qr code includes
|
|
||||||
require_once 'resources/qr_code/QRErrorCorrectLevel.php';
|
|
||||||
require_once 'resources/qr_code/QRCode.php';
|
|
||||||
require_once 'resources/qr_code/QRCodeImage.php';
|
|
||||||
|
|
||||||
//build the otp authentication url
|
|
||||||
$otpauth = "otpauth://totp/".$this->username;
|
|
||||||
$otpauth .= "?secret=".$this->user_totp_secret;
|
|
||||||
$otpauth .= "&issuer=".$_SESSION['domain_name'];
|
|
||||||
|
|
||||||
//build the qr code image
|
|
||||||
try {
|
|
||||||
$code = new QRCode (- 1, QRErrorCorrectLevel::H);
|
|
||||||
$code->addData($otpauth);
|
|
||||||
$code->make();
|
|
||||||
$img = new QRCodeImage ($code, $width=210, $height=210, $quality=50);
|
|
||||||
$img->draw();
|
|
||||||
$image = $img->getImage();
|
|
||||||
$img->finish();
|
|
||||||
}
|
|
||||||
catch (Exception $error) {
|
|
||||||
echo $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
//assign values to the template
|
|
||||||
$view->assign("totp_secret", $this->user_totp_secret);
|
|
||||||
$view->assign("totp_image", base64_encode($image));
|
|
||||||
$view->assign("totp_description", $text['description-totp']);
|
|
||||||
$view->assign("button_next", $text['button-next']);
|
|
||||||
$view->assign("favicon", $theme_favicon);
|
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
|
||||||
|
|
||||||
//messages
|
|
||||||
$view->assign('messages', message::html(true, ' '));
|
|
||||||
|
|
||||||
//render the template
|
|
||||||
$content = $view->render('totp_secret.htm');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//assign values to the template
|
|
||||||
$view->assign("button_verify", $text['label-verify']);
|
|
||||||
$view->assign("message_delay", $theme_message_delay);
|
|
||||||
|
|
||||||
//messages
|
|
||||||
$view->assign('messages', message::html(true, ' '));
|
|
||||||
|
|
||||||
//render the template
|
|
||||||
$content = $view->render('totp.htm');
|
|
||||||
}
|
|
||||||
echo $content;
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
//if authorized then verify
|
//if authorized then verify
|
||||||
if (isset($_POST['authentication_code'])) {
|
if (isset($_POST['authentication_code'])) {
|
||||||
|
|
||||||
//get the user details
|
//get the user details
|
||||||
$sql = "select user_uuid, user_email, contact_uuid, user_totp_secret\n";
|
$sql = "select user_uuid, user_email, contact_uuid, user_totp_secret\n";
|
||||||
$sql .= "from v_users\n";
|
$sql .= "from v_users\n";
|
||||||
$sql .= "where (\n";
|
$sql .= "where (\n";
|
||||||
$sql .= " username = :username\n";
|
$sql .= " username = :username\n";
|
||||||
$sql .= " or user_email = :username\n";
|
$sql .= " or user_email = :username\n";
|
||||||
$sql .= ")\n";
|
$sql .= ")\n";
|
||||||
|
if ($users_unique != "global") {
|
||||||
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
|
$sql .= "and domain_uuid = :domain_uuid ";
|
||||||
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
|
}
|
||||||
|
$parameters['username'] = $_SESSION["username"];
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
$this->user_uuid = $row['user_uuid'];
|
||||||
|
$this->user_email = $row['user_email'];
|
||||||
|
$this->contact_uuid = $row['contact_uuid'];
|
||||||
|
$this->user_totp_secret = $row['user_totp_secret'];
|
||||||
|
unset($parameters);
|
||||||
|
|
||||||
|
//create the authenticator object
|
||||||
|
$totp = new google_authenticator;
|
||||||
|
|
||||||
|
//validate the code
|
||||||
|
if ($totp->checkCode($this->user_totp_secret, $_POST['authentication_code'])) {
|
||||||
|
$auth_valid = true;
|
||||||
|
} else {
|
||||||
|
$auth_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//clear posted authentication code
|
||||||
|
unset($_POST['authentication_code']);
|
||||||
|
|
||||||
|
//check if contacts app exists
|
||||||
|
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . '/core/contacts/') ? true : false;
|
||||||
|
|
||||||
|
//get the user details
|
||||||
|
if ($auth_valid) {
|
||||||
|
//get user data from the database
|
||||||
|
$sql = "select ";
|
||||||
|
$sql .= " u.user_uuid, ";
|
||||||
|
$sql .= " u.username, ";
|
||||||
|
$sql .= " u.user_email, ";
|
||||||
|
$sql .= " u.contact_uuid ";
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$sql .= ",";
|
||||||
|
$sql .= "c.contact_organization, ";
|
||||||
|
$sql .= "c.contact_name_given, ";
|
||||||
|
$sql .= "c.contact_name_family, ";
|
||||||
|
$sql .= "a.contact_attachment_uuid ";
|
||||||
|
}
|
||||||
|
$sql .= "from ";
|
||||||
|
$sql .= " v_users as u ";
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$sql .= "left join v_contacts as c on u.contact_uuid = c.contact_uuid and u.contact_uuid is not null ";
|
||||||
|
$sql .= "left join v_contact_attachments as a on u.contact_uuid = a.contact_uuid and u.contact_uuid is not null and a.attachment_primary = true and a.attachment_filename is not null and a.attachment_content is not null ";
|
||||||
|
}
|
||||||
|
$sql .= "where ";
|
||||||
|
$sql .= " u.user_uuid = :user_uuid ";
|
||||||
if ($users_unique != "global") {
|
if ($users_unique != "global") {
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
//unique username per domain (not globally unique across system - example: email address)
|
||||||
$sql .= "and domain_uuid = :domain_uuid ";
|
$sql .= "and u.domain_uuid = :domain_uuid ";
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
}
|
}
|
||||||
$parameters['username'] = $_SESSION["username"];
|
$parameters['user_uuid'] = $_SESSION["user_uuid"];
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
$this->user_uuid = $row['user_uuid'];
|
|
||||||
$this->user_email = $row['user_email'];
|
|
||||||
$this->contact_uuid = $row['contact_uuid'];
|
|
||||||
$this->user_totp_secret = $row['user_totp_secret'];
|
|
||||||
unset($parameters);
|
unset($parameters);
|
||||||
|
} else {
|
||||||
//create the authenticator object
|
|
||||||
$totp = new google_authenticator;
|
|
||||||
|
|
||||||
//validate the code
|
|
||||||
if ($totp->checkCode($this->user_totp_secret, $_POST['authentication_code'])) {
|
|
||||||
$auth_valid = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$auth_valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//clear posted authentication code
|
|
||||||
unset($_POST['authentication_code']);
|
|
||||||
|
|
||||||
//check if contacts app exists
|
|
||||||
$contacts_exists = file_exists($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH.'/core/contacts/') ? true : false;
|
|
||||||
|
|
||||||
//get the user details
|
|
||||||
if ($auth_valid) {
|
|
||||||
//get user data from the database
|
|
||||||
$sql = "select ";
|
|
||||||
$sql .= " u.user_uuid, ";
|
|
||||||
$sql .= " u.username, ";
|
|
||||||
$sql .= " u.user_email, ";
|
|
||||||
$sql .= " u.contact_uuid ";
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$sql .= ",";
|
|
||||||
$sql .= "c.contact_organization, ";
|
|
||||||
$sql .= "c.contact_name_given, ";
|
|
||||||
$sql .= "c.contact_name_family, ";
|
|
||||||
$sql .= "a.contact_attachment_uuid ";
|
|
||||||
}
|
|
||||||
$sql .= "from ";
|
|
||||||
$sql .= " v_users as u ";
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$sql .= "left join v_contacts as c on u.contact_uuid = c.contact_uuid and u.contact_uuid is not null ";
|
|
||||||
$sql .= "left join v_contact_attachments as a on u.contact_uuid = a.contact_uuid and u.contact_uuid is not null and a.attachment_primary = true and a.attachment_filename is not null and a.attachment_content is not null ";
|
|
||||||
}
|
|
||||||
$sql .= "where ";
|
|
||||||
$sql .= " u.user_uuid = :user_uuid ";
|
|
||||||
if ($users_unique != "global") {
|
|
||||||
//unique username per domain (not globally unique across system - example: email address)
|
|
||||||
$sql .= "and u.domain_uuid = :domain_uuid ";
|
|
||||||
$parameters['domain_uuid'] = $_SESSION["domain_uuid"];
|
|
||||||
}
|
|
||||||
$parameters['user_uuid'] = $_SESSION["user_uuid"];
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
unset($parameters);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// //destroy session
|
// //destroy session
|
||||||
// session_unset();
|
// session_unset();
|
||||||
// session_destroy();
|
// session_destroy();
|
||||||
@@ -397,64 +394,64 @@ class plugin_totp {
|
|||||||
// //exit the code
|
// //exit the code
|
||||||
// exit();
|
// exit();
|
||||||
|
|
||||||
//clear authentication session
|
//clear authentication session
|
||||||
unset($_SESSION['authentication']);
|
unset($_SESSION['authentication']);
|
||||||
|
|
||||||
// clear username
|
// clear username
|
||||||
unset($_SESSION["username"]);
|
unset($_SESSION["username"]);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
//check if user successfully logged in during the interval
|
|
||||||
//$sql = "select user_log_uuid, timestamp, user_name, user_agent, remote_address ";
|
|
||||||
$sql = "select count(*) as count ";
|
|
||||||
$sql .= "from v_user_logs ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and user_uuid = :user_uuid ";
|
|
||||||
$sql .= "and user_agent = :user_agent ";
|
|
||||||
$sql .= "and type = 'login' ";
|
|
||||||
$sql .= "and result = 'success' ";
|
|
||||||
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) > 3 ";
|
|
||||||
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) < 300 ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$parameters['user_uuid'] = $this->user_uuid;
|
|
||||||
$parameters['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
|
||||||
$user_log_count = $this->database->select($sql, $parameters, 'all');
|
|
||||||
//view_array($user_log_count);
|
|
||||||
unset($sql, $parameters);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//build the result array
|
|
||||||
$result["plugin"] = "totp";
|
|
||||||
$result["domain_name"] = $_SESSION["domain_name"];
|
|
||||||
$result["username"] = $_SESSION["username"] ?? null;
|
|
||||||
$result["user_uuid"] = $_SESSION["user_uuid"];
|
|
||||||
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
|
||||||
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
|
||||||
if ($contacts_exists) {
|
|
||||||
$result["contact_organization"] = $row["contact_organization"];
|
|
||||||
$result["contact_name_given"] = $row["contact_name_given"];
|
|
||||||
$result["contact_name_family"] = $row["contact_name_family"];
|
|
||||||
$result["contact_image"] = $row["contact_attachment_uuid"];
|
|
||||||
}
|
|
||||||
$result["authorized"] = $auth_valid ? true : false;
|
|
||||||
|
|
||||||
//add the failed login to user logs
|
|
||||||
if (!$auth_valid) {
|
|
||||||
user_logs::add($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
//retun the array
|
|
||||||
return $result;
|
|
||||||
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['plugin'] = "totp";
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['domain_name'] = $_SESSION["domain_name"];
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['username'] = $row['username'];
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['user_uuid'] = $_SESSION["user_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['contact_uuid'] = $_SESSION["contact_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['domain_uuid'] = $_SESSION["domain_uuid"];
|
|
||||||
//$_SESSION['authentication']['plugin']['totp']['authorized'] = $auth_valid ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//check if user successfully logged in during the interval
|
||||||
|
//$sql = "select user_log_uuid, timestamp, user_name, user_agent, remote_address ";
|
||||||
|
$sql = "select count(*) as count ";
|
||||||
|
$sql .= "from v_user_logs ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and user_uuid = :user_uuid ";
|
||||||
|
$sql .= "and user_agent = :user_agent ";
|
||||||
|
$sql .= "and type = 'login' ";
|
||||||
|
$sql .= "and result = 'success' ";
|
||||||
|
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) > 3 ";
|
||||||
|
$sql .= "and floor(extract(epoch from now()) - extract(epoch from timestamp)) < 300 ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$parameters['user_uuid'] = $this->user_uuid;
|
||||||
|
$parameters['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
$user_log_count = $this->database->select($sql, $parameters, 'all');
|
||||||
|
//view_array($user_log_count);
|
||||||
|
unset($sql, $parameters);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//build the result array
|
||||||
|
$result["plugin"] = "totp";
|
||||||
|
$result["domain_name"] = $_SESSION["domain_name"];
|
||||||
|
$result["username"] = $_SESSION["username"] ?? null;
|
||||||
|
$result["user_uuid"] = $_SESSION["user_uuid"];
|
||||||
|
$result["domain_uuid"] = $_SESSION["domain_uuid"];
|
||||||
|
$result["contact_uuid"] = $_SESSION["contact_uuid"];
|
||||||
|
if ($contacts_exists) {
|
||||||
|
$result["contact_organization"] = $row["contact_organization"];
|
||||||
|
$result["contact_name_given"] = $row["contact_name_given"];
|
||||||
|
$result["contact_name_family"] = $row["contact_name_family"];
|
||||||
|
$result["contact_image"] = $row["contact_attachment_uuid"];
|
||||||
|
}
|
||||||
|
$result["authorized"] = $auth_valid ? true : false;
|
||||||
|
|
||||||
|
//add the failed login to user logs
|
||||||
|
if (!$auth_valid) {
|
||||||
|
user_logs::add($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//retun the array
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['plugin'] = "totp";
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['domain_name'] = $_SESSION["domain_name"];
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['username'] = $row['username'];
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['user_uuid'] = $_SESSION["user_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['contact_uuid'] = $_SESSION["contact_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['domain_uuid'] = $_SESSION["domain_uuid"];
|
||||||
|
//$_SESSION['authentication']['plugin']['totp']['authorized'] = $auth_valid ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,18 +38,6 @@
|
|||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduct the functionality but requirs PHP 5.1.0 or higher
|
|
||||||
if (!function_exists('str_getcsv')) {
|
|
||||||
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
|
|
||||||
$fp = fopen("php://memory", 'r+');
|
|
||||||
fputs($fp, $input);
|
|
||||||
rewind($fp);
|
|
||||||
$data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
|
|
||||||
fclose($fp);
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the max php execution time
|
//set the max php execution time
|
||||||
ini_set('max_execution_time', 7200);
|
ini_set('max_execution_time', 7200);
|
||||||
|
|
||||||
@@ -252,6 +240,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//get the parent table
|
//get the parent table
|
||||||
|
/**
|
||||||
|
* Retrieves the parent table name from a given schema based on the provided table name.
|
||||||
|
*
|
||||||
|
* @param array $schema A list of tables and their properties in the database schema.
|
||||||
|
* @param string $table_name The name of the table for which to retrieve the parent.
|
||||||
|
*
|
||||||
|
* @return string|null The parent table name, or null if no match is found.
|
||||||
|
*/
|
||||||
function get_parent($schema,$table_name) {
|
function get_parent($schema,$table_name) {
|
||||||
foreach ($schema as $row) {
|
foreach ($schema as $row) {
|
||||||
if ($row['table'] == $table_name) {
|
if ($row['table'] == $table_name) {
|
||||||
|
|||||||
@@ -581,6 +581,13 @@ require_once "resources/footer.php";
|
|||||||
|
|
||||||
|
|
||||||
// used above
|
// used above
|
||||||
|
/**
|
||||||
|
* Retrieves the contents of a URL using cURL.
|
||||||
|
*
|
||||||
|
* @param string $url The URL to retrieve.
|
||||||
|
*
|
||||||
|
* @return string The contents of the retrieved URL, or FALSE if an error occurred.
|
||||||
|
*/
|
||||||
function curl_file_get_contents($url) {
|
function curl_file_get_contents($url) {
|
||||||
$curl = curl_init();
|
$curl = curl_init();
|
||||||
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
|
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
|
||||||
|
|||||||
@@ -25,262 +25,304 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the contacts class
|
//define the contacts class
|
||||||
class contacts {
|
class contacts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'contacts';
|
const app_name = 'contacts';
|
||||||
const app_uuid = '04481e0e-a478-c559-adad-52bd4174574c';
|
const app_uuid = '04481e0e-a478-c559-adad-52bd4174574c';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
private $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $permission_prefix;
|
private $permission_prefix;
|
||||||
private $list_page;
|
private $list_page;
|
||||||
private $tables;
|
private $tables;
|
||||||
private $table;
|
private $table;
|
||||||
private $uuid_prefix;
|
private $uuid_prefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare public variables
|
* declare public variables
|
||||||
*/
|
*/
|
||||||
public $contact_uuid;
|
public $contact_uuid;
|
||||||
|
|
||||||
/**
|
|
||||||
* called when the object is created
|
|
||||||
*/
|
|
||||||
public function __construct(array $setting_array = []) {
|
|
||||||
//set domain and user UUIDs
|
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
|
||||||
|
|
||||||
//set objects
|
/**
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
* Constructor for the class.
|
||||||
|
*
|
||||||
|
* This method initializes the object with setting_array and session data.
|
||||||
|
*
|
||||||
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//assign private variables
|
//set objects
|
||||||
$this->permission_prefix = 'contact_';
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
$this->list_page = 'contacts.php';
|
|
||||||
$this->tables[] = 'contact_addresses';
|
|
||||||
$this->tables[] = 'contact_attachments';
|
|
||||||
$this->tables[] = 'contact_emails';
|
|
||||||
$this->tables[] = 'contact_groups';
|
|
||||||
$this->tables[] = 'contact_notes';
|
|
||||||
$this->tables[] = 'contact_phones';
|
|
||||||
$this->tables[] = 'contact_relations';
|
|
||||||
$this->tables[] = 'contact_settings';
|
|
||||||
$this->tables[] = 'contact_times';
|
|
||||||
$this->tables[] = 'contact_urls';
|
|
||||||
$this->tables[] = 'contact_users';
|
|
||||||
$this->tables[] = 'contacts';
|
|
||||||
$this->uuid_prefix = 'contact_';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
//assign private variables
|
||||||
* delete records
|
$this->permission_prefix = 'contact_';
|
||||||
*/
|
$this->list_page = 'contacts.php';
|
||||||
public function delete($records) {
|
$this->tables[] = 'contact_addresses';
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
$this->tables[] = 'contact_attachments';
|
||||||
|
$this->tables[] = 'contact_emails';
|
||||||
|
$this->tables[] = 'contact_groups';
|
||||||
|
$this->tables[] = 'contact_notes';
|
||||||
|
$this->tables[] = 'contact_phones';
|
||||||
|
$this->tables[] = 'contact_relations';
|
||||||
|
$this->tables[] = 'contact_settings';
|
||||||
|
$this->tables[] = 'contact_times';
|
||||||
|
$this->tables[] = 'contact_urls';
|
||||||
|
$this->tables[] = 'contact_users';
|
||||||
|
$this->tables[] = 'contacts';
|
||||||
|
$this->uuid_prefix = 'contact_';
|
||||||
|
}
|
||||||
|
|
||||||
//add multi-lingual support
|
/**
|
||||||
$language = new text;
|
* Deletes one or multiple records.
|
||||||
$text = $language->get();
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete multiple records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//build the delete array
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
if (is_array($this->tables) && @sizeof($this->tables) != 0) {
|
|
||||||
foreach ($this->tables as $table) {
|
|
||||||
$array[$table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
$array[$table][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//grant temp permissions
|
|
||||||
$p = permissions::new();
|
|
||||||
foreach ($this->tables as $table) {
|
|
||||||
$p->add(database::singular($table).'_delete', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//revoke temp permissions
|
|
||||||
foreach ($this->tables as $table) {
|
|
||||||
$p->delete(database::singular($table).'_delete', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete_properties($records) {
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->list_page);
|
header('Location: ' . $this->list_page);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//delete multiple records
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
//check permissions and build the delete array
|
//build the delete array
|
||||||
$x = 0;
|
foreach ($records as $x => $record) {
|
||||||
foreach ($records as $property_name => $properties) {
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
if (permission_exists(database::singular($property_name).'_delete')) {
|
if (is_array($this->tables) && @sizeof($this->tables) != 0) {
|
||||||
if (is_array($properties) && @sizeof($properties) != 0) {
|
foreach ($this->tables as $table) {
|
||||||
foreach ($properties as $property) {
|
$array[$table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
if ($property['checked'] == 'true' && is_uuid($property['uuid'])) {
|
$array[$table][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
$array[$property_name][$x][database::singular($property_name).'_uuid'] = $property['uuid'];
|
|
||||||
$array[$property_name][$x]['contact_uuid'] = $this->contact_uuid;
|
|
||||||
$array[$property_name][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function delete_users($records) {
|
//delete the checked rows
|
||||||
//assign private variables
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
$this->permission_prefix = 'contact_user_';
|
|
||||||
$this->table = 'contact_users';
|
|
||||||
$this->uuid_prefix = 'contact_user_';
|
|
||||||
|
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
//grant temp permissions
|
||||||
|
$p = permissions::new();
|
||||||
//add multi-lingual support
|
foreach ($this->tables as $table) {
|
||||||
$language = new text;
|
$p->add(database::singular($table) . '_delete', 'temp');
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//execute delete
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
//filter out unchecked ivr menu options, build delete array
|
//revoke temp permissions
|
||||||
$x = 0;
|
foreach ($this->tables as $table) {
|
||||||
foreach ($records as $record) {
|
$p->delete(database::singular($table) . '_delete', 'temp');
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
$array[$this->table][$x]['contact_uuid'] = $this->contact_uuid;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function delete_groups($records) {
|
/**
|
||||||
//assign private variables
|
* Deletes one or multiple records.
|
||||||
$this->permission_prefix = 'contact_group_';
|
*
|
||||||
$this->table = 'contact_groups';
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
$this->uuid_prefix = 'contact_group_';
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete_properties($records) {
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
//add multi-lingual support
|
//delete multiple records
|
||||||
$language = new text;
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
//check permissions and build the delete array
|
||||||
$token = new token;
|
$x = 0;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
foreach ($records as $property_name => $properties) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
if (permission_exists(database::singular($property_name) . '_delete')) {
|
||||||
header('Location: '.$this->list_page);
|
if (is_array($properties) && @sizeof($properties) != 0) {
|
||||||
exit;
|
foreach ($properties as $property) {
|
||||||
}
|
if ($property['checked'] == 'true' && is_uuid($property['uuid'])) {
|
||||||
|
$array[$property_name][$x][database::singular($property_name) . '_uuid'] = $property['uuid'];
|
||||||
//delete multiple records
|
$array[$property_name][$x]['contact_uuid'] = $this->contact_uuid;
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
$array[$property_name][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$x++;
|
||||||
//filter out unchecked ivr menu options, build delete array
|
|
||||||
$x = 0;
|
|
||||||
foreach ($records as $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
$array[$this->table][$x]['contact_uuid'] = $this->contact_uuid;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} //method
|
|
||||||
|
|
||||||
} //class
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes one or multiple records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete_users($records) {
|
||||||
|
//assign private variables
|
||||||
|
$this->permission_prefix = 'contact_user_';
|
||||||
|
$this->table = 'contact_users';
|
||||||
|
$this->uuid_prefix = 'contact_user_';
|
||||||
|
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//filter out unchecked ivr menu options, build delete array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
$array[$this->table][$x]['contact_uuid'] = $this->contact_uuid;
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes one or multiple records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete_groups($records) {
|
||||||
|
//assign private variables
|
||||||
|
$this->permission_prefix = 'contact_group_';
|
||||||
|
$this->table = 'contact_groups';
|
||||||
|
$this->uuid_prefix = 'contact_group_';
|
||||||
|
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//filter out unchecked ivr menu options, build delete array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
$array[$this->table][$x]['contact_uuid'] = $this->contact_uuid;
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //method
|
||||||
|
|
||||||
|
} //class
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,149 +25,161 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the databases class
|
//define the databases class
|
||||||
class databases {
|
class databases {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'databases';
|
const app_name = 'databases';
|
||||||
const app_uuid = '8d229b6d-1383-fcec-74c6-4ce1682479e2';
|
const app_uuid = '8d229b6d-1383-fcec-74c6-4ce1682479e2';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private $database;
|
private $database;
|
||||||
private $permission_prefix;
|
private $permission_prefix;
|
||||||
private $list_page;
|
private $list_page;
|
||||||
private $table;
|
private $table;
|
||||||
private $uuid_prefix;
|
private $uuid_prefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Initializes the object by setting default values and connecting to the database.
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
|
|
||||||
//assign private variables
|
//assign private variables
|
||||||
$this->permission_prefix = 'database_';
|
$this->permission_prefix = 'database_';
|
||||||
$this->list_page = 'databases.php';
|
$this->list_page = 'databases.php';
|
||||||
$this->table = 'databases';
|
$this->table = 'databases';
|
||||||
$this->uuid_prefix = 'database_';
|
$this->uuid_prefix = 'database_';
|
||||||
|
|
||||||
//connect to the database
|
//connect to the database
|
||||||
if (empty($this->database)) {
|
if (empty($this->database)) {
|
||||||
$this->database = database::new();
|
$this->database = database::new();
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* delete records
|
|
||||||
*/
|
|
||||||
public function delete($records) {
|
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete multiple records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//build the delete array
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* copy records
|
|
||||||
*/
|
|
||||||
public function copy($records) {
|
|
||||||
if (permission_exists($this->permission_prefix.'add')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get checked records
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//create insert array from existing data
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select * from v_".$this->table." ";
|
|
||||||
$sql .= "where ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $x => $row) {
|
|
||||||
|
|
||||||
//copy data
|
|
||||||
$array[$this->table][$x] = $row;
|
|
||||||
|
|
||||||
//overwrite
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
|
|
||||||
$array[$this->table][$x]['database_description'] = trim($row['database_description'].' ('.$text['label-copy'].')');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes and set the message
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-copy']);
|
|
||||||
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes one or multiple records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//build the delete array
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies one or more records
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function copy($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'add')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get checked records
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create insert array from existing data
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select * from v_" . $this->table . " ";
|
||||||
|
$sql .= "where " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $x => $row) {
|
||||||
|
|
||||||
|
//copy data
|
||||||
|
$array[$this->table][$x] = $row;
|
||||||
|
|
||||||
|
//overwrite
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
|
||||||
|
$array[$this->table][$x]['database_description'] = trim($row['database_description'] . ' (' . $text['label-copy'] . ')');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes and set the message
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-copy']);
|
||||||
|
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -230,6 +230,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//create a function to find matching row in array and return the row or boolean
|
//create a function to find matching row in array and return the row or boolean
|
||||||
|
/**
|
||||||
|
* Searches for a value in an array and returns the corresponding row or boolean result.
|
||||||
|
*
|
||||||
|
* @param array $search_array The array to search in.
|
||||||
|
* @param string $field The field name to match.
|
||||||
|
* @param mixed $value The value to search for.
|
||||||
|
* @param string $type The type of result to return. Can be 'boolean' or 'row'. Defaults to 'boolean'.
|
||||||
|
*
|
||||||
|
* @return bool|mixed The found row if $type is 'row', true if the value exists and $type is 'boolean', false otherwise.
|
||||||
|
*/
|
||||||
function find_in_array($search_array, $field, $value, $type = 'boolean') {
|
function find_in_array($search_array, $field, $value, $type = 'boolean') {
|
||||||
foreach($search_array as $row) {
|
foreach($search_array as $row) {
|
||||||
if ($row[$field] == $value) {
|
if ($row[$field] == $value) {
|
||||||
|
|||||||
@@ -27,309 +27,333 @@
|
|||||||
/**
|
/**
|
||||||
* default_settings class
|
* default_settings class
|
||||||
*/
|
*/
|
||||||
class default_settings {
|
class default_settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'default_settings';
|
const app_name = 'default_settings';
|
||||||
const app_uuid = '2c2453c0-1bea-4475-9f44-4d969650de09';
|
const app_uuid = '2c2453c0-1bea-4475-9f44-4d969650de09';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
public $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
public $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
private $table;
|
private $table;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
private $location;
|
private $location;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set domain and user UUIDs
|
*
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//set objects
|
//set objects
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
|
||||||
//assign the variables
|
//assign the variables
|
||||||
$this->name = 'default_setting';
|
$this->name = 'default_setting';
|
||||||
$this->table = 'default_settings';
|
$this->table = 'default_settings';
|
||||||
$this->toggle_field = 'default_setting_enabled';
|
$this->toggle_field = 'default_setting_enabled';
|
||||||
$this->toggle_values = ['true','false'];
|
$this->toggle_values = ['true', 'false'];
|
||||||
$this->location = 'default_settings.php';
|
$this->location = 'default_settings.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete rows from the database
|
* Deletes one or multiple records.
|
||||||
*/
|
*
|
||||||
public function delete($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->name.'_delete')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->name . '_delete')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->location);
|
header('Location: ' . $this->location);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
//build the delete array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($records as $record) {
|
||||||
|
//add to the array
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//increment the id
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
$x++;
|
||||||
//build the delete array
|
}
|
||||||
$x = 0;
|
|
||||||
foreach ($records as $record) {
|
|
||||||
//add to the array
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
|
|
||||||
}
|
|
||||||
|
|
||||||
//increment the id
|
//delete the checked rows
|
||||||
$x++;
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
}
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
//delete the checked rows
|
//set message
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
message::add($text['message-delete']);
|
||||||
//execute delete
|
}
|
||||||
$this->database->delete($array);
|
unset($records);
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggle a field between two values
|
* Toggles the state of one or more records.
|
||||||
*/
|
*
|
||||||
public function toggle($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->name.'_edit')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function toggle($records) {
|
||||||
|
if (permission_exists($this->name . '_edit')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->location);
|
header('Location: ' . $this->location);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//toggle the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
//get current toggle state
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//toggle the checked records
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
|
||||||
//get current toggle state
|
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
foreach($records as $record) {
|
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
foreach ($rows as $row) {
|
||||||
}
|
$states[$row['uuid']] = $row['toggle'];
|
||||||
}
|
}
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
|
|
||||||
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$states[$row['uuid']] = $row['toggle'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build update array
|
|
||||||
$x = 0;
|
|
||||||
foreach($states as $uuid => $state) {
|
|
||||||
//create the array
|
|
||||||
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
|
|
||||||
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
|
||||||
|
|
||||||
//increment the id
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-toggle']);
|
|
||||||
}
|
|
||||||
unset($records, $states);
|
|
||||||
}
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//build update array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($states as $uuid => $state) {
|
||||||
|
//create the array
|
||||||
|
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
|
||||||
|
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
||||||
|
|
||||||
|
//increment the id
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-toggle']);
|
||||||
|
}
|
||||||
|
unset($records, $states);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* copy rows from the database
|
* Copies one or more records
|
||||||
*/
|
*
|
||||||
public function copy($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->name.'_add')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function copy($records) {
|
||||||
|
if (permission_exists($this->name . '_add')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->location);
|
header('Location: ' . $this->location);
|
||||||
exit;
|
exit;
|
||||||
}
|
|
||||||
|
|
||||||
//copy the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get checked records
|
|
||||||
foreach($records as $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = $record['uuid'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy settings
|
|
||||||
if (is_array($uuids) && sizeof($uuids) > 0) {
|
|
||||||
$settings_copied = 0;
|
|
||||||
foreach ($uuids as $x => $uuid) {
|
|
||||||
|
|
||||||
// get default setting from db
|
|
||||||
$sql = "select * from v_default_settings ";
|
|
||||||
$sql .= "where default_setting_uuid = :default_setting_uuid ";
|
|
||||||
$parameters['default_setting_uuid'] = $uuid;
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
if (is_array($row) && sizeof($row) != 0) {
|
|
||||||
$default_setting_category = $row["default_setting_category"];
|
|
||||||
$default_setting_subcategory = $row["default_setting_subcategory"];
|
|
||||||
$default_setting_name = $row["default_setting_name"];
|
|
||||||
$default_setting_value = $row["default_setting_value"];
|
|
||||||
$default_setting_order = $row["default_setting_order"];
|
|
||||||
$default_setting_enabled = $row["default_setting_enabled"];
|
|
||||||
$default_setting_description = $row["default_setting_description"];
|
|
||||||
$default_setting = $row; // all values
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $row);
|
|
||||||
|
|
||||||
//set a random password for http_auth_password
|
|
||||||
if ($default_setting_subcategory == "http_auth_password") {
|
|
||||||
$default_setting_value = generate_password();
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy to domain
|
|
||||||
if (is_uuid($this->domain_uuid)) {
|
|
||||||
|
|
||||||
// check if exists
|
|
||||||
$sql = "select domain_setting_uuid from v_domain_settings ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and domain_setting_category = :domain_setting_category ";
|
|
||||||
$sql .= "and domain_setting_subcategory = :domain_setting_subcategory ";
|
|
||||||
$sql .= "and domain_setting_name = :domain_setting_name ";
|
|
||||||
$sql .= "and domain_setting_name <> 'array' ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$parameters['domain_setting_category'] = $default_setting_category;
|
|
||||||
$parameters['domain_setting_subcategory'] = $default_setting_subcategory;
|
|
||||||
$parameters['domain_setting_name'] = $default_setting_name;
|
|
||||||
$target_domain_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
|
||||||
$message = $this->database->message;
|
|
||||||
|
|
||||||
$action = is_uuid($target_domain_setting_uuid) ? 'update' : 'add';
|
|
||||||
unset($sql, $parameters);
|
|
||||||
|
|
||||||
// fix null
|
|
||||||
$default_setting_order = $default_setting_order != '' ? $default_setting_order : null;
|
|
||||||
|
|
||||||
//begin array
|
|
||||||
$array['domain_settings'][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_category'] = $default_setting_category;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_subcategory'] = $default_setting_subcategory;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_name'] = $default_setting_name;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_value'] = $default_setting_value;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_order'] = $default_setting_order;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_enabled'] = $default_setting_enabled ?: 0;
|
|
||||||
$array['domain_settings'][$x]['domain_setting_description'] = $default_setting_description;
|
|
||||||
|
|
||||||
//insert
|
|
||||||
if ($action == "add" && permission_exists("domain_select") && permission_exists("domain_setting_add") && count($_SESSION['domains']) > 1) {
|
|
||||||
$array['domain_settings'][$x]['domain_setting_uuid'] = uuid();
|
|
||||||
}
|
|
||||||
//update
|
|
||||||
if ($action == "update" && permission_exists('domain_setting_edit')) {
|
|
||||||
$array['domain_settings'][$x]['domain_setting_uuid'] = $target_domain_setting_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//execute
|
|
||||||
if (is_uuid($array['domain_settings'][$x]['domain_setting_uuid'])) {
|
|
||||||
$this->database->save($array);
|
|
||||||
$message = $this->database->message;
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
$settings_copied++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//duplicate default setting
|
|
||||||
else {
|
|
||||||
|
|
||||||
//populate and adjust array
|
|
||||||
$array['default_settings'][$x] = $default_setting;
|
|
||||||
$array['default_settings'][$x]['default_setting_uuid'] = uuid();
|
|
||||||
$array['default_settings'][$x]['default_setting_enabled'] = $default_setting_enabled ?: 0;
|
|
||||||
$array['default_settings'][$x]['default_setting_description'] .= ' (Copy)';
|
|
||||||
unset($array['default_settings'][$x]['insert_date']);
|
|
||||||
unset($array['default_settings'][$x]['insert_user']);
|
|
||||||
unset($array['default_settings'][$x]['update_date']);
|
|
||||||
unset($array['default_settings'][$x]['update_user']);
|
|
||||||
|
|
||||||
//execute
|
|
||||||
$this->database->save($array);
|
|
||||||
$message = $this->database->message;
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
$settings_copied++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // foreach
|
|
||||||
}
|
|
||||||
|
|
||||||
//set message
|
|
||||||
if ($settings_copied != 0) {
|
|
||||||
message::add($text['message-copy']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} //method
|
|
||||||
|
|
||||||
} //class
|
//copy the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get checked records
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = $record['uuid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy settings
|
||||||
|
if (is_array($uuids) && sizeof($uuids) > 0) {
|
||||||
|
$settings_copied = 0;
|
||||||
|
foreach ($uuids as $x => $uuid) {
|
||||||
|
|
||||||
|
// get default setting from db
|
||||||
|
$sql = "select * from v_default_settings ";
|
||||||
|
$sql .= "where default_setting_uuid = :default_setting_uuid ";
|
||||||
|
$parameters['default_setting_uuid'] = $uuid;
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
if (is_array($row) && sizeof($row) != 0) {
|
||||||
|
$default_setting_category = $row["default_setting_category"];
|
||||||
|
$default_setting_subcategory = $row["default_setting_subcategory"];
|
||||||
|
$default_setting_name = $row["default_setting_name"];
|
||||||
|
$default_setting_value = $row["default_setting_value"];
|
||||||
|
$default_setting_order = $row["default_setting_order"];
|
||||||
|
$default_setting_enabled = $row["default_setting_enabled"];
|
||||||
|
$default_setting_description = $row["default_setting_description"];
|
||||||
|
$default_setting = $row; // all values
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $row);
|
||||||
|
|
||||||
|
//set a random password for http_auth_password
|
||||||
|
if ($default_setting_subcategory == "http_auth_password") {
|
||||||
|
$default_setting_value = generate_password();
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy to domain
|
||||||
|
if (is_uuid($this->domain_uuid)) {
|
||||||
|
|
||||||
|
// check if exists
|
||||||
|
$sql = "select domain_setting_uuid from v_domain_settings ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and domain_setting_category = :domain_setting_category ";
|
||||||
|
$sql .= "and domain_setting_subcategory = :domain_setting_subcategory ";
|
||||||
|
$sql .= "and domain_setting_name = :domain_setting_name ";
|
||||||
|
$sql .= "and domain_setting_name <> 'array' ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$parameters['domain_setting_category'] = $default_setting_category;
|
||||||
|
$parameters['domain_setting_subcategory'] = $default_setting_subcategory;
|
||||||
|
$parameters['domain_setting_name'] = $default_setting_name;
|
||||||
|
$target_domain_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
||||||
|
$message = $this->database->message;
|
||||||
|
|
||||||
|
$action = is_uuid($target_domain_setting_uuid) ? 'update' : 'add';
|
||||||
|
unset($sql, $parameters);
|
||||||
|
|
||||||
|
// fix null
|
||||||
|
$default_setting_order = $default_setting_order != '' ? $default_setting_order : null;
|
||||||
|
|
||||||
|
//begin array
|
||||||
|
$array['domain_settings'][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_category'] = $default_setting_category;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_subcategory'] = $default_setting_subcategory;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_name'] = $default_setting_name;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_value'] = $default_setting_value;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_order'] = $default_setting_order;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_enabled'] = $default_setting_enabled ?: 0;
|
||||||
|
$array['domain_settings'][$x]['domain_setting_description'] = $default_setting_description;
|
||||||
|
|
||||||
|
//insert
|
||||||
|
if ($action == "add" && permission_exists("domain_select") && permission_exists("domain_setting_add") && count($_SESSION['domains']) > 1) {
|
||||||
|
$array['domain_settings'][$x]['domain_setting_uuid'] = uuid();
|
||||||
|
}
|
||||||
|
//update
|
||||||
|
if ($action == "update" && permission_exists('domain_setting_edit')) {
|
||||||
|
$array['domain_settings'][$x]['domain_setting_uuid'] = $target_domain_setting_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (is_uuid($array['domain_settings'][$x]['domain_setting_uuid'])) {
|
||||||
|
$this->database->save($array);
|
||||||
|
$message = $this->database->message;
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
$settings_copied++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //duplicate default setting
|
||||||
|
else {
|
||||||
|
|
||||||
|
//populate and adjust array
|
||||||
|
$array['default_settings'][$x] = $default_setting;
|
||||||
|
$array['default_settings'][$x]['default_setting_uuid'] = uuid();
|
||||||
|
$array['default_settings'][$x]['default_setting_enabled'] = $default_setting_enabled ?: 0;
|
||||||
|
$array['default_settings'][$x]['default_setting_description'] .= ' (Copy)';
|
||||||
|
unset($array['default_settings'][$x]['insert_date']);
|
||||||
|
unset($array['default_settings'][$x]['insert_user']);
|
||||||
|
unset($array['default_settings'][$x]['update_date']);
|
||||||
|
unset($array['default_settings'][$x]['update_user']);
|
||||||
|
|
||||||
|
//execute
|
||||||
|
$this->database->save($array);
|
||||||
|
$message = $this->database->message;
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
$settings_copied++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // foreach
|
||||||
|
}
|
||||||
|
|
||||||
|
//set message
|
||||||
|
if ($settings_copied != 0) {
|
||||||
|
message::add($text['message-copy']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //method
|
||||||
|
|
||||||
|
} //class
|
||||||
|
|||||||
@@ -25,375 +25,401 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the domain settings class
|
//define the domain settings class
|
||||||
class domain_settings {
|
class domain_settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'domain_settings';
|
const app_name = 'domain_settings';
|
||||||
const app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
const app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain name set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
public $domain_name;
|
* @var string
|
||||||
|
*/
|
||||||
|
public $domain_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare public variables
|
* declare public variables
|
||||||
*/
|
*/
|
||||||
public $domain_uuid;
|
public $domain_uuid;
|
||||||
public $domain_uuid_target;
|
public $domain_uuid_target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $permission_prefix;
|
private $permission_prefix;
|
||||||
private $list_page;
|
private $list_page;
|
||||||
private $table;
|
private $table;
|
||||||
private $uuid_prefix;
|
private $uuid_prefix;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set domain and user UUIDs
|
*
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//set objects
|
//set objects
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
|
||||||
//assign private variables
|
//assign private variables
|
||||||
$this->permission_prefix = 'domain_setting_';
|
$this->permission_prefix = 'domain_setting_';
|
||||||
$this->list_page = PROJECT_PATH."/core/domains/domain_edit.php?id=".urlencode($this->domain_uuid ?? '');
|
$this->list_page = PROJECT_PATH . "/core/domains/domain_edit.php?id=" . urlencode($this->domain_uuid ?? '');
|
||||||
$this->table = 'domain_settings';
|
$this->table = 'domain_settings';
|
||||||
$this->uuid_prefix = 'domain_setting_';
|
$this->uuid_prefix = 'domain_setting_';
|
||||||
$this->toggle_field = 'domain_setting_enabled';
|
$this->toggle_field = 'domain_setting_enabled';
|
||||||
$this->toggle_values = ['true','false'];
|
$this->toggle_values = ['true', 'false'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete records
|
* Deletes one or multiple records.
|
||||||
*/
|
*
|
||||||
public function delete($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->list_page);
|
header('Location: ' . $this->list_page);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//build the delete array
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//delete the checked rows
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
//build the delete array
|
//execute delete
|
||||||
foreach ($records as $x => $record) {
|
$this->database->delete($array);
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
unset($array);
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
//set message
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
//execute delete
|
unset($records);
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggle records
|
* Toggles the state of one or more records.
|
||||||
*/
|
*
|
||||||
public function toggle($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->permission_prefix.'edit')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function toggle($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'edit')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//toggle the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get current toggle state
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$rows = $this->database->select($sql, $parameters, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$states[$row['uuid']] = $row['toggle'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build update array
|
|
||||||
if (is_array($states) && @sizeof($states) != 0) {
|
|
||||||
$x = 0;
|
|
||||||
foreach ($states as $uuid => $state) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
|
|
||||||
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-toggle']);
|
|
||||||
}
|
|
||||||
unset($records, $states);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//toggle the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get current toggle state
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$rows = $this->database->select($sql, $parameters, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$states[$row['uuid']] = $row['toggle'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//build update array
|
||||||
|
if (is_array($states) && @sizeof($states) != 0) {
|
||||||
|
$x = 0;
|
||||||
|
foreach ($states as $uuid => $state) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
|
||||||
|
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-toggle']);
|
||||||
|
}
|
||||||
|
unset($records, $states);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* copy records
|
* Copies one or more records
|
||||||
*/
|
*
|
||||||
public function copy($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->permission_prefix.'add') && permission_exists('domain_select') && count($_SESSION['domains']) > 1) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
* @throws \Random\RandomException
|
||||||
|
*/
|
||||||
|
public function copy($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'add') && permission_exists('domain_select') && count($_SESSION['domains']) > 1) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
if (!$token->validate('/core/domain_settings/domain_settings.php')) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->list_page);
|
header('Location: ' . $this->list_page);
|
||||||
exit;
|
exit;
|
||||||
}
|
|
||||||
|
|
||||||
//copy the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get checked records
|
|
||||||
foreach($records as $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = $record['uuid'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
|
|
||||||
$settings_copied = 0;
|
|
||||||
|
|
||||||
//to different domain
|
|
||||||
if (is_uuid($this->domain_uuid_target)) {
|
|
||||||
|
|
||||||
foreach ($uuids as $uuid) {
|
|
||||||
|
|
||||||
//get domain setting from db
|
|
||||||
$sql = "select * from v_domain_settings ";
|
|
||||||
$sql .= "where domain_setting_uuid = :domain_setting_uuid ";
|
|
||||||
$parameters['domain_setting_uuid'] = $uuid;
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
if (is_array($row) && sizeof($row) != 0) {
|
|
||||||
$domain_setting_category = $row["domain_setting_category"];
|
|
||||||
$domain_setting_subcategory = $row["domain_setting_subcategory"];
|
|
||||||
$domain_setting_name = $row["domain_setting_name"];
|
|
||||||
$domain_setting_value = $row["domain_setting_value"];
|
|
||||||
$domain_setting_order = $row["domain_setting_order"];
|
|
||||||
$domain_setting_enabled = $row["domain_setting_enabled"];
|
|
||||||
$domain_setting_description = $row["domain_setting_description"];
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $row);
|
|
||||||
|
|
||||||
//set a random password for http_auth_password
|
|
||||||
if ($domain_setting_subcategory == "http_auth_password") {
|
|
||||||
$domain_setting_value = generate_password();
|
|
||||||
}
|
|
||||||
|
|
||||||
//target is different domain, check if exists
|
|
||||||
if ($this->domain_uuid_target != $this->domain_uuid) {
|
|
||||||
$sql = "select domain_setting_uuid from v_domain_settings ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and domain_setting_category = :domain_setting_category ";
|
|
||||||
$sql .= "and domain_setting_subcategory = :domain_setting_subcategory ";
|
|
||||||
$sql .= "and domain_setting_name = :domain_setting_name ";
|
|
||||||
$sql .= "and domain_setting_name <> 'array' ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid_target;
|
|
||||||
$parameters['domain_setting_category'] = $domain_setting_category;
|
|
||||||
$parameters['domain_setting_subcategory'] = $domain_setting_subcategory;
|
|
||||||
$parameters['domain_setting_name'] = $domain_setting_name;
|
|
||||||
$target_domain_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
|
||||||
|
|
||||||
$action = is_uuid($target_domain_setting_uuid) ? 'update' : 'add';
|
|
||||||
unset($sql, $parameters);
|
|
||||||
}
|
|
||||||
//target is same domain, duplicate
|
|
||||||
else {
|
|
||||||
$action = 'add';
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix null
|
|
||||||
$domain_setting_order = $domain_setting_order != '' ? $domain_setting_order : null;
|
|
||||||
|
|
||||||
//begin array
|
|
||||||
$array['domain_settings'][0]['domain_uuid'] = $this->domain_uuid_target;
|
|
||||||
$array['domain_settings'][0]['domain_setting_category'] = $domain_setting_category;
|
|
||||||
$array['domain_settings'][0]['domain_setting_subcategory'] = $domain_setting_subcategory;
|
|
||||||
$array['domain_settings'][0]['domain_setting_name'] = $domain_setting_name;
|
|
||||||
$array['domain_settings'][0]['domain_setting_value'] = $domain_setting_value;
|
|
||||||
$array['domain_settings'][0]['domain_setting_order'] = $domain_setting_order;
|
|
||||||
$array['domain_settings'][0]['domain_setting_enabled'] = $domain_setting_enabled ?: 0;
|
|
||||||
$array['domain_settings'][0]['domain_setting_description'] = $domain_setting_description;
|
|
||||||
|
|
||||||
//insert
|
|
||||||
if ($action == "add" && permission_exists("domain_setting_add")) {
|
|
||||||
$array['domain_settings'][0]['domain_setting_uuid'] = uuid();
|
|
||||||
}
|
|
||||||
//update
|
|
||||||
if ($action == "update" && permission_exists('domain_setting_edit')) {
|
|
||||||
$array['domain_settings'][0]['domain_setting_uuid'] = $target_domain_setting_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//execute
|
|
||||||
if (is_uuid($array['domain_settings'][0]['domain_setting_uuid'])) {
|
|
||||||
$this->database->app_name = 'domain_settings';
|
|
||||||
$this->database->app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
$settings_copied++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //foreach
|
|
||||||
} //if
|
|
||||||
|
|
||||||
//to default settings
|
|
||||||
else if ($this->domain_uuid_target == 'default') {
|
|
||||||
foreach ($uuids as $uuid) {
|
|
||||||
|
|
||||||
//get domain setting from db
|
|
||||||
$sql = "select * from v_domain_settings ";
|
|
||||||
$sql .= "where domain_setting_uuid = :domain_setting_uuid ";
|
|
||||||
$parameters['domain_setting_uuid'] = $uuid;
|
|
||||||
$row = $this->database->select($sql, $parameters, 'row');
|
|
||||||
if (is_array($row) && sizeof($row) != 0) {
|
|
||||||
$domain_setting_category = $row["domain_setting_category"];
|
|
||||||
$domain_setting_subcategory = $row["domain_setting_subcategory"];
|
|
||||||
$domain_setting_name = $row["domain_setting_name"];
|
|
||||||
$domain_setting_value = $row["domain_setting_value"];
|
|
||||||
$domain_setting_order = $row["domain_setting_order"];
|
|
||||||
$domain_setting_enabled = $row["domain_setting_enabled"];
|
|
||||||
$domain_setting_description = $row["domain_setting_description"];
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $row);
|
|
||||||
|
|
||||||
//set a random password for http_auth_password
|
|
||||||
if ($domain_setting_subcategory == "http_auth_password") {
|
|
||||||
$domain_setting_value = generate_password();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if exists
|
|
||||||
$sql = "select default_setting_uuid from v_default_settings ";
|
|
||||||
$sql .= "where default_setting_category = :default_setting_category ";
|
|
||||||
$sql .= "and default_setting_subcategory = :default_setting_subcategory ";
|
|
||||||
$sql .= "and default_setting_name = :default_setting_name ";
|
|
||||||
$sql .= "and default_setting_name <> 'array' ";
|
|
||||||
$parameters['default_setting_category'] = $domain_setting_category;
|
|
||||||
$parameters['default_setting_subcategory'] = $domain_setting_subcategory;
|
|
||||||
$parameters['default_setting_name'] = $domain_setting_name;
|
|
||||||
$target_default_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
|
||||||
|
|
||||||
$action = is_uuid($target_default_setting_uuid) ? 'update' : 'add';
|
|
||||||
unset($sql, $parameters);
|
|
||||||
|
|
||||||
// fix null
|
|
||||||
$domain_setting_order = $domain_setting_order != '' ? $domain_setting_order : null;
|
|
||||||
|
|
||||||
//begin array
|
|
||||||
$array['default_settings'][0]['default_setting_category'] = $domain_setting_category;
|
|
||||||
$array['default_settings'][0]['default_setting_subcategory'] = $domain_setting_subcategory;
|
|
||||||
$array['default_settings'][0]['default_setting_name'] = $domain_setting_name;
|
|
||||||
$array['default_settings'][0]['default_setting_value'] = $domain_setting_value;
|
|
||||||
$array['default_settings'][0]['default_setting_order'] = $domain_setting_order;
|
|
||||||
$array['default_settings'][0]['default_setting_enabled'] = $domain_setting_enabled;
|
|
||||||
$array['default_settings'][0]['default_setting_description'] = $domain_setting_description;
|
|
||||||
|
|
||||||
//insert
|
|
||||||
if ($action == "add" && permission_exists("default_setting_add")) {
|
|
||||||
$array['default_settings'][0]['default_setting_uuid'] = uuid();
|
|
||||||
}
|
|
||||||
//update
|
|
||||||
if ($action == "update" && permission_exists('default_setting_edit')) {
|
|
||||||
$array['default_settings'][0]['default_setting_uuid'] = $target_default_setting_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//execute
|
|
||||||
if (is_uuid($array['default_settings'][0]['default_setting_uuid'])) {
|
|
||||||
$this->database->app_name = 'domain_settings';
|
|
||||||
$this->database->app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
$settings_copied++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //foreach
|
|
||||||
} //if
|
|
||||||
|
|
||||||
// set message
|
|
||||||
message::add($text['message-copy'].": ".escape($settings_copied));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($records);
|
|
||||||
}
|
}
|
||||||
} //method
|
|
||||||
|
|
||||||
} //class
|
//copy the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get checked records
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = $record['uuid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
|
||||||
|
$settings_copied = 0;
|
||||||
|
|
||||||
|
//to different domain
|
||||||
|
if (is_uuid($this->domain_uuid_target)) {
|
||||||
|
|
||||||
|
foreach ($uuids as $uuid) {
|
||||||
|
|
||||||
|
//get domain setting from db
|
||||||
|
$sql = "select * from v_domain_settings ";
|
||||||
|
$sql .= "where domain_setting_uuid = :domain_setting_uuid ";
|
||||||
|
$parameters['domain_setting_uuid'] = $uuid;
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
if (is_array($row) && sizeof($row) != 0) {
|
||||||
|
$domain_setting_category = $row["domain_setting_category"];
|
||||||
|
$domain_setting_subcategory = $row["domain_setting_subcategory"];
|
||||||
|
$domain_setting_name = $row["domain_setting_name"];
|
||||||
|
$domain_setting_value = $row["domain_setting_value"];
|
||||||
|
$domain_setting_order = $row["domain_setting_order"];
|
||||||
|
$domain_setting_enabled = $row["domain_setting_enabled"];
|
||||||
|
$domain_setting_description = $row["domain_setting_description"];
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $row);
|
||||||
|
|
||||||
|
//set a random password for http_auth_password
|
||||||
|
if ($domain_setting_subcategory == "http_auth_password") {
|
||||||
|
$domain_setting_value = generate_password();
|
||||||
|
}
|
||||||
|
|
||||||
|
//target is different domain, check if exists
|
||||||
|
if ($this->domain_uuid_target != $this->domain_uuid) {
|
||||||
|
$sql = "select domain_setting_uuid from v_domain_settings ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and domain_setting_category = :domain_setting_category ";
|
||||||
|
$sql .= "and domain_setting_subcategory = :domain_setting_subcategory ";
|
||||||
|
$sql .= "and domain_setting_name = :domain_setting_name ";
|
||||||
|
$sql .= "and domain_setting_name <> 'array' ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid_target;
|
||||||
|
$parameters['domain_setting_category'] = $domain_setting_category;
|
||||||
|
$parameters['domain_setting_subcategory'] = $domain_setting_subcategory;
|
||||||
|
$parameters['domain_setting_name'] = $domain_setting_name;
|
||||||
|
$target_domain_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
||||||
|
|
||||||
|
$action = is_uuid($target_domain_setting_uuid) ? 'update' : 'add';
|
||||||
|
unset($sql, $parameters);
|
||||||
|
} //target is same domain, duplicate
|
||||||
|
else {
|
||||||
|
$action = 'add';
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix null
|
||||||
|
$domain_setting_order = $domain_setting_order != '' ? $domain_setting_order : null;
|
||||||
|
|
||||||
|
//begin array
|
||||||
|
$array['domain_settings'][0]['domain_uuid'] = $this->domain_uuid_target;
|
||||||
|
$array['domain_settings'][0]['domain_setting_category'] = $domain_setting_category;
|
||||||
|
$array['domain_settings'][0]['domain_setting_subcategory'] = $domain_setting_subcategory;
|
||||||
|
$array['domain_settings'][0]['domain_setting_name'] = $domain_setting_name;
|
||||||
|
$array['domain_settings'][0]['domain_setting_value'] = $domain_setting_value;
|
||||||
|
$array['domain_settings'][0]['domain_setting_order'] = $domain_setting_order;
|
||||||
|
$array['domain_settings'][0]['domain_setting_enabled'] = $domain_setting_enabled ?: 0;
|
||||||
|
$array['domain_settings'][0]['domain_setting_description'] = $domain_setting_description;
|
||||||
|
|
||||||
|
//insert
|
||||||
|
if ($action == "add" && permission_exists("domain_setting_add")) {
|
||||||
|
$array['domain_settings'][0]['domain_setting_uuid'] = uuid();
|
||||||
|
}
|
||||||
|
//update
|
||||||
|
if ($action == "update" && permission_exists('domain_setting_edit')) {
|
||||||
|
$array['domain_settings'][0]['domain_setting_uuid'] = $target_domain_setting_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (is_uuid($array['domain_settings'][0]['domain_setting_uuid'])) {
|
||||||
|
$this->database->app_name = 'domain_settings';
|
||||||
|
$this->database->app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
$settings_copied++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //foreach
|
||||||
|
} //if
|
||||||
|
|
||||||
|
//to default settings
|
||||||
|
elseif ($this->domain_uuid_target == 'default') {
|
||||||
|
foreach ($uuids as $uuid) {
|
||||||
|
|
||||||
|
//get domain setting from db
|
||||||
|
$sql = "select * from v_domain_settings ";
|
||||||
|
$sql .= "where domain_setting_uuid = :domain_setting_uuid ";
|
||||||
|
$parameters['domain_setting_uuid'] = $uuid;
|
||||||
|
$row = $this->database->select($sql, $parameters, 'row');
|
||||||
|
if (is_array($row) && sizeof($row) != 0) {
|
||||||
|
$domain_setting_category = $row["domain_setting_category"];
|
||||||
|
$domain_setting_subcategory = $row["domain_setting_subcategory"];
|
||||||
|
$domain_setting_name = $row["domain_setting_name"];
|
||||||
|
$domain_setting_value = $row["domain_setting_value"];
|
||||||
|
$domain_setting_order = $row["domain_setting_order"];
|
||||||
|
$domain_setting_enabled = $row["domain_setting_enabled"];
|
||||||
|
$domain_setting_description = $row["domain_setting_description"];
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $row);
|
||||||
|
|
||||||
|
//set a random password for http_auth_password
|
||||||
|
if ($domain_setting_subcategory == "http_auth_password") {
|
||||||
|
$domain_setting_value = generate_password();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if exists
|
||||||
|
$sql = "select default_setting_uuid from v_default_settings ";
|
||||||
|
$sql .= "where default_setting_category = :default_setting_category ";
|
||||||
|
$sql .= "and default_setting_subcategory = :default_setting_subcategory ";
|
||||||
|
$sql .= "and default_setting_name = :default_setting_name ";
|
||||||
|
$sql .= "and default_setting_name <> 'array' ";
|
||||||
|
$parameters['default_setting_category'] = $domain_setting_category;
|
||||||
|
$parameters['default_setting_subcategory'] = $domain_setting_subcategory;
|
||||||
|
$parameters['default_setting_name'] = $domain_setting_name;
|
||||||
|
$target_default_setting_uuid = $this->database->select($sql, $parameters, 'column');
|
||||||
|
|
||||||
|
$action = is_uuid($target_default_setting_uuid) ? 'update' : 'add';
|
||||||
|
unset($sql, $parameters);
|
||||||
|
|
||||||
|
// fix null
|
||||||
|
$domain_setting_order = $domain_setting_order != '' ? $domain_setting_order : null;
|
||||||
|
|
||||||
|
//begin array
|
||||||
|
$array['default_settings'][0]['default_setting_category'] = $domain_setting_category;
|
||||||
|
$array['default_settings'][0]['default_setting_subcategory'] = $domain_setting_subcategory;
|
||||||
|
$array['default_settings'][0]['default_setting_name'] = $domain_setting_name;
|
||||||
|
$array['default_settings'][0]['default_setting_value'] = $domain_setting_value;
|
||||||
|
$array['default_settings'][0]['default_setting_order'] = $domain_setting_order;
|
||||||
|
$array['default_settings'][0]['default_setting_enabled'] = $domain_setting_enabled;
|
||||||
|
$array['default_settings'][0]['default_setting_description'] = $domain_setting_description;
|
||||||
|
|
||||||
|
//insert
|
||||||
|
if ($action == "add" && permission_exists("default_setting_add")) {
|
||||||
|
$array['default_settings'][0]['default_setting_uuid'] = uuid();
|
||||||
|
}
|
||||||
|
//update
|
||||||
|
if ($action == "update" && permission_exists('default_setting_edit')) {
|
||||||
|
$array['default_settings'][0]['default_setting_uuid'] = $target_default_setting_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (is_uuid($array['default_settings'][0]['default_setting_uuid'])) {
|
||||||
|
$this->database->app_name = 'domain_settings';
|
||||||
|
$this->database->app_uuid = 'b31e723a-bf70-670c-a49b-470d2a232f71';
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
$settings_copied++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //foreach
|
||||||
|
} //if
|
||||||
|
|
||||||
|
// set message
|
||||||
|
message::add($text['message-copy'] . ": " . escape($settings_copied));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
} //method
|
||||||
|
|
||||||
|
} //class
|
||||||
|
|||||||
@@ -25,244 +25,270 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the email templates class
|
//define the email templates class
|
||||||
class email_templates {
|
class email_templates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'email_templates';
|
const app_name = 'email_templates';
|
||||||
const app_uuid = '8173e738-2523-46d5-8943-13883befd2fd';
|
const app_uuid = '8173e738-2523-46d5-8943-13883befd2fd';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
private $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $permission_prefix;
|
private $permission_prefix;
|
||||||
private $list_page;
|
private $list_page;
|
||||||
private $table;
|
private $table;
|
||||||
private $uuid_prefix;
|
private $uuid_prefix;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set domain and user UUIDs
|
*
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//set objects
|
//set objects
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
|
||||||
//assign private variables
|
|
||||||
$this->permission_prefix = 'email_template_';
|
|
||||||
$this->list_page = 'email_templates.php';
|
|
||||||
$this->table = 'email_templates';
|
|
||||||
$this->uuid_prefix = 'email_template_';
|
|
||||||
$this->toggle_field = 'template_enabled';
|
|
||||||
$this->toggle_values = ['true','false'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* delete records
|
|
||||||
*/
|
|
||||||
public function delete($records) {
|
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete multiple records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//build the delete array
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* toggle records
|
|
||||||
*/
|
|
||||||
public function toggle($records) {
|
|
||||||
if (permission_exists($this->permission_prefix.'edit')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//toggle the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get current toggle state
|
|
||||||
foreach($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
|
|
||||||
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
|
||||||
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$rows = $this->database->select($sql, $parameters, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$states[$row['uuid']] = $row['toggle'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build update array
|
|
||||||
$x = 0;
|
|
||||||
foreach($states as $uuid => $state) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
|
|
||||||
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-toggle']);
|
|
||||||
}
|
|
||||||
unset($records, $states);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* copy records
|
|
||||||
*/
|
|
||||||
public function copy($records) {
|
|
||||||
if (permission_exists($this->permission_prefix.'add')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get checked records
|
|
||||||
foreach($records as $x => $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//create insert array from existing data
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select * from v_".$this->table." ";
|
|
||||||
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
|
||||||
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$rows = $this->database->select($sql, $parameters, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $x => $row) {
|
|
||||||
|
|
||||||
//convert boolean values to a string
|
|
||||||
foreach($row as $key => $value) {
|
|
||||||
if (gettype($value) == 'boolean') {
|
|
||||||
$value = $value ? 'true' : 'false';
|
|
||||||
$row[$key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy data
|
|
||||||
$array[$this->table][$x] = $row;
|
|
||||||
|
|
||||||
//overwrite
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = uuid();
|
|
||||||
$array[$this->table][$x]['template_description'] = trim($row['template_description'].' ('.$text['label-copy'].')');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes and set the message
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-copy']);
|
|
||||||
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//assign private variables
|
||||||
|
$this->permission_prefix = 'email_template_';
|
||||||
|
$this->list_page = 'email_templates.php';
|
||||||
|
$this->table = 'email_templates';
|
||||||
|
$this->uuid_prefix = 'email_template_';
|
||||||
|
$this->toggle_field = 'template_enabled';
|
||||||
|
$this->toggle_values = ['true', 'false'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes one or multiple records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//build the delete array
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the state of one or more records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function toggle($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'edit')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//toggle the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get current toggle state
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
|
||||||
|
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
||||||
|
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$rows = $this->database->select($sql, $parameters, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$states[$row['uuid']] = $row['toggle'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//build update array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($states as $uuid => $state) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
|
||||||
|
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-toggle']);
|
||||||
|
}
|
||||||
|
unset($records, $states);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies one or more records
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function copy($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'add')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get checked records
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create insert array from existing data
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select * from v_" . $this->table . " ";
|
||||||
|
$sql .= "where (domain_uuid = :domain_uuid or domain_uuid is null) ";
|
||||||
|
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$rows = $this->database->select($sql, $parameters, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $x => $row) {
|
||||||
|
|
||||||
|
//convert boolean values to a string
|
||||||
|
foreach ($row as $key => $value) {
|
||||||
|
if (gettype($value) == 'boolean') {
|
||||||
|
$value = $value ? 'true' : 'false';
|
||||||
|
$row[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy data
|
||||||
|
$array[$this->table][$x] = $row;
|
||||||
|
|
||||||
|
//overwrite
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = uuid();
|
||||||
|
$array[$this->table][$x]['template_description'] = trim($row['template_description'] . ' (' . $text['label-copy'] . ')');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes and set the message
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-copy']);
|
||||||
|
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,193 +25,216 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the permission class
|
//define the permission class
|
||||||
class permission {
|
class permission {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'groups';
|
const app_name = 'groups';
|
||||||
const app_uuid = '2caf27b0-540a-43d5-bb9b-c9871a1e4f84';
|
const app_uuid = '2caf27b0-540a-43d5-bb9b-c9871a1e4f84';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private $database;
|
private $database;
|
||||||
private $database_group_permissions;
|
private $database_group_permissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set objects
|
*
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set objects
|
||||||
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the permissions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes unprotected group permissions from the database.
|
||||||
|
*
|
||||||
|
* This method retrieves a list of apps and their associated permissions, then deletes any permissions that are not protected.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function delete() {
|
||||||
|
|
||||||
|
//get the $apps array from the installed apps from the core and mod directories
|
||||||
|
$config_list = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . "/*/*/app_config.php");
|
||||||
|
$x = 0;
|
||||||
|
foreach ($config_list as $config_path) {
|
||||||
|
include($config_path);
|
||||||
|
$x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete the permissions
|
//initialize array
|
||||||
function delete() {
|
$group_name_array = [];
|
||||||
|
|
||||||
//get the $apps array from the installed apps from the core and mod directories
|
//restore default permissions
|
||||||
$config_list = glob($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH."/*/*/app_config.php");
|
$x = 0;
|
||||||
$x = 0;
|
foreach ($apps as $row) {
|
||||||
foreach ($config_list as $config_path) {
|
if (!empty($row['permissions']) && is_array($row['permissions']) && @sizeof($row['permissions']) != 0) {
|
||||||
include($config_path);
|
foreach ($row['permissions'] as $permission) {
|
||||||
$x++;
|
if (!empty($permission['groups']) && is_array($permission['groups'])) {
|
||||||
|
foreach ($permission['groups'] as $group_name) {
|
||||||
|
if (is_array($group_name_array) || !in_array($group_name, $group_name_array)) {
|
||||||
|
$group_name_array[] = $group_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$group_names = "'" . implode("','", $group_name_array) . "'";
|
||||||
|
|
||||||
//initialize array
|
//delete unprotected permissions
|
||||||
$group_name_array = array();
|
$sql = "delete from v_group_permissions as p ";
|
||||||
|
$sql .= "where group_name in ( ";
|
||||||
|
$sql .= " select group_name ";
|
||||||
|
$sql .= " from v_groups ";
|
||||||
|
$sql .= " where group_protected <> true ";
|
||||||
|
$sql .= " and group_name in (" . $group_names . ") ";
|
||||||
|
$sql .= ")";
|
||||||
|
$sql .= "and (permission_protected <> 'true' or permission_protected is null)";
|
||||||
|
$result = $this->database->select($sql);
|
||||||
|
|
||||||
//restore default permissions
|
//get the group_permissons
|
||||||
$x = 0;
|
/*
|
||||||
foreach ($apps as $row) {
|
$sql = "select * from v_group_permissions as p ";
|
||||||
if (!empty($row['permissions']) && is_array($row['permissions']) && @sizeof($row['permissions']) != 0) {
|
$sql .= "where group_name in ( ";
|
||||||
foreach ($row['permissions'] as $permission) {
|
$sql .= " select group_name ";
|
||||||
if (!empty($permission['groups']) && is_array($permission['groups'])) {
|
$sql .= " from v_groups ";
|
||||||
foreach ($permission['groups'] as $group_name) {
|
$sql .= " where group_protected <> true ";
|
||||||
if (is_array($group_name_array) || !in_array($group_name, $group_name_array)) {
|
$sql .= " and group_name in (".$group_names.") ";
|
||||||
$group_name_array[] = $group_name;
|
$sql .= ");";
|
||||||
|
$group_permissions = $this->database->select($sql, null, 'all');
|
||||||
|
*/
|
||||||
|
|
||||||
|
//delete unprotected group permissions
|
||||||
|
/*
|
||||||
|
if (is_array($group_permissions) && sizeof($group_permissions) > 0) {
|
||||||
|
$x = 0;
|
||||||
|
foreach ($group_permissions as $row) {
|
||||||
|
//build delete array
|
||||||
|
$array['group_permissions'][$x]['group_permission_uuid'] = $row['group_permission_uuid'];
|
||||||
|
$array['group_permissions'][$x]['domain_uuid'] = ($row['domain_uuid'] != '') ? $row['domain_uuid'] : null;
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//grant temporary permissions
|
||||||
|
$p = permissions::new();
|
||||||
|
$p->add('group_permission_delete', 'temp');
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
//revoke temporary permissions
|
||||||
|
$p->delete('group_permission_delete', 'temp');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//restore the permissions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore default group and permission settings.
|
||||||
|
*
|
||||||
|
* This method restores the default groups and permissions by deleting existing unprotected permissions,
|
||||||
|
* adding default groups if none exist, retrieving remaining permissions from installed apps,
|
||||||
|
* and inserting default permissions into the database.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @see permission::delete()
|
||||||
|
*/
|
||||||
|
function restore() {
|
||||||
|
|
||||||
|
//if the are no groups add the default groups
|
||||||
|
$sql = "select * from v_groups ";
|
||||||
|
$sql .= "where domain_uuid is null ";
|
||||||
|
$groups = $this->database->select($sql, null, 'all');
|
||||||
|
|
||||||
|
//delete the group permissions
|
||||||
|
$this->delete();
|
||||||
|
|
||||||
|
//get the remaining group permissions
|
||||||
|
$sql = "select permission_name, group_name from v_group_permissions ";
|
||||||
|
$this->database_group_permissions = $this->database->select($sql, null, 'all');
|
||||||
|
|
||||||
|
//get the $apps array from the installed apps from the core and mod directories
|
||||||
|
$config_list = glob($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH . "/*/*/app_config.php");
|
||||||
|
$x = 0;
|
||||||
|
foreach ($config_list as $config_path) {
|
||||||
|
include($config_path);
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//restore default permissions
|
||||||
|
$x = 0;
|
||||||
|
foreach ($apps as $row) {
|
||||||
|
if (!empty($row['permissions']) && is_array($row['permissions']) && @sizeof($row['permissions']) != 0) {
|
||||||
|
foreach ($row['permissions'] as $permission) {
|
||||||
|
//set the variables
|
||||||
|
if (!empty($permission['groups'])) {
|
||||||
|
foreach ($permission['groups'] as $group_name) {
|
||||||
|
//check group protection
|
||||||
|
$group_uuid = null;
|
||||||
|
$group_protected = false;
|
||||||
|
if (is_array($groups)) {
|
||||||
|
foreach ($groups as $group) {
|
||||||
|
if ($group['group_name'] == $group_name) {
|
||||||
|
$group_uuid = $group['group_uuid'];
|
||||||
|
$group_protected = $group['group_protected'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$group_protected) {
|
||||||
|
// check if the item is not currently in the database
|
||||||
|
$exists = false;
|
||||||
|
foreach ($this->database_group_permissions as $i => $group_permission) {
|
||||||
|
if ($group_permission['permission_name'] == $permission['name']) {
|
||||||
|
if ($group_permission['group_name'] == $group_name) {
|
||||||
|
$exists = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!$exists) {
|
||||||
|
//build default permissions insert array
|
||||||
|
$array['group_permissions'][$x]['group_permission_uuid'] = uuid();
|
||||||
|
$array['group_permissions'][$x]['permission_name'] = $permission['name'];
|
||||||
|
$array['group_permissions'][$x]['permission_protected'] = 'false';
|
||||||
|
$array['group_permissions'][$x]['permission_assigned'] = 'true';
|
||||||
|
$array['group_permissions'][$x]['group_name'] = $group_name;
|
||||||
|
$array['group_permissions'][$x]['group_uuid'] = $group_uuid;
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$group_names = "'".implode("','", $group_name_array)."'";
|
}
|
||||||
|
|
||||||
//delete unprotected permissions
|
|
||||||
$sql = "delete from v_group_permissions as p ";
|
|
||||||
$sql .= "where group_name in ( ";
|
|
||||||
$sql .= " select group_name ";
|
|
||||||
$sql .= " from v_groups ";
|
|
||||||
$sql .= " where group_protected <> true ";
|
|
||||||
$sql .= " and group_name in (".$group_names.") ";
|
|
||||||
$sql .= ")";
|
|
||||||
$sql .= "and (permission_protected <> 'true' or permission_protected is null)";
|
|
||||||
$result = $this->database->select($sql);
|
|
||||||
|
|
||||||
//get the group_permissons
|
|
||||||
/*
|
|
||||||
$sql = "select * from v_group_permissions as p ";
|
|
||||||
$sql .= "where group_name in ( ";
|
|
||||||
$sql .= " select group_name ";
|
|
||||||
$sql .= " from v_groups ";
|
|
||||||
$sql .= " where group_protected <> true ";
|
|
||||||
$sql .= " and group_name in (".$group_names.") ";
|
|
||||||
$sql .= ");";
|
|
||||||
$group_permissions = $this->database->select($sql, null, 'all');
|
|
||||||
*/
|
|
||||||
|
|
||||||
//delete unprotected group permissions
|
|
||||||
/*
|
|
||||||
if (is_array($group_permissions) && sizeof($group_permissions) > 0) {
|
|
||||||
$x = 0;
|
|
||||||
foreach ($group_permissions as $row) {
|
|
||||||
//build delete array
|
|
||||||
$array['group_permissions'][$x]['group_permission_uuid'] = $row['group_permission_uuid'];
|
|
||||||
$array['group_permissions'][$x]['domain_uuid'] = ($row['domain_uuid'] != '') ? $row['domain_uuid'] : null;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//grant temporary permissions
|
|
||||||
$p = permissions::new();
|
|
||||||
$p->add('group_permission_delete', 'temp');
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
//revoke temporary permissions
|
|
||||||
$p->delete('group_permission_delete', 'temp');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//restore the permissions
|
if (is_array($array) && @sizeof($array)) {
|
||||||
function restore() {
|
//grant temporary permissions
|
||||||
|
$p = permissions::new();
|
||||||
|
$p->add('group_permission_add', 'temp');
|
||||||
|
|
||||||
//if the are no groups add the default groups
|
//execute insert
|
||||||
$sql = "select * from v_groups ";
|
$this->database->save($array);
|
||||||
$sql .= "where domain_uuid is null ";
|
unset($array);
|
||||||
$groups = $this->database->select($sql, null, 'all');
|
|
||||||
|
|
||||||
//delete the group permissions
|
//revoke temporary permissions
|
||||||
$this->delete();
|
$p->delete('group_permission_add', 'temp');
|
||||||
|
}
|
||||||
//get the remaining group permissions
|
|
||||||
$sql = "select permission_name, group_name from v_group_permissions ";
|
|
||||||
$this->database_group_permissions = $this->database->select($sql, null, 'all');
|
|
||||||
|
|
||||||
//get the $apps array from the installed apps from the core and mod directories
|
|
||||||
$config_list = glob($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH."/*/*/app_config.php");
|
|
||||||
$x = 0;
|
|
||||||
foreach ($config_list as $config_path) {
|
|
||||||
include($config_path);
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//restore default permissions
|
|
||||||
$x = 0;
|
|
||||||
foreach ($apps as $row) {
|
|
||||||
if (!empty($row['permissions']) && is_array($row['permissions']) && @sizeof($row['permissions']) != 0) {
|
|
||||||
foreach ($row['permissions'] as $permission) {
|
|
||||||
//set the variables
|
|
||||||
if (!empty($permission['groups'])) {
|
|
||||||
foreach ($permission['groups'] as $group_name) {
|
|
||||||
//check group protection
|
|
||||||
$group_uuid = null;
|
|
||||||
$group_protected = false;
|
|
||||||
if (is_array($groups)) {
|
|
||||||
foreach ($groups as $group) {
|
|
||||||
if ($group['group_name'] == $group_name) {
|
|
||||||
$group_uuid = $group['group_uuid'];
|
|
||||||
$group_protected = $group['group_protected'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$group_protected) {
|
|
||||||
// check if the item is not currently in the database
|
|
||||||
$exists = false;
|
|
||||||
foreach ($this->database_group_permissions as $i => $group_permission) {
|
|
||||||
if ($group_permission['permission_name'] == $permission['name']) {
|
|
||||||
if ($group_permission['group_name'] == $group_name) {
|
|
||||||
$exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$exists) {
|
|
||||||
//build default permissions insert array
|
|
||||||
$array['group_permissions'][$x]['group_permission_uuid'] = uuid();
|
|
||||||
$array['group_permissions'][$x]['permission_name'] = $permission['name'];
|
|
||||||
$array['group_permissions'][$x]['permission_protected'] = 'false';
|
|
||||||
$array['group_permissions'][$x]['permission_assigned'] = 'true';
|
|
||||||
$array['group_permissions'][$x]['group_name'] = $group_name;
|
|
||||||
$array['group_permissions'][$x]['group_uuid'] = $group_uuid;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($array) && @sizeof($array)) {
|
|
||||||
//grant temporary permissions
|
|
||||||
$p = permissions::new();
|
|
||||||
$p->add('group_permission_add', 'temp');
|
|
||||||
|
|
||||||
//execute insert
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//revoke temporary permissions
|
|
||||||
$p->delete('group_permission_add', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -1,174 +1,174 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class install {
|
class install {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'install';
|
const app_name = 'install';
|
||||||
const app_uuid = '75507e6e-891e-11e5-af63-feff819cdc9f';
|
const app_uuid = '75507e6e-891e-11e5-af63-feff819cdc9f';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare public variables
|
* declare public variables
|
||||||
*/
|
*/
|
||||||
public $message;
|
public $message;
|
||||||
public $database_host;
|
public $database_host;
|
||||||
public $database_port;
|
public $database_port;
|
||||||
public $database_name;
|
public $database_name;
|
||||||
public $database_username;
|
public $database_username;
|
||||||
public $database_password;
|
public $database_password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* called when the object is created
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Used to create the config.conf file.</p>
|
* Used to create the config.conf file using paths based on the operating system.
|
||||||
* <p>BSD /usr/local/etc/fusionpbx</p>
|
*
|
||||||
* <p>Linux /etc/fusionpbx</p>
|
* @return boolean true if the configuration file is successfully created, false otherwise.
|
||||||
* @return boolean
|
*/
|
||||||
*/
|
public function config() {
|
||||||
public function config() {
|
|
||||||
|
|
||||||
//set the default config file location
|
//set the default config file location
|
||||||
$os = strtoupper(substr(PHP_OS, 0, 3));
|
$os = strtoupper(substr(PHP_OS, 0, 3));
|
||||||
switch ($os) {
|
switch ($os) {
|
||||||
case "FRE":
|
case "FRE":
|
||||||
case "OPE":
|
case "OPE":
|
||||||
case "NET":
|
case "NET":
|
||||||
case "BSD":
|
case "BSD":
|
||||||
$config_path = '/usr/local/etc/fusionpbx';
|
$config_path = '/usr/local/etc/fusionpbx';
|
||||||
$config_file = $config_path.'/config.conf';
|
$config_file = $config_path . '/config.conf';
|
||||||
$document_root = '/usr/local/www/fusionpbx';
|
$document_root = '/usr/local/www/fusionpbx';
|
||||||
|
|
||||||
$conf_dir = '/usr/local/etc/freeswitch';
|
$conf_dir = '/usr/local/etc/freeswitch';
|
||||||
$sounds_dir = '/usr/share/freeswitch/sounds';
|
$sounds_dir = '/usr/share/freeswitch/sounds';
|
||||||
$database_dir = '/var/lib/freeswitch/db';
|
$database_dir = '/var/lib/freeswitch/db';
|
||||||
$recordings_dir = '/var/lib/freeswitch/recordings';
|
$recordings_dir = '/var/lib/freeswitch/recordings';
|
||||||
$storage_dir = '/var/lib/freeswitch/storage';
|
$storage_dir = '/var/lib/freeswitch/storage';
|
||||||
$voicemail_dir = '/var/lib/freeswitch/storage/voicemail';
|
$voicemail_dir = '/var/lib/freeswitch/storage/voicemail';
|
||||||
$scripts_dir = '/usr/share/freeswitch/scripts';
|
$scripts_dir = '/usr/share/freeswitch/scripts';
|
||||||
$php_dir = PHP_BINDIR;
|
$php_dir = PHP_BINDIR;
|
||||||
$cache_location = '/var/cache/fusionpbx';
|
$cache_location = '/var/cache/fusionpbx';
|
||||||
break;
|
break;
|
||||||
case "LIN":
|
case "LIN":
|
||||||
$config_path = '/etc/fusionpbx/';
|
$config_path = '/etc/fusionpbx/';
|
||||||
$config_file = $config_path.'/config.conf';
|
$config_file = $config_path . '/config.conf';
|
||||||
$document_root = '/var/www/fusionpbx';
|
$document_root = '/var/www/fusionpbx';
|
||||||
|
|
||||||
$conf_dir = '/etc/freeswitch';
|
$conf_dir = '/etc/freeswitch';
|
||||||
$sounds_dir = '/usr/share/freeswitch/sounds';
|
$sounds_dir = '/usr/share/freeswitch/sounds';
|
||||||
$database_dir = '/var/lib/freeswitch/db';
|
$database_dir = '/var/lib/freeswitch/db';
|
||||||
$recordings_dir = '/var/lib/freeswitch/recordings';
|
$recordings_dir = '/var/lib/freeswitch/recordings';
|
||||||
$storage_dir = '/var/lib/freeswitch/storage';
|
$storage_dir = '/var/lib/freeswitch/storage';
|
||||||
$voicemail_dir = '/var/lib/freeswitch/storage/voicemail';
|
$voicemail_dir = '/var/lib/freeswitch/storage/voicemail';
|
||||||
$scripts_dir = '/usr/share/freeswitch/scripts';
|
$scripts_dir = '/usr/share/freeswitch/scripts';
|
||||||
$php_dir = PHP_BINDIR;
|
$php_dir = PHP_BINDIR;
|
||||||
$cache_location = '/var/cache/fusionpbx';
|
$cache_location = '/var/cache/fusionpbx';
|
||||||
break;
|
break;
|
||||||
case "WIN":
|
case "WIN":
|
||||||
$system_drive = getenv('SystemDrive');
|
$system_drive = getenv('SystemDrive');
|
||||||
$config_path = $system_drive . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx' ;
|
$config_path = $system_drive . DIRECTORY_SEPARATOR . 'ProgramData' . DIRECTORY_SEPARATOR . 'fusionpbx';
|
||||||
$config_file = $config_path.DIRECTORY_SEPARATOR.'config.conf';
|
$config_file = $config_path . DIRECTORY_SEPARATOR . 'config.conf';
|
||||||
$document_root = $_SERVER["DOCUMENT_ROOT"];
|
$document_root = $_SERVER["DOCUMENT_ROOT"];
|
||||||
|
|
||||||
$conf_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'conf';
|
$conf_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'conf';
|
||||||
$sounds_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'sounds';
|
$sounds_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'sounds';
|
||||||
$database_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'db';
|
$database_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'db';
|
||||||
$recordings_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'recordings';
|
$recordings_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'recordings';
|
||||||
$storage_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'storage';
|
$storage_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'storage';
|
||||||
$voicemail_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'voicemail';
|
$voicemail_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'voicemail';
|
||||||
$scripts_dir = $_SERVER['ProgramFiles'].DIRECTORY_SEPARATOR.'freeswitch'.DIRECTORY_SEPARATOR.'scripts';
|
$scripts_dir = $_SERVER['ProgramFiles'] . DIRECTORY_SEPARATOR . 'freeswitch' . DIRECTORY_SEPARATOR . 'scripts';
|
||||||
$php_dir = dirname(PHP_BINARY);
|
$php_dir = dirname(PHP_BINARY);
|
||||||
$cache_location = dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'fusionpbx';
|
$cache_location = dirname($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'fusionpbx';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//end the script if the config path is not set
|
//end the script if the config path is not set
|
||||||
if (!isset($config_path)) {
|
if (!isset($config_path)) {
|
||||||
$this->message = "Config file path not found\n";
|
$this->message = "Config file path not found\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//config directory is not writable
|
//config directory is not writable
|
||||||
if (!is_writable($config_path)) {
|
if (!is_writable($config_path)) {
|
||||||
$this->message = "Check permissions ".$config_path." must be writable.\n";
|
$this->message = "Check permissions " . $config_path . " must be writable.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//make the config directory
|
//make the config directory
|
||||||
if (isset($config_path)) {
|
if (isset($config_path)) {
|
||||||
system('mkdir -p '.$config_path);
|
system('mkdir -p ' . $config_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//build the config file
|
//build the config file
|
||||||
$conf = "\n";
|
$conf = "\n";
|
||||||
$conf .= "#database system settings\n";
|
$conf .= "#database system settings\n";
|
||||||
$conf .= "database.0.type = pgsql\n";
|
$conf .= "database.0.type = pgsql\n";
|
||||||
$conf .= "database.0.host = ".$this->database_host."\n";
|
$conf .= "database.0.host = " . $this->database_host . "\n";
|
||||||
$conf .= "database.0.port = ".$this->database_port."\n";
|
$conf .= "database.0.port = " . $this->database_port . "\n";
|
||||||
$conf .= "database.0.sslmode = prefer\n";
|
$conf .= "database.0.sslmode = prefer\n";
|
||||||
$conf .= "database.0.name = ".$this->database_name."\n";
|
$conf .= "database.0.name = " . $this->database_name . "\n";
|
||||||
$conf .= "database.0.username = ".$this->database_username."\n";
|
$conf .= "database.0.username = " . $this->database_username . "\n";
|
||||||
$conf .= "database.0.password = ".$this->database_password."\n";
|
$conf .= "database.0.password = " . $this->database_password . "\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#database switch settings\n";
|
$conf .= "#database switch settings\n";
|
||||||
$conf .= "database.1.type = sqlite\n";
|
$conf .= "database.1.type = sqlite\n";
|
||||||
$conf .= "database.1.path = ".$database_dir."\n";
|
$conf .= "database.1.path = " . $database_dir . "\n";
|
||||||
$conf .= "database.1.name = core.db\n";
|
$conf .= "database.1.name = core.db\n";
|
||||||
//$conf .= "database.1.backend.base64 = \n";
|
//$conf .= "database.1.backend.base64 = \n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#general settings\n";
|
$conf .= "#general settings\n";
|
||||||
$conf .= "document.root = ".$document_root."\n";
|
$conf .= "document.root = " . $document_root . "\n";
|
||||||
$conf .= "project.path =\n";
|
$conf .= "project.path =\n";
|
||||||
$conf .= "temp.dir = /tmp\n";
|
$conf .= "temp.dir = /tmp\n";
|
||||||
$conf .= "php.dir = ".$php_dir."\n";
|
$conf .= "php.dir = " . $php_dir . "\n";
|
||||||
$conf .= "php.bin = php\n";
|
$conf .= "php.bin = php\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#session settings\n";
|
$conf .= "#session settings\n";
|
||||||
$conf .= "session.cookie_httponly = true\n";
|
$conf .= "session.cookie_httponly = true\n";
|
||||||
$conf .= "session.cookie_secure = true\n";
|
$conf .= "session.cookie_secure = true\n";
|
||||||
$conf .= "session.cookie_samesite = Lax\n";
|
$conf .= "session.cookie_samesite = Lax\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#cache settings\n";
|
$conf .= "#cache settings\n";
|
||||||
$conf .= "cache.method = file\n";
|
$conf .= "cache.method = file\n";
|
||||||
$conf .= "cache.location = ".$cache_location."\n";
|
$conf .= "cache.location = " . $cache_location . "\n";
|
||||||
$conf .= "cache.settings = true\n";
|
$conf .= "cache.settings = true\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#switch settings\n";
|
$conf .= "#switch settings\n";
|
||||||
$conf .= "switch.conf.dir = ".$conf_dir."\n";
|
$conf .= "switch.conf.dir = " . $conf_dir . "\n";
|
||||||
$conf .= "switch.sounds.dir = ".$sounds_dir."\n";
|
$conf .= "switch.sounds.dir = " . $sounds_dir . "\n";
|
||||||
$conf .= "switch.database.dir = ".$database_dir."\n";
|
$conf .= "switch.database.dir = " . $database_dir . "\n";
|
||||||
$conf .= "switch.recordings.dir = ".$recordings_dir."\n";
|
$conf .= "switch.recordings.dir = " . $recordings_dir . "\n";
|
||||||
$conf .= "switch.storage.dir = ".$storage_dir."\n";
|
$conf .= "switch.storage.dir = " . $storage_dir . "\n";
|
||||||
$conf .= "switch.voicemail.dir = ".$voicemail_dir."\n";
|
$conf .= "switch.voicemail.dir = " . $voicemail_dir . "\n";
|
||||||
$conf .= "switch.scripts.dir = ".$scripts_dir."\n";
|
$conf .= "switch.scripts.dir = " . $scripts_dir . "\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#switch xml handler\n";
|
$conf .= "#switch xml handler\n";
|
||||||
$conf .= "xml_handler.fs_path = false\n";
|
$conf .= "xml_handler.fs_path = false\n";
|
||||||
$conf .= "xml_handler.reg_as_number_alias = false\n";
|
$conf .= "xml_handler.reg_as_number_alias = false\n";
|
||||||
$conf .= "xml_handler.number_as_presence_id = true\n";
|
$conf .= "xml_handler.number_as_presence_id = true\n";
|
||||||
$conf .= "\n";
|
$conf .= "\n";
|
||||||
$conf .= "#error reporting options: user,dev,all\n";
|
$conf .= "#error reporting options: user,dev,all\n";
|
||||||
$conf .= "error.reporting = user\n";
|
$conf .= "error.reporting = user\n";
|
||||||
|
|
||||||
//write the config file
|
//write the config file
|
||||||
$file_handle = fopen($config_file,"w");
|
$file_handle = fopen($config_file, "w");
|
||||||
if(!$file_handle) { return; }
|
if (!$file_handle) {
|
||||||
fwrite($file_handle, $conf);
|
return;
|
||||||
fclose($file_handle);
|
}
|
||||||
|
fwrite($file_handle, $conf);
|
||||||
//if the config.conf file was saved return true
|
fclose($file_handle);
|
||||||
if (file_exists($config_file)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//if the config.conf file was saved return true
|
||||||
|
if (file_exists($config_file)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,6 +86,15 @@
|
|||||||
$tmp_menu_item_order = 0;
|
$tmp_menu_item_order = 0;
|
||||||
|
|
||||||
//add the build db child menu list
|
//add the build db child menu list
|
||||||
|
/**
|
||||||
|
* Builds a child menu list from the database.
|
||||||
|
*
|
||||||
|
* @param object $database The database connection object.
|
||||||
|
* @param int $menu_item_level The current level of the menu item.
|
||||||
|
* @param string $menu_item_uuid The UUID of the parent menu item.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
function build_db_child_menu_list ($database, $menu_item_level, $menu_item_uuid) {
|
function build_db_child_menu_list ($database, $menu_item_level, $menu_item_uuid) {
|
||||||
global $settings, $menu_uuid, $list_row_edit_button;
|
global $settings, $menu_uuid, $list_row_edit_button;
|
||||||
global $tmp_menu_item_order, $v_link_label_edit, $v_link_label_delete;
|
global $tmp_menu_item_order, $v_link_label_edit, $v_link_label_delete;
|
||||||
|
|||||||
@@ -6,14 +6,23 @@
|
|||||||
class software {
|
class software {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* version
|
* Returns the version number as a string.
|
||||||
|
*
|
||||||
|
* @return string The version number in the format 'major.minor.patch'.
|
||||||
*/
|
*/
|
||||||
public static function version() {
|
public static function version() {
|
||||||
return '5.5.3';
|
return '5.5.3';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* numeric_version
|
* Returns the version number as a single integer.
|
||||||
|
*
|
||||||
|
* This function takes the version string, splits it into its components, and combines
|
||||||
|
* them into a single integer value. The integer is calculated by multiplying each component
|
||||||
|
* by an increasing power of 100 (e.g., 10,000 for the major version, 1,000 for the minor version,
|
||||||
|
* and 100 for the patch version).
|
||||||
|
*
|
||||||
|
* @return int The numeric version number.
|
||||||
*/
|
*/
|
||||||
public static function numeric_version() {
|
public static function numeric_version() {
|
||||||
$v = explode('.', software::version());
|
$v = explode('.', software::version());
|
||||||
|
|||||||
@@ -578,9 +578,15 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update file system permissions
|
* Update file permissions for a FusionPBX installation.
|
||||||
|
*
|
||||||
|
* This function updates the permissions of various directories in a FusionPBX installation,
|
||||||
|
* specifically adjusting ownership to match the expected behavior. The changes are only applied
|
||||||
|
* when running as root, and an error message is displayed otherwise.
|
||||||
|
*
|
||||||
|
* @param array $text A translation dictionary containing the label for when not running as root.
|
||||||
|
* @param settings $settings The current application settings instance.
|
||||||
*/
|
*/
|
||||||
function update_file_permissions($text, settings $settings) {
|
function update_file_permissions($text, settings $settings) {
|
||||||
|
|
||||||
@@ -640,7 +646,14 @@ function update_file_permissions($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade services
|
* Upgrade services by copying and enabling them in systemd.
|
||||||
|
*
|
||||||
|
* This function iterates through all service files found in the application's
|
||||||
|
* core and app directories, copies each one to /etc/systemd/system, reloads
|
||||||
|
* the daemon, and enables the service.
|
||||||
|
*
|
||||||
|
* @param string $text Text containing the upgrade description (not used)
|
||||||
|
* @param settings $settings Application settings
|
||||||
*/
|
*/
|
||||||
function upgrade_services($text, settings $settings) {
|
function upgrade_services($text, settings $settings) {
|
||||||
//echo ($text['description-upgrade_services'] ?? "")."\n";
|
//echo ($text['description-upgrade_services'] ?? "")."\n";
|
||||||
@@ -657,7 +670,13 @@ function upgrade_services($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop services
|
* Stops running services by name.
|
||||||
|
*
|
||||||
|
* This function iterates over all service files, extracts the service names,
|
||||||
|
* and stops each service using systemctl.
|
||||||
|
*
|
||||||
|
* @param array $text
|
||||||
|
* @param settings $settings
|
||||||
*/
|
*/
|
||||||
function stop_services($text, settings $settings) {
|
function stop_services($text, settings $settings) {
|
||||||
//echo ($text['description-stop_services'] ?? "")."\n";
|
//echo ($text['description-stop_services'] ?? "")."\n";
|
||||||
@@ -672,7 +691,12 @@ function stop_services($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart services
|
* Restarts all services
|
||||||
|
*
|
||||||
|
* This function restarts all core and app services.
|
||||||
|
*
|
||||||
|
* @param array $text Array containing localized text
|
||||||
|
* @param settings $settings Settings object
|
||||||
*/
|
*/
|
||||||
function restart_services($text, settings $settings) {
|
function restart_services($text, settings $settings) {
|
||||||
//echo ($text['description-restart_services'] ?? "")."\n";
|
//echo ($text['description-restart_services'] ?? "")."\n";
|
||||||
@@ -687,8 +711,11 @@ function restart_services($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the service name
|
* Finds the service name in an INI file from a given file.
|
||||||
* @param string $file
|
*
|
||||||
|
* @param string $file The fully qualified path and file containing the ExecStart command.
|
||||||
|
*
|
||||||
|
* @return string|null The service name if found, otherwise an empty string.
|
||||||
*/
|
*/
|
||||||
function find_service_name(string $file) {
|
function find_service_name(string $file) {
|
||||||
$parsed = parse_ini_file($file);
|
$parsed = parse_ini_file($file);
|
||||||
@@ -703,9 +730,9 @@ function find_service_name(string $file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the current user has root privileges.
|
* Checks whether the current user is the root user or not.
|
||||||
*
|
*
|
||||||
* @return bool Returns true if the current user is the root user, false otherwise.
|
* @return bool True if the current user has root privileges, false otherwise.
|
||||||
*/
|
*/
|
||||||
function is_root(): bool {
|
function is_root(): bool {
|
||||||
return posix_getuid() === 0;
|
return posix_getuid() === 0;
|
||||||
|
|||||||
@@ -52,9 +52,18 @@ $display_type = 'text';
|
|||||||
show_upgrade_menu();
|
show_upgrade_menu();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show upgrade menu
|
* Display the upgrade menu to the user.
|
||||||
* @global type $text
|
*
|
||||||
* @global type $software_name
|
* This function displays a menu with various upgrade options and prompts the
|
||||||
|
* user for input. Based on the user's selection, it performs the corresponding
|
||||||
|
* actions such as upgrading code, schema, auto loader, domains, menu,
|
||||||
|
* permissions, file permissions, services, or restarting services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @global text $text
|
||||||
|
* @global string $software_name
|
||||||
|
* @global settings $settings
|
||||||
*/
|
*/
|
||||||
function show_upgrade_menu() {
|
function show_upgrade_menu() {
|
||||||
//set the global variables
|
//set the global variables
|
||||||
@@ -90,7 +99,7 @@ function show_upgrade_menu() {
|
|||||||
|
|
||||||
//show the command menu
|
//show the command menu
|
||||||
echo "Options:\n";
|
echo "Options:\n";
|
||||||
foreach ($options as list($key, $label, $description)) {
|
foreach ($options as [$key, $label, $description]) {
|
||||||
if (!is_numeric($key)) { echo " "; }
|
if (!is_numeric($key)) { echo " "; }
|
||||||
echo " $key) $label" . ((!empty($option) && $option == 'h') ? " - " . $description : "") . "\n";
|
echo " $key) $label" . ((!empty($option) && $option == 'h') ? " - " . $description : "") . "\n";
|
||||||
}
|
}
|
||||||
@@ -172,8 +181,12 @@ function show_upgrade_menu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild the cache file
|
* Upgrade auto loader by removing temporary files and updating it.
|
||||||
* @global type $text
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @global text $text
|
||||||
|
* @global auto_loader $autoload
|
||||||
*/
|
*/
|
||||||
function do_upgrade_auto_loader() {
|
function do_upgrade_auto_loader() {
|
||||||
global $text, $autoload;
|
global $text, $autoload;
|
||||||
@@ -188,7 +201,10 @@ function do_upgrade_auto_loader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update file system permissions
|
* Update file permissions for the application.
|
||||||
|
*
|
||||||
|
* @param array $text Array of text to display to the user.
|
||||||
|
* @param settings $settings Settings object containing various configuration options.
|
||||||
*/
|
*/
|
||||||
function do_file_permissions($text, settings $settings) {
|
function do_file_permissions($text, settings $settings) {
|
||||||
|
|
||||||
@@ -256,18 +272,33 @@ function do_file_permissions($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the currently logged in user.
|
||||||
|
*
|
||||||
|
* @return string|null The username of the current user, or null if not available
|
||||||
|
*/
|
||||||
function current_user(): ?string {
|
function current_user(): ?string {
|
||||||
return posix_getpwuid(posix_getuid())['name'] ?? null;
|
return posix_getpwuid(posix_getuid())['name'] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//show the upgrade type
|
//show the upgrade type
|
||||||
|
/**
|
||||||
|
* Returns a string containing the current version of the software.
|
||||||
|
*
|
||||||
|
* @return string|null The software version as a string, or null if not available.
|
||||||
|
*/
|
||||||
function show_software_version(): ?string {
|
function show_software_version(): ?string {
|
||||||
return software::version() . "\n";
|
return software::version() . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade the source folder
|
* Upgrade code by pulling the latest changes from version control.
|
||||||
* @return type
|
*
|
||||||
|
* If the pull operation is successful, no result message will be returned.
|
||||||
|
* Otherwise, a result array containing 'result' set to false and a 'message'
|
||||||
|
* detailing the failure will be returned.
|
||||||
|
*
|
||||||
|
* @return null A result array or null on success
|
||||||
*/
|
*/
|
||||||
function do_upgrade_code() {
|
function do_upgrade_code() {
|
||||||
//assume failed
|
//assume failed
|
||||||
@@ -284,8 +315,7 @@ function do_upgrade_code() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade any of the git submodules
|
* Upgrade code submodules by pulling the latest changes from Git repositories.
|
||||||
* @global type $text
|
|
||||||
*/
|
*/
|
||||||
function do_upgrade_code_submodules() {
|
function do_upgrade_code_submodules() {
|
||||||
global $text;
|
global $text;
|
||||||
@@ -312,7 +342,7 @@ function do_upgrade_code_submodules() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute all app_defaults.php files
|
* Perform upgrade on domains.
|
||||||
*/
|
*/
|
||||||
function do_upgrade_domains() {
|
function do_upgrade_domains() {
|
||||||
$domain = new domains;
|
$domain = new domains;
|
||||||
@@ -320,7 +350,11 @@ function do_upgrade_domains() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade schema and/or data_types
|
* Upgrades the database schema to the latest version.
|
||||||
|
*
|
||||||
|
* @param bool $data_types Whether or not to include data types in the upgrade process. Defaults to false.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_upgrade_schema(bool $data_types = false) {
|
function do_upgrade_schema(bool $data_types = false) {
|
||||||
//get the database schema put it into an array then compare and update the database as needed.
|
//get the database schema put it into an array then compare and update the database as needed.
|
||||||
@@ -330,7 +364,9 @@ function do_upgrade_schema(bool $data_types = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore the default menu
|
* Upgrades the menu and restores it to its default state.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_upgrade_menu() {
|
function do_upgrade_menu() {
|
||||||
//define the global variables
|
//define the global variables
|
||||||
@@ -365,7 +401,9 @@ function do_upgrade_menu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore the default permissions
|
* Upgrades database permissions to the latest version.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_upgrade_permissions() {
|
function do_upgrade_permissions() {
|
||||||
//define the global variables
|
//define the global variables
|
||||||
@@ -381,7 +419,10 @@ function do_upgrade_permissions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default upgrade schema and app defaults
|
* Performs default upgrades to the application, including multi-lingual support,
|
||||||
|
* database schema updates, and running of app_defaults.php files.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_upgrade_defaults() {
|
function do_upgrade_defaults() {
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
@@ -406,7 +447,14 @@ function do_upgrade_defaults() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade services
|
* Upgrades the services to the latest version.
|
||||||
|
*
|
||||||
|
* This function upgrades all service files and enables them as systemd services.
|
||||||
|
*
|
||||||
|
* @param string $text An array containing upgrade information. The 'description-upgrade_services' key is used for informational messages.
|
||||||
|
* @param settings $settings Configuration settings object.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_upgrade_services($text, settings $settings) {
|
function do_upgrade_services($text, settings $settings) {
|
||||||
echo ($text['description-upgrade_services'] ?? "")."\n";
|
echo ($text['description-upgrade_services'] ?? "")."\n";
|
||||||
@@ -423,8 +471,11 @@ function do_upgrade_services($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the service name
|
* Retrieves the name of a service from an .ini file.
|
||||||
* @param string $file
|
*
|
||||||
|
* @param string $file Path to the .ini file containing service information.
|
||||||
|
*
|
||||||
|
* @return string The name of the service, or empty string if not found.
|
||||||
*/
|
*/
|
||||||
function get_service_name(string $file) {
|
function get_service_name(string $file) {
|
||||||
$parsed = parse_ini_file($file);
|
$parsed = parse_ini_file($file);
|
||||||
@@ -438,19 +489,22 @@ function get_service_name(string $file) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the current user has root privileges.
|
* Checks if the current user is the root user.
|
||||||
*
|
*
|
||||||
* @return bool Returns true if the current user is the root user, false otherwise.
|
* @return bool True if the user is the root user, false otherwise.
|
||||||
*/
|
*/
|
||||||
function is_root_user(): bool {
|
function is_root_user(): bool {
|
||||||
return posix_getuid() === 0;
|
return posix_getuid() === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart services
|
* Restarts services defined in the system.
|
||||||
|
*
|
||||||
|
* @param array $text An array of strings for service descriptions.
|
||||||
|
* @param object $settings An instance of the settings class, not used in this function.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function do_restart_services($text, settings $settings) {
|
function do_restart_services($text, settings $settings) {
|
||||||
echo ($text['description-restart_services'] ?? "")."\n";
|
echo ($text['description-restart_services'] ?? "")."\n";
|
||||||
@@ -465,8 +519,13 @@ function do_restart_services($text, settings $settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the old config.php file
|
* Loads configuration from a PHP file and writes it to a new configuration file.
|
||||||
* @return type
|
*
|
||||||
|
* If the configuration file does not exist but the config.php file is present,
|
||||||
|
* the settings in the config.php file are used as defaults for the new
|
||||||
|
* configuration file. The config directory is created if it does not exist.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function load_config_php() {
|
function load_config_php() {
|
||||||
//if the config file doesn't exist and the config.php does exist use it to write a new config file
|
//if the config file doesn't exist and the config.php does exist use it to write a new config file
|
||||||
|
|||||||
@@ -27,145 +27,163 @@
|
|||||||
/**
|
/**
|
||||||
* user_logs class
|
* user_logs class
|
||||||
*/
|
*/
|
||||||
class user_logs {
|
class user_logs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'user_logs';
|
const app_name = 'user_logs';
|
||||||
const app_uuid = '582a13cf-7d75-4ea3-b2d9-60914352d76e';
|
const app_uuid = '582a13cf-7d75-4ea3-b2d9-60914352d76e';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
private $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
private $table;
|
private $table;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
private $location;
|
private $location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the class.
|
||||||
|
*
|
||||||
|
* This method initializes the object with setting_array and session data.
|
||||||
|
*
|
||||||
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
/**
|
//set objects
|
||||||
* called when the object is created
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
*/
|
|
||||||
public function __construct(array $setting_array = []) {
|
|
||||||
//set domain and user UUIDs
|
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
|
||||||
|
|
||||||
//set objects
|
//assign the variables
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->name = 'user_log';
|
||||||
|
$this->table = 'user_logs';
|
||||||
|
$this->toggle_field = '';
|
||||||
|
$this->toggle_values = ['true', 'false'];
|
||||||
|
$this->location = 'user_logs.php';
|
||||||
|
}
|
||||||
|
|
||||||
//assign the variables
|
/**
|
||||||
$this->name = 'user_log';
|
* Adds a new log entry to the database.
|
||||||
$this->table = 'user_logs';
|
*
|
||||||
$this->toggle_field = '';
|
* This method creates a database object, prepares an array of data for insertion,
|
||||||
$this->toggle_values = ['true','false'];
|
* saves the data, and removes any temporary permissions created during the process.
|
||||||
$this->location = 'user_logs.php';
|
*
|
||||||
|
* @param array $result An associative array containing user login result details.
|
||||||
|
* @param string $details Optional additional details for failed logins. Defaults to ''.
|
||||||
|
*/
|
||||||
|
public static function add($result, $details = '') {
|
||||||
|
|
||||||
|
//create the database object
|
||||||
|
$database = database::new();
|
||||||
|
|
||||||
|
//prepare the array
|
||||||
|
$array = [];
|
||||||
|
$array['user_logs'][0]["timestamp"] = 'now()';
|
||||||
|
$array['user_logs'][0]["domain_uuid"] = $result['domain_uuid'];
|
||||||
|
$array['user_logs'][0]["user_uuid"] = $result['user_uuid'];
|
||||||
|
$array['user_logs'][0]["username"] = $result['username'];
|
||||||
|
$array['user_logs'][0]["hostname"] = gethostname();
|
||||||
|
$array['user_logs'][0]["type"] = 'login';
|
||||||
|
$array['user_logs'][0]["remote_address"] = $_SERVER['REMOTE_ADDR'];
|
||||||
|
$array['user_logs'][0]["user_agent"] = $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
$array['user_logs'][0]["session_id"] = session_id();
|
||||||
|
$array['user_logs'][0]["type"] = 'login';
|
||||||
|
if ($result["authorized"]) {
|
||||||
|
$array['user_logs'][0]["result"] = 'success';
|
||||||
|
} else {
|
||||||
|
$array['user_logs'][0]["result"] = 'failure';
|
||||||
|
$array['user_logs'][0]["detail"] = $details;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//add the dialplan permission
|
||||||
* add user_logs
|
$p = permissions::new();
|
||||||
*/
|
$p->add("user_log_add", 'temp');
|
||||||
public static function add($result, $details = '') {
|
|
||||||
|
|
||||||
//create the database object
|
//save to the data
|
||||||
$database = database::new();
|
$database->save($array, false);
|
||||||
|
$message = $database->message;
|
||||||
|
|
||||||
//prepare the array
|
//remove the temporary permission
|
||||||
$array = [];
|
$p->delete("user_log_add", 'temp');
|
||||||
$array['user_logs'][0]["timestamp"] = 'now()';
|
}
|
||||||
$array['user_logs'][0]["domain_uuid"] = $result['domain_uuid'];
|
|
||||||
$array['user_logs'][0]["user_uuid"] = $result['user_uuid'];
|
|
||||||
$array['user_logs'][0]["username"] = $result['username'];
|
|
||||||
$array['user_logs'][0]["hostname"] = gethostname();
|
|
||||||
$array['user_logs'][0]["type"] = 'login';
|
|
||||||
$array['user_logs'][0]["remote_address"] = $_SERVER['REMOTE_ADDR'];
|
|
||||||
$array['user_logs'][0]["user_agent"] = $_SERVER['HTTP_USER_AGENT'];
|
|
||||||
$array['user_logs'][0]["session_id"] = session_id();
|
|
||||||
$array['user_logs'][0]["type"] = 'login';
|
|
||||||
if ($result["authorized"]) {
|
|
||||||
$array['user_logs'][0]["result"] = 'success';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$array['user_logs'][0]["result"] = 'failure';
|
|
||||||
$array['user_logs'][0]["detail"] = $details;
|
|
||||||
}
|
|
||||||
|
|
||||||
//add the dialplan permission
|
/**
|
||||||
$p = permissions::new();
|
* Deletes one or multiple records.
|
||||||
$p->add("user_log_add", 'temp');
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->name . '_delete')) {
|
||||||
|
|
||||||
//save to the data
|
//add multi-lingual support
|
||||||
$database->save($array, false);
|
$language = new text;
|
||||||
$message = $database->message;
|
$text = $language->get();
|
||||||
|
|
||||||
//remove the temporary permission
|
//validate the token
|
||||||
$p->delete("user_log_add", 'temp');
|
$token = new token;
|
||||||
}
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->location);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
//delete multiple records
|
||||||
* delete rows from the database
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
*/
|
//build the delete array
|
||||||
public function delete($records) {
|
$x = 0;
|
||||||
if (permission_exists($this->name.'_delete')) {
|
foreach ($records as $record) {
|
||||||
|
//add to the array
|
||||||
//add multi-lingual support
|
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
$language = new text;
|
$array[$this->table][$x][$this->name . '_uuid'] = $record['uuid'];
|
||||||
$text = $language->get();
|
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->location);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//increment the id
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
$x++;
|
||||||
//build the delete array
|
}
|
||||||
$x = 0;
|
|
||||||
foreach ($records as $record) {
|
|
||||||
//add to the array
|
|
||||||
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
|
|
||||||
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//increment the id
|
//delete the checked rows
|
||||||
$x++;
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
}
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
//delete the checked rows
|
//set message
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
message::add($text['message-delete']);
|
||||||
//execute delete
|
}
|
||||||
$this->database->delete($array);
|
unset($records);
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,176 +25,196 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//define the user settings class
|
//define the user settings class
|
||||||
class user_settings {
|
class user_settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'user_settings';
|
const app_name = 'user_settings';
|
||||||
const app_uuid = '3a3337f7-78d1-23e3-0cfd-f14499b8ed97';
|
const app_uuid = '3a3337f7-78d1-23e3-0cfd-f14499b8ed97';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
private $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare private variables
|
* declare private variables
|
||||||
*/
|
*/
|
||||||
private $permission_prefix;
|
private $permission_prefix;
|
||||||
private $list_page;
|
private $list_page;
|
||||||
private $table;
|
private $table;
|
||||||
private $uuid_prefix;
|
private $uuid_prefix;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare public variables
|
* declare public variables
|
||||||
*/
|
*/
|
||||||
public $user_uuid;
|
public $user_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set domain and user UUIDs
|
*
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//set objects
|
//set objects
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
|
||||||
//assign private variables
|
//assign private variables
|
||||||
$this->permission_prefix = 'user_setting_';
|
$this->permission_prefix = 'user_setting_';
|
||||||
$this->list_page = PROJECT_PATH."/core/user/user_edit.php?id=".urlencode($this->user_uuid ?? '');
|
$this->list_page = PROJECT_PATH . "/core/user/user_edit.php?id=" . urlencode($this->user_uuid ?? '');
|
||||||
$this->table = 'user_settings';
|
$this->table = 'user_settings';
|
||||||
$this->uuid_prefix = 'user_setting_';
|
$this->uuid_prefix = 'user_setting_';
|
||||||
$this->toggle_field = 'user_setting_enabled';
|
$this->toggle_field = 'user_setting_enabled';
|
||||||
$this->toggle_values = ['true','false'];
|
$this->toggle_values = ['true', 'false'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete records
|
* Deletes one or multiple records.
|
||||||
*/
|
*
|
||||||
public function delete($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->permission_prefix.'delete')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'delete')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate('/core/user_settings/user_settings.php')) {
|
if (!$token->validate('/core/user_settings/user_settings.php')) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->list_page);
|
header('Location: ' . $this->list_page);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete multiple records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//build the delete array
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $record['uuid'];
|
||||||
|
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//delete multiple records
|
//delete the checked rows
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
//build the delete array
|
//execute delete
|
||||||
foreach ($records as $x => $record) {
|
$this->database->delete($array);
|
||||||
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
unset($array);
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $record['uuid'];
|
|
||||||
$array[$this->table][$x]['domain_uuid'] = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
//set message
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
//execute delete
|
unset($records);
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggle records
|
* Toggles the state of one or more records.
|
||||||
*/
|
*
|
||||||
public function toggle($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->permission_prefix.'edit')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function toggle($records) {
|
||||||
|
if (permission_exists($this->permission_prefix . 'edit')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate('/core/user_settings/user_settings.php')) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->list_page);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//toggle the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get current toggle state
|
|
||||||
foreach ($records as $x => $record) {
|
|
||||||
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select ".$this->uuid_prefix."uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
|
|
||||||
$sql .= "where domain_uuid = :domain_uuid ";
|
|
||||||
$sql .= "and ".$this->uuid_prefix."uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
|
||||||
$rows = $this->database->select($sql, $parameters, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$states[$row['uuid']] = $row['toggle'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build update array
|
|
||||||
if (is_array($states) && @sizeof($states) != 0) {
|
|
||||||
$x = 0;
|
|
||||||
foreach ($states as $uuid => $state) {
|
|
||||||
$array[$this->table][$x][$this->uuid_prefix.'uuid'] = $uuid;
|
|
||||||
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-toggle']);
|
|
||||||
}
|
|
||||||
unset($records, $states);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate('/core/user_settings/user_settings.php')) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->list_page);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
} //method
|
|
||||||
|
|
||||||
} //class
|
//toggle the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get current toggle state
|
||||||
|
foreach ($records as $x => $record) {
|
||||||
|
if ($record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select " . $this->uuid_prefix . "uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
|
||||||
|
$sql .= "where domain_uuid = :domain_uuid ";
|
||||||
|
$sql .= "and " . $this->uuid_prefix . "uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||||
|
$rows = $this->database->select($sql, $parameters, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$states[$row['uuid']] = $row['toggle'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//build update array
|
||||||
|
if (is_array($states) && @sizeof($states) != 0) {
|
||||||
|
$x = 0;
|
||||||
|
foreach ($states as $uuid => $state) {
|
||||||
|
$array[$this->table][$x][$this->uuid_prefix . 'uuid'] = $uuid;
|
||||||
|
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-toggle']);
|
||||||
|
}
|
||||||
|
unset($records, $states);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} //method
|
||||||
|
|
||||||
|
} //class
|
||||||
|
|||||||
@@ -27,309 +27,336 @@
|
|||||||
/**
|
/**
|
||||||
* users class
|
* users class
|
||||||
*/
|
*/
|
||||||
class users {
|
class users {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare constant variables
|
* declare constant variables
|
||||||
*/
|
*/
|
||||||
const app_name = 'users';
|
const app_name = 'users';
|
||||||
const app_uuid = '112124b3-95c2-5352-7e9d-d14c0b88f207';
|
const app_uuid = '112124b3-95c2-5352-7e9d-d14c0b88f207';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in the constructor. Must be a database object and cannot be null.
|
* Set in the constructor. Must be a database object and cannot be null.
|
||||||
* @var database Database Object
|
*
|
||||||
*/
|
* @var database Database Object
|
||||||
private $database;
|
*/
|
||||||
|
private $database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||||
* @var settings Settings Object
|
*
|
||||||
*/
|
* @var settings Settings Object
|
||||||
private $settings;
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set in the session global array
|
* Domain UUID set in the constructor. This can be passed in through the $settings_array associative array or set
|
||||||
* @var string
|
* in the session global array
|
||||||
*/
|
*
|
||||||
private $domain_uuid;
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* declare the variables
|
* declare the variables
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
private $table;
|
private $table;
|
||||||
private $toggle_field;
|
private $toggle_field;
|
||||||
private $toggle_values;
|
private $toggle_values;
|
||||||
private $location;
|
private $location;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when the object is created
|
* Constructor for the class.
|
||||||
*/
|
*
|
||||||
public function __construct(array $setting_array = []) {
|
* This method initializes the object with setting_array and session data.
|
||||||
//set domain and user UUIDs
|
*
|
||||||
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
* @param array $setting_array An optional array of settings to override default values. Defaults to [].
|
||||||
|
*/
|
||||||
|
public function __construct(array $setting_array = []) {
|
||||||
|
//set domain and user UUIDs
|
||||||
|
$this->domain_uuid = $setting_array['domain_uuid'] ?? $_SESSION['domain_uuid'] ?? '';
|
||||||
|
|
||||||
//set objects
|
//set objects
|
||||||
$this->database = $setting_array['database'] ?? database::new();
|
$this->database = $setting_array['database'] ?? database::new();
|
||||||
|
|
||||||
//assign the variables
|
//assign the variables
|
||||||
$this->name = 'user';
|
$this->name = 'user';
|
||||||
$this->table = 'users';
|
$this->table = 'users';
|
||||||
$this->toggle_field = 'user_enabled';
|
$this->toggle_field = 'user_enabled';
|
||||||
$this->toggle_values = ['true','false'];
|
$this->toggle_values = ['true', 'false'];
|
||||||
$this->location = 'users.php';
|
$this->location = 'users.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete rows from the database
|
* Deletes one or multiple records.
|
||||||
*/
|
*
|
||||||
public function delete($records) {
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
if (permission_exists($this->name.'_delete')) {
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function delete($records) {
|
||||||
|
if (permission_exists($this->name . '_delete')) {
|
||||||
|
|
||||||
//add multi-lingual support
|
//add multi-lingual support
|
||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//validate the token
|
//validate the token
|
||||||
$token = new token;
|
$token = new token;
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
header('Location: '.$this->location);
|
header('Location: ' . $this->location);
|
||||||
exit;
|
exit;
|
||||||
}
|
|
||||||
|
|
||||||
//delete multiple records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
//build the delete array
|
|
||||||
$x = 0;
|
|
||||||
foreach ($records as $record) {
|
|
||||||
//add to the array
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
//get the user_uuid
|
|
||||||
$user_uuid = $record['uuid'];
|
|
||||||
|
|
||||||
//get the user's domain from v_users
|
|
||||||
if (permission_exists('user_domain')) {
|
|
||||||
$sql = "select domain_uuid from v_users ";
|
|
||||||
$sql .= "where user_uuid = :user_uuid ";
|
|
||||||
$parameters['user_uuid'] = $user_uuid;
|
|
||||||
$domain_uuid = $this->database->select($sql, $parameters, 'column');
|
|
||||||
unset($sql, $parameters);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$domain_uuid = $this->domain_uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//required to be a superadmin to delete a member of the superadmin group
|
|
||||||
$superadmin_list = superadmin_list();
|
|
||||||
if (if_superadmin($superadmin_list, $user_uuid)) {
|
|
||||||
if (!if_group("superadmin")) {
|
|
||||||
//access denied - do not delete the user
|
|
||||||
header("Location: index.php");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the user settings
|
|
||||||
$array['user_settings'][$x]['user_uuid'] = $user_uuid;
|
|
||||||
$array['user_settings'][$x]['domain_uuid'] = $domain_uuid;
|
|
||||||
|
|
||||||
//delete the groups the user is assigned to
|
|
||||||
$array['user_groups'][$x]['user_uuid'] = $user_uuid;
|
|
||||||
$array['user_groups'][$x]['domain_uuid'] = $domain_uuid;
|
|
||||||
|
|
||||||
//delete the user
|
|
||||||
$array['users'][$x]['user_uuid'] = $user_uuid;
|
|
||||||
$array['users'][$x]['domain_uuid'] = $domain_uuid;
|
|
||||||
|
|
||||||
//increment the id
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete the checked rows
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//execute
|
|
||||||
$p = permissions::new();
|
|
||||||
$p->add('user_setting_delete', 'temp');
|
|
||||||
$p->add('user_group_delete', 'temp');
|
|
||||||
|
|
||||||
//execute delete
|
|
||||||
$this->database->delete($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
$p->delete('user_setting_delete', 'temp');
|
|
||||||
$p->delete('user_group_delete', 'temp');
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-delete']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
//delete multiple records
|
||||||
* toggle a field between two values
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
*/
|
//build the delete array
|
||||||
public function toggle($records) {
|
$x = 0;
|
||||||
if (permission_exists($this->name.'_edit')) {
|
foreach ($records as $record) {
|
||||||
|
//add to the array
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
//get the user_uuid
|
||||||
|
$user_uuid = $record['uuid'];
|
||||||
|
|
||||||
//add multi-lingual support
|
//get the user's domain from v_users
|
||||||
$language = new text;
|
if (permission_exists('user_domain')) {
|
||||||
$text = $language->get();
|
$sql = "select domain_uuid from v_users ";
|
||||||
|
$sql .= "where user_uuid = :user_uuid ";
|
||||||
|
$parameters['user_uuid'] = $user_uuid;
|
||||||
|
$domain_uuid = $this->database->select($sql, $parameters, 'column');
|
||||||
|
unset($sql, $parameters);
|
||||||
|
} else {
|
||||||
|
$domain_uuid = $this->domain_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
//validate the token
|
//required to be a superadmin to delete a member of the superadmin group
|
||||||
$token = new token;
|
$superadmin_list = superadmin_list();
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
if (if_superadmin($superadmin_list, $user_uuid)) {
|
||||||
message::add($text['message-invalid_token'],'negative');
|
if (!if_group("superadmin")) {
|
||||||
header('Location: '.$this->location);
|
//access denied - do not delete the user
|
||||||
exit;
|
header("Location: index.php");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the user settings
|
||||||
|
$array['user_settings'][$x]['user_uuid'] = $user_uuid;
|
||||||
|
$array['user_settings'][$x]['domain_uuid'] = $domain_uuid;
|
||||||
|
|
||||||
|
//delete the groups the user is assigned to
|
||||||
|
$array['user_groups'][$x]['user_uuid'] = $user_uuid;
|
||||||
|
$array['user_groups'][$x]['domain_uuid'] = $domain_uuid;
|
||||||
|
|
||||||
|
//delete the user
|
||||||
|
$array['users'][$x]['user_uuid'] = $user_uuid;
|
||||||
|
$array['users'][$x]['domain_uuid'] = $domain_uuid;
|
||||||
|
|
||||||
|
//increment the id
|
||||||
|
$x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//toggle the checked records
|
|
||||||
if (is_array($records) && @sizeof($records) != 0) {
|
|
||||||
//get current toggle state
|
|
||||||
foreach($records as $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
|
|
||||||
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$states[$row['uuid']] = $row['toggle'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build update array
|
|
||||||
$x = 0;
|
|
||||||
foreach($states as $uuid => $state) {
|
|
||||||
//create the array
|
|
||||||
$array[$this->table][$x][$this->name.'_uuid'] = $uuid;
|
|
||||||
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
|
||||||
|
|
||||||
//increment the id
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes
|
|
||||||
if (is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//save the array
|
|
||||||
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-toggle']);
|
|
||||||
}
|
|
||||||
unset($records, $states);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* copy rows from the database
|
|
||||||
*/
|
|
||||||
public function copy($records) {
|
|
||||||
if (permission_exists($this->name.'_add')) {
|
|
||||||
|
|
||||||
//add multi-lingual support
|
|
||||||
$language = new text;
|
|
||||||
$text = $language->get();
|
|
||||||
|
|
||||||
//validate the token
|
|
||||||
$token = new token;
|
|
||||||
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
|
||||||
message::add($text['message-invalid_token'],'negative');
|
|
||||||
header('Location: '.$this->location);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the checked records
|
|
||||||
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
|
|
||||||
|
|
||||||
//get checked records
|
|
||||||
foreach($records as $record) {
|
|
||||||
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
|
||||||
$uuids[] = "'".$record['uuid']."'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//create the array from existing data
|
|
||||||
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
|
|
||||||
$sql = "select * from v_".$this->table." ";
|
|
||||||
$sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
|
|
||||||
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
|
||||||
if (is_array($rows) && @sizeof($rows) != 0) {
|
|
||||||
$x = 0;
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
//convert boolean values to a string
|
|
||||||
foreach($row as $key => $value) {
|
|
||||||
if (gettype($value) == 'boolean') {
|
|
||||||
$value = $value ? 'true' : 'false';
|
|
||||||
$row[$key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy data
|
|
||||||
$array[$this->table][$x] = $row;
|
|
||||||
|
|
||||||
//add copy to the description
|
|
||||||
$array[$this->table][$x][$this->name.'_uuid'] = uuid();
|
|
||||||
$array[$this->table][$x]['username'] = $row['username'].'-'.$text['label-copy'];
|
|
||||||
|
|
||||||
//increment the id
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($sql, $parameters, $rows, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
//save the changes and set the message
|
|
||||||
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
|
|
||||||
//save the array
|
|
||||||
$this->database->save($array);
|
|
||||||
unset($array);
|
|
||||||
|
|
||||||
//set message
|
|
||||||
message::add($text['message-copy']);
|
|
||||||
}
|
|
||||||
unset($records);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove old user log entries. Called the maintenance service application.
|
|
||||||
* @param settings $settings
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function database_maintenance(settings $settings): void {
|
|
||||||
$database = $settings->database();
|
|
||||||
$domains = maintenance_service::get_domains($database);
|
|
||||||
foreach ($domains as $domain_uuid => $domain_name) {
|
|
||||||
$domain_settings = new settings(['database' => $database, 'domain_uuid' => $domain_uuid]);
|
|
||||||
$retention_days = $domain_settings->get('users', 'database_retention_days', '');
|
|
||||||
if (!empty($retention_days) && is_numeric($retention_days)) {
|
|
||||||
$sql = "delete from v_user_logs where timestamp < NOW() - INTERVAL '$retention_days days'";
|
|
||||||
$sql.= " and domain_uuid = '$domain_uuid'";
|
|
||||||
$database->execute($sql);
|
|
||||||
$code = $database->message['code'] ?? 0;
|
|
||||||
if ($code == 200) {
|
|
||||||
maintenance_service::log_write(self::class, "Successfully removed entries older than $retention_days", $domain_uuid);
|
|
||||||
} else {
|
|
||||||
$message = $database->message['message'] ?? "An unknown error has occurred";
|
|
||||||
maintenance_service::log_write(self::class, "Unable to remove old database records. Error message: $message ($code)", $domain_uuid, maintenance_service::LOG_ERROR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
maintenance_service::log_write(self::class, "Database retention days not set or not numeric", $domain_uuid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//delete the checked rows
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//execute
|
||||||
|
$p = permissions::new();
|
||||||
|
$p->add('user_setting_delete', 'temp');
|
||||||
|
$p->add('user_group_delete', 'temp');
|
||||||
|
|
||||||
|
//execute delete
|
||||||
|
$this->database->delete($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
$p->delete('user_setting_delete', 'temp');
|
||||||
|
$p->delete('user_group_delete', 'temp');
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-delete']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the state of one or more records.
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function toggle($records) {
|
||||||
|
if (permission_exists($this->name . '_edit')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->location);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//toggle the checked records
|
||||||
|
if (is_array($records) && @sizeof($records) != 0) {
|
||||||
|
//get current toggle state
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select " . $this->name . "_uuid as uuid, " . $this->toggle_field . " as toggle from v_" . $this->table . " ";
|
||||||
|
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$states[$row['uuid']] = $row['toggle'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//build update array
|
||||||
|
$x = 0;
|
||||||
|
foreach ($states as $uuid => $state) {
|
||||||
|
//create the array
|
||||||
|
$array[$this->table][$x][$this->name . '_uuid'] = $uuid;
|
||||||
|
$array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
|
||||||
|
|
||||||
|
//increment the id
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes
|
||||||
|
if (is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//save the array
|
||||||
|
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-toggle']);
|
||||||
|
}
|
||||||
|
unset($records, $states);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies one or more records
|
||||||
|
*
|
||||||
|
* @param array $records An array of record IDs to delete, where each ID is an associative array
|
||||||
|
* containing 'uuid' and 'checked' keys. The 'checked' value indicates
|
||||||
|
* whether the corresponding checkbox was checked for deletion.
|
||||||
|
*
|
||||||
|
* @return void No return value; this method modifies the database state and sets a message.
|
||||||
|
*/
|
||||||
|
public function copy($records) {
|
||||||
|
if (permission_exists($this->name . '_add')) {
|
||||||
|
|
||||||
|
//add multi-lingual support
|
||||||
|
$language = new text;
|
||||||
|
$text = $language->get();
|
||||||
|
|
||||||
|
//validate the token
|
||||||
|
$token = new token;
|
||||||
|
if (!$token->validate($_SERVER['PHP_SELF'])) {
|
||||||
|
message::add($text['message-invalid_token'], 'negative');
|
||||||
|
header('Location: ' . $this->location);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the checked records
|
||||||
|
if (!empty($records) && is_array($records) && @sizeof($records) != 0) {
|
||||||
|
|
||||||
|
//get checked records
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
|
||||||
|
$uuids[] = "'" . $record['uuid'] . "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create the array from existing data
|
||||||
|
if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
|
||||||
|
$sql = "select * from v_" . $this->table . " ";
|
||||||
|
$sql .= "where " . $this->name . "_uuid in (" . implode(', ', $uuids) . ") ";
|
||||||
|
$rows = $this->database->select($sql, $parameters ?? null, 'all');
|
||||||
|
if (is_array($rows) && @sizeof($rows) != 0) {
|
||||||
|
$x = 0;
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
//convert boolean values to a string
|
||||||
|
foreach ($row as $key => $value) {
|
||||||
|
if (gettype($value) == 'boolean') {
|
||||||
|
$value = $value ? 'true' : 'false';
|
||||||
|
$row[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy data
|
||||||
|
$array[$this->table][$x] = $row;
|
||||||
|
|
||||||
|
//add copy to the description
|
||||||
|
$array[$this->table][$x][$this->name . '_uuid'] = uuid();
|
||||||
|
$array[$this->table][$x]['username'] = $row['username'] . '-' . $text['label-copy'];
|
||||||
|
|
||||||
|
//increment the id
|
||||||
|
$x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($sql, $parameters, $rows, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the changes and set the message
|
||||||
|
if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
|
||||||
|
//save the array
|
||||||
|
$this->database->save($array);
|
||||||
|
unset($array);
|
||||||
|
|
||||||
|
//set message
|
||||||
|
message::add($text['message-copy']);
|
||||||
|
}
|
||||||
|
unset($records);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove old user log entries. Called the maintenance service application.
|
||||||
|
*
|
||||||
|
* @param settings $settings
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function database_maintenance(settings $settings): void {
|
||||||
|
$database = $settings->database();
|
||||||
|
$domains = maintenance_service::get_domains($database);
|
||||||
|
foreach ($domains as $domain_uuid => $domain_name) {
|
||||||
|
$domain_settings = new settings(['database' => $database, 'domain_uuid' => $domain_uuid]);
|
||||||
|
$retention_days = $domain_settings->get('users', 'database_retention_days', '');
|
||||||
|
if (!empty($retention_days) && is_numeric($retention_days)) {
|
||||||
|
$sql = "delete from v_user_logs where timestamp < NOW() - INTERVAL '$retention_days days'";
|
||||||
|
$sql .= " and domain_uuid = '$domain_uuid'";
|
||||||
|
$database->execute($sql);
|
||||||
|
$code = $database->message['code'] ?? 0;
|
||||||
|
if ($code == 200) {
|
||||||
|
maintenance_service::log_write(self::class, "Successfully removed entries older than $retention_days", $domain_uuid);
|
||||||
|
} else {
|
||||||
|
$message = $database->message['message'] ?? "An unknown error has occurred";
|
||||||
|
maintenance_service::log_write(self::class, "Unable to remove old database records. Error message: $message ($code)", $domain_uuid, maintenance_service::LOG_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
maintenance_service::log_write(self::class, "Database retention days not set or not numeric", $domain_uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,18 +38,6 @@
|
|||||||
$language = new text;
|
$language = new text;
|
||||||
$text = $language->get();
|
$text = $language->get();
|
||||||
|
|
||||||
//built in str_getcsv requires PHP 5.3 or higher, this function can be used to reproduce the functionality but requires PHP 5.1.0 or higher
|
|
||||||
if (!function_exists('str_getcsv')) {
|
|
||||||
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
|
|
||||||
$fp = fopen("php://memory", 'r+');
|
|
||||||
fputs($fp, $input);
|
|
||||||
rewind($fp);
|
|
||||||
$data = fgetcsv($fp, null, $delimiter, $enclosure); // $escape only got added in 5.3.0
|
|
||||||
fclose($fp);
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the http get values and set them as php variables
|
//get the http get values and set them as php variables
|
||||||
$action = $_POST["action"] ?? '';
|
$action = $_POST["action"] ?? '';
|
||||||
$from_row = $_POST["from_row"] ?? '';
|
$from_row = $_POST["from_row"] ?? '';
|
||||||
@@ -220,6 +208,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//get the parent table
|
//get the parent table
|
||||||
|
/**
|
||||||
|
* Retrieves the parent table of a given table in the schema.
|
||||||
|
*
|
||||||
|
* @param array $schema An array containing schema information, where each row represents a table.
|
||||||
|
* @param string $table_name The name of the table for which to retrieve the parent.
|
||||||
|
*
|
||||||
|
* @return mixed|null The parent table of the specified table, or null if no match is found.
|
||||||
|
*/
|
||||||
function get_parent($schema,$table_name) {
|
function get_parent($schema,$table_name) {
|
||||||
foreach ($schema as $row) {
|
foreach ($schema as $row) {
|
||||||
if ($row['table'] == $table_name) {
|
if ($row['table'] == $table_name) {
|
||||||
|
|||||||
@@ -29,19 +29,22 @@
|
|||||||
/**
|
/**
|
||||||
* A base message for communication
|
* A base message for communication
|
||||||
*
|
*
|
||||||
|
* @param string $payload ;
|
||||||
|
*
|
||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
* @param string $payload;
|
|
||||||
*/
|
*/
|
||||||
class base_message {
|
class base_message {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id is contained to the base_message class. Subclasses or child classes should not adjust this value
|
* The id is contained to the base_message class. Subclasses or child classes should not adjust this value
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Payload can be any value
|
* Payload can be any value
|
||||||
|
*
|
||||||
* @var mixed
|
* @var mixed
|
||||||
*/
|
*/
|
||||||
protected $payload;
|
protected $payload;
|
||||||
@@ -51,6 +54,7 @@ class base_message {
|
|||||||
* When the array is provided as an associative array, the object properties
|
* When the array is provided as an associative array, the object properties
|
||||||
* are filled using the array key as the property name and the value of the array
|
* are filled using the array key as the property name and the value of the array
|
||||||
* for the value of the property in the object.
|
* for the value of the property in the object.
|
||||||
|
*
|
||||||
* @param array $associative_properties_array
|
* @param array $associative_properties_array
|
||||||
*/
|
*/
|
||||||
public function __construct($associative_properties_array = []) {
|
public function __construct($associative_properties_array = []) {
|
||||||
@@ -69,7 +73,9 @@ class base_message {
|
|||||||
* If the method exists then the method will be called to get the value in the object property.
|
* If the method exists then the method will be called to get the value in the object property.
|
||||||
* If the method is not in the object then the property name is checked to see if it is valid. If the
|
* If the method is not in the object then the property name is checked to see if it is valid. If the
|
||||||
* name is not available then an exception is thrown.
|
* name is not available then an exception is thrown.
|
||||||
|
*
|
||||||
* @param string $name Name of the property
|
* @param string $name Name of the property
|
||||||
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws InvalidProperty
|
* @throws InvalidProperty
|
||||||
*/
|
*/
|
||||||
@@ -90,13 +96,15 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the object property in the given name to be the given value
|
* Sets the object property in the given name to be the given value
|
||||||
* @param string $name Name of the object property
|
*
|
||||||
* @param mixed $value Value of the object property
|
* @param string $name Name of the object property
|
||||||
|
* @param mixed $value Value of the object property
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function __set(string $name, $value): void {
|
public function __set(string $name, $value): void {
|
||||||
if (method_exists($this, "set_$name")){
|
if (method_exists($this, "set_$name")) {
|
||||||
//
|
//
|
||||||
// By calling the method with the setter name of the property first, we give
|
// By calling the method with the setter name of the property first, we give
|
||||||
// the child object the opportunity to modify the value before it is
|
// the child object the opportunity to modify the value before it is
|
||||||
@@ -124,6 +132,7 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a method that PHP will call if the object is echoed or printed.
|
* Provides a method that PHP will call if the object is echoed or printed.
|
||||||
|
*
|
||||||
* @return string JSON string representing the object
|
* @return string JSON string representing the object
|
||||||
* @depends to_json
|
* @depends to_json
|
||||||
*/
|
*/
|
||||||
@@ -133,6 +142,7 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this object ID given by PHP
|
* Returns this object ID given by PHP
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function get_id(): int {
|
public function get_id(): int {
|
||||||
@@ -141,7 +151,9 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the message payload to be delivered
|
* Sets the message payload to be delivered
|
||||||
|
*
|
||||||
* @param mixed $payload Payload for the message to carry
|
* @param mixed $payload Payload for the message to carry
|
||||||
|
*
|
||||||
* @return $this Returns this object for chaining
|
* @return $this Returns this object for chaining
|
||||||
*/
|
*/
|
||||||
public function set_payload($payload) {
|
public function set_payload($payload) {
|
||||||
@@ -151,6 +163,7 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the payload contained in this message
|
* Returns the payload contained in this message
|
||||||
|
*
|
||||||
* @return mixed Payload in the message
|
* @return mixed Payload in the message
|
||||||
*/
|
*/
|
||||||
public function get_payload() {
|
public function get_payload() {
|
||||||
@@ -164,8 +177,11 @@ class base_message {
|
|||||||
* the method is called with no parameters given, the payload is
|
* the method is called with no parameters given, the payload is
|
||||||
* returned to the caller.
|
* returned to the caller.
|
||||||
* Payload the message object is delivering
|
* Payload the message object is delivering
|
||||||
|
*
|
||||||
* @param mixed $payload If set, payload is set to the value. Otherwise, the payload is returned.
|
* @param mixed $payload If set, payload is set to the value. Otherwise, the payload is returned.
|
||||||
* @return mixed If payload was given to call the method, this object is returned. If no value was provided the payload is returned.
|
*
|
||||||
|
* @return mixed If payload was given to call the method, this object is returned. If no value was provided the
|
||||||
|
* payload is returned.
|
||||||
* @see set_payload
|
* @see set_payload
|
||||||
* @see get_payload
|
* @see get_payload
|
||||||
*/
|
*/
|
||||||
@@ -178,7 +194,9 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively convert this object or child object to an array.
|
* Recursively convert this object or child object to an array.
|
||||||
|
*
|
||||||
* @param mixed $iterate Private value to be set while iterating over the object properties
|
* @param mixed $iterate Private value to be set while iterating over the object properties
|
||||||
|
*
|
||||||
* @return array Array representing the properties of this object
|
* @return array Array representing the properties of this object
|
||||||
*/
|
*/
|
||||||
public function to_array($iterate = null): array {
|
public function to_array($iterate = null): array {
|
||||||
@@ -191,7 +209,7 @@ class base_message {
|
|||||||
$value = $this->to_array($value);
|
$value = $this->to_array($value);
|
||||||
} elseif (is_object($value) && method_exists($value, 'to_array')) {
|
} elseif (is_object($value) && method_exists($value, 'to_array')) {
|
||||||
$value = $value->to_array();
|
$value = $value->to_array();
|
||||||
} elseif (is_object($value) && method_exists($value, '__toArray')) { // PHP array casting
|
} elseif (is_object($value) && method_exists($value, '__toArray')) { // PHP array casting
|
||||||
$value = $value->__toArray();
|
$value = $value->__toArray();
|
||||||
}
|
}
|
||||||
$array[$property] = $value;
|
$array[$property] = $value;
|
||||||
@@ -201,6 +219,7 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a json string
|
* Returns a json string
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @depends to_array
|
* @depends to_array
|
||||||
*/
|
*/
|
||||||
@@ -210,6 +229,7 @@ class base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array representing this object or child object.
|
* Returns an array representing this object or child object.
|
||||||
|
*
|
||||||
* @return array Array of object properties
|
* @return array Array of object properties
|
||||||
*/
|
*/
|
||||||
public function __toArray(): array {
|
public function __toArray(): array {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of base_websocket_system_service
|
* Description of base_websocket_system_service
|
||||||
*
|
*
|
||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
*/
|
*/
|
||||||
@@ -12,12 +12,14 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a time to fire the on_timer function
|
* Sets a time to fire the on_timer function
|
||||||
|
*
|
||||||
* @var int|null
|
* @var int|null
|
||||||
*/
|
*/
|
||||||
protected $timer_expire_time = null;
|
protected $timer_expire_time = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Websocket client
|
* Websocket client
|
||||||
|
*
|
||||||
* @var websocket_client $ws_client
|
* @var websocket_client $ws_client
|
||||||
*/
|
*/
|
||||||
protected $ws_client;
|
protected $ws_client;
|
||||||
@@ -26,6 +28,7 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of topics and their callbacks
|
* Array of topics and their callbacks
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $topics;
|
protected $topics;
|
||||||
@@ -35,24 +38,37 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
* Listener is an array of socket and callback used to listen for events on the socket. When a listener is added,
|
* Listener is an array of socket and callback used to listen for events on the socket. When a listener is added,
|
||||||
* the socket is added to the array of listeners. When the socket is closed, the listener is removed from the
|
* the socket is added to the array of listeners. When the socket is closed, the listener is removed from the
|
||||||
* array of listeners. When an event is received on the respective socket, the provided callback is called.
|
* array of listeners. When an event is received on the respective socket, the provided callback is called.
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $listeners;
|
protected $listeners;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs the version of the Service.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
protected static function display_version(): void {
|
protected static function display_version(): void {
|
||||||
echo "System Dashboard Service 1.0\n";
|
echo "System Dashboard Service 1.0\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a timer to trigger the defined function every $seconds. To stop the timer, set the value to null
|
* Set a timer to trigger the defined function every $seconds. To stop the timer, set the value to null
|
||||||
|
*
|
||||||
* @param int $seconds
|
* @param int $seconds
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @see on_timer
|
* @see on_timer
|
||||||
*/
|
*/
|
||||||
protected function set_timer(int $seconds, callable $callable): void {
|
protected function set_timer(int $seconds, callable $callable): void {
|
||||||
$this->timers[] = ['expire_time' => time() + $seconds, 'callable' => $callable];
|
$this->timers[] = ['expire_time' => time() + $seconds, 'callable' => $callable];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append command options to set the websockets port and host address
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
protected static function set_command_options() {
|
protected static function set_command_options() {
|
||||||
parent::append_command_option(
|
parent::append_command_option(
|
||||||
command_option::new()
|
command_option::new()
|
||||||
@@ -74,10 +90,20 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the port for the WebSocket connection.
|
||||||
|
*
|
||||||
|
* @param int $port The new port number to use for the WebSocket connection
|
||||||
|
*/
|
||||||
protected static function set_websockets_port($port): void {
|
protected static function set_websockets_port($port): void {
|
||||||
self::$websocket_port = $port;
|
self::$websocket_port = $port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the host address for websockets connections.
|
||||||
|
*
|
||||||
|
* @param string $host The host address to use for websockets connections
|
||||||
|
*/
|
||||||
protected static function set_websockets_host_address($host): void {
|
protected static function set_websockets_host_address($host): void {
|
||||||
self::$websocket_host = $host;
|
self::$websocket_host = $host;
|
||||||
}
|
}
|
||||||
@@ -85,14 +111,20 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
/**
|
/**
|
||||||
* Add a socket listener
|
* Add a socket listener
|
||||||
*
|
*
|
||||||
* @param $socket
|
* @param $socket
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function add_listener($socket, callable $callback): void {
|
protected function add_listener($socket, callable $callback): void {
|
||||||
$this->listeners[] = [$socket, $callback];
|
$this->listeners[] = [$socket, $callback];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main execution loop for handling WebSocket events and timers.
|
||||||
|
*
|
||||||
|
* @return int Exit code, indicating whether the process exited normally (0) or with an error (1).
|
||||||
|
*/
|
||||||
public function run(): int {
|
public function run(): int {
|
||||||
// set the timers property as an array
|
// set the timers property as an array
|
||||||
$this->timers = [];
|
$this->timers = [];
|
||||||
@@ -175,7 +207,7 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
// Timers can be set by child classes
|
// Timers can be set by child classes
|
||||||
if (!empty($this->timers)) {
|
if (!empty($this->timers)) {
|
||||||
// Check all timers
|
// Check all timers
|
||||||
foreach($this->timers as $key => $array) {
|
foreach ($this->timers as $key => $array) {
|
||||||
// Check if the timer should be run
|
// Check if the timer should be run
|
||||||
if (time() >= $array['expire_time']) {
|
if (time() >= $array['expire_time']) {
|
||||||
// Get the callback function
|
// Get the callback function
|
||||||
@@ -197,6 +229,7 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to the web socket server using a websocket_client object
|
* Connects to the web socket server using a websocket_client object
|
||||||
|
*
|
||||||
* @return bool True if connected and False if not able to connect
|
* @return bool True if connected and False if not able to connect
|
||||||
*/
|
*/
|
||||||
protected function connect_to_ws_server(): bool {
|
protected function connect_to_ws_server(): bool {
|
||||||
@@ -227,7 +260,7 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the message from the web socket client and triggers the appropriate requested topic event
|
* Handles the message from the web socket client and triggers the appropriate requested topic event
|
||||||
* @param resource $ws_client
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function handle_websocket_event() {
|
private function handle_websocket_event() {
|
||||||
@@ -257,7 +290,8 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Call each of the registered events for the websocket topic that has arrived
|
* Call each of the registered events for the websocket topic that has arrived
|
||||||
* @param string $topic
|
*
|
||||||
|
* @param string $topic
|
||||||
* @param websocket_message $websocket_message
|
* @param websocket_message $websocket_message
|
||||||
*/
|
*/
|
||||||
private function trigger_topic(string $topic, websocket_message $websocket_message) {
|
private function trigger_topic(string $topic, websocket_message $websocket_message) {
|
||||||
@@ -272,6 +306,11 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate with the websocket server using a service token
|
||||||
|
*
|
||||||
|
* @param websocket_message $websocket_message The incoming websocket message that triggered this event
|
||||||
|
*/
|
||||||
protected function on_authenticate(websocket_message $websocket_message) {
|
protected function on_authenticate(websocket_message $websocket_message) {
|
||||||
$this->info("Authenticating with websocket server");
|
$this->info("Authenticating with websocket server");
|
||||||
// Create a service token
|
// Create a service token
|
||||||
@@ -283,7 +322,8 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the service to register a callback so when the topic arrives the callable is called
|
* Allows the service to register a callback so when the topic arrives the callable is called
|
||||||
* @param string $topic
|
*
|
||||||
|
* @param string $topic
|
||||||
* @param callable $callable
|
* @param callable $callable
|
||||||
*/
|
*/
|
||||||
protected function on_topic($topic, $callable) {
|
protected function on_topic($topic, $callable) {
|
||||||
@@ -293,9 +333,19 @@ abstract class base_websocket_system_service extends service implements websocke
|
|||||||
$this->topics[$topic][] = $callable;
|
$this->topics[$topic][] = $callable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a websocket message to the client
|
||||||
|
*
|
||||||
|
* @param websocket_message $websocket_message The message to be sent
|
||||||
|
*/
|
||||||
protected function respond(websocket_message $websocket_message): void {
|
protected function respond(websocket_message $websocket_message): void {
|
||||||
websocket_client::send($this->ws_client->socket(), $websocket_message);
|
websocket_client::send($this->ws_client->socket(), $websocket_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register topics and associated callbacks.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
abstract protected function register_topics(): void;
|
abstract protected function register_topics(): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,25 @@ class permission_filter implements filter {
|
|||||||
private $field_map;
|
private $field_map;
|
||||||
private $permissions;
|
private $permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of this class with a map of event field keys to permissions and an optional list of
|
||||||
|
* additional permissions.
|
||||||
|
*
|
||||||
|
* @param array $event_field_key_to_permission_map Map of event field keys to permissions
|
||||||
|
* @param array $permissions Optional list of additional permissions (default: [])
|
||||||
|
*/
|
||||||
public function __construct(array $event_field_key_to_permission_map, array $permissions = []) {
|
public function __construct(array $event_field_key_to_permission_map, array $permissions = []) {
|
||||||
$this->field_map = $event_field_key_to_permission_map;
|
$this->field_map = $event_field_key_to_permission_map;
|
||||||
$this->add_permissions($permissions);
|
$this->add_permissions($permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the object to check if a value can be set for a given field.
|
||||||
|
*
|
||||||
|
* @param string $key The key of the field to check
|
||||||
|
*
|
||||||
|
* @return bool|null True if the value can be set, null otherwise
|
||||||
|
*/
|
||||||
public function __invoke(string $key, $value): ?bool {
|
public function __invoke(string $key, $value): ?bool {
|
||||||
$permission = $this->field_map[$key] ?? null;
|
$permission = $this->field_map[$key] ?? null;
|
||||||
if ($permission === null || $this->has_permission($permission)) {
|
if ($permission === null || $this->has_permission($permission)) {
|
||||||
@@ -50,7 +64,9 @@ class permission_filter implements filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an associative array of permissions where $key is the name of the permission and $value is ignored as it should always be set to true.
|
* Adds an associative array of permissions where $key is the name of the permission and $value is ignored as it
|
||||||
|
* should always be set to true.
|
||||||
|
*
|
||||||
* @param array $permissions
|
* @param array $permissions
|
||||||
*/
|
*/
|
||||||
public function add_permissions(array $permissions) {
|
public function add_permissions(array $permissions) {
|
||||||
@@ -62,6 +78,7 @@ class permission_filter implements filter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a single permission
|
* Adds a single permission
|
||||||
|
*
|
||||||
* @param string $key
|
* @param string $key
|
||||||
*/
|
*/
|
||||||
public function add_permission(string $key) {
|
public function add_permission(string $key) {
|
||||||
@@ -70,7 +87,9 @@ class permission_filter implements filter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the filter has a permission
|
* Checks if the filter has a permission
|
||||||
|
*
|
||||||
* @param string $key
|
* @param string $key
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function has_permission(string $key): bool {
|
public function has_permission(string $key): bool {
|
||||||
|
|||||||
@@ -33,6 +33,17 @@
|
|||||||
*/
|
*/
|
||||||
class socket_exception extends \Exception {
|
class socket_exception extends \Exception {
|
||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of the object.
|
||||||
|
*
|
||||||
|
* @param mixed $id Unique identifier for this exception (default: null)
|
||||||
|
* @param string $message Exception message (default: "")
|
||||||
|
* @param int $code Exception code (default: 0)
|
||||||
|
* @param \Throwable|null $previous The previous exception (default: null)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function __construct($id = null, string $message = "", int $code = 0, ?\Throwable $previous = null) {
|
public function __construct($id = null, string $message = "", int $code = 0, ?\Throwable $previous = null) {
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
return parent::__construct($message, $code, $previous);
|
return parent::__construct($message, $code, $previous);
|
||||||
|
|||||||
@@ -30,12 +30,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of subscriber
|
* Description of subscriber
|
||||||
|
*
|
||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
*/
|
*/
|
||||||
class subscriber {
|
class subscriber {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ID of the object given by PHP
|
* The ID of the object given by PHP
|
||||||
|
*
|
||||||
* @var spl_object_id
|
* @var spl_object_id
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
@@ -51,128 +53,151 @@ class subscriber {
|
|||||||
* The resource is cast to an integer and then saved in order to match the
|
* The resource is cast to an integer and then saved in order to match the
|
||||||
* a resource to the original socket. This is primarily used in the equals
|
* a resource to the original socket. This is primarily used in the equals
|
||||||
* method to test for equality.
|
* method to test for equality.
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $socket_id;
|
private $socket_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote IP of the socket resource connection
|
* Remote IP of the socket resource connection
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $remote_ip;
|
private $remote_ip;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote port of the socket resource connection
|
* Remote port of the socket resource connection
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $remote_port;
|
private $remote_port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Services the subscriber has subscribed to
|
* Services the subscriber has subscribed to
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $services;
|
private $services;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permissions array of the subscriber
|
* Permissions array of the subscriber
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $permissions;
|
private $permissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain name the subscriber belongs to
|
* Domain name the subscriber belongs to
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $domain_name;
|
private $domain_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain UUID the subscriber belongs to
|
* Domain UUID the subscriber belongs to
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $domain_uuid;
|
private $domain_uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token hash used to validate this subscriber
|
* Token hash used to validate this subscriber
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $token_hash;
|
private $token_hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token name used to validate this subscriber
|
* Token name used to validate this subscriber
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $token_name;
|
private $token_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Epoch time the token was issued
|
* Epoch time the token was issued
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $token_time;
|
private $token_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time limit in seconds
|
* Time limit in seconds
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $token_limit;
|
private $token_limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the subscriber has a time limit set for their token or not
|
* Whether the subscriber has a time limit set for their token or not
|
||||||
|
*
|
||||||
* @var bool True when there is a time limit. False if no time limit set.
|
* @var bool True when there is a time limit. False if no time limit set.
|
||||||
*/
|
*/
|
||||||
private $enable_token_time_limit;
|
private $enable_token_time_limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the subscriber is able to broadcast messages as a service
|
* Whether the subscriber is able to broadcast messages as a service
|
||||||
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $service;
|
private $service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the service class object to handle callbacks
|
* The name of the service class object to handle callbacks
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $service_class;
|
private $service_class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the subscriber is a service the service name used
|
* If the subscriber is a service the service name used
|
||||||
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $service_name;
|
private $service_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The filter used to send web socket messages
|
* The filter used to send web socket messages
|
||||||
|
*
|
||||||
* @var filter
|
* @var filter
|
||||||
*/
|
*/
|
||||||
private $filter;
|
private $filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function or method name to call when sending information through the socket
|
* Function or method name to call when sending information through the socket
|
||||||
|
*
|
||||||
* @var callable
|
* @var callable
|
||||||
*/
|
*/
|
||||||
private $callback;
|
private $callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscriptions to services
|
* Subscriptions to services
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $subscriptions;
|
private $subscriptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this subscriber has been authenticated
|
* Whether or not this subscriber has been authenticated
|
||||||
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $authenticated;
|
private $authenticated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User information
|
* User information
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a subscriber object.
|
* Creates a subscriber object.
|
||||||
* @param resource|stream $socket Connected socket
|
*
|
||||||
* @param callable $frame_wrapper The callback used to wrap communication in a web socket frame. Sending NULL to the frame wrapper should send a disconnect.
|
* @param resource|stream $socket Connected socket
|
||||||
|
* @param callable $frame_wrapper The callback used to wrap communication in a web socket frame. Sending
|
||||||
|
* NULL to the frame wrapper should send a disconnect.
|
||||||
|
*
|
||||||
* @throws \socket_exception Thrown when the passed socket is already closed
|
* @throws \socket_exception Thrown when the passed socket is already closed
|
||||||
* @throws \InvalidArgumentException Thrown when the $callback is not a valid callback
|
* @throws \InvalidArgumentException Thrown when the $callback is not a valid callback
|
||||||
*/
|
*/
|
||||||
@@ -186,9 +211,9 @@ class subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set object identifiers
|
// set object identifiers
|
||||||
$this->id = md5(spl_object_hash($this)); // PHP unique object hash is similar to 000000000000000f0000000000000000 so we use md5
|
$this->id = md5(spl_object_hash($this)); // PHP unique object hash is similar to 000000000000000f0000000000000000 so we use md5
|
||||||
$this->socket = $socket;
|
$this->socket = $socket;
|
||||||
$this->socket_id = (int) $socket;
|
$this->socket_id = (int)$socket;
|
||||||
|
|
||||||
$this->domain_name = '';
|
$this->domain_name = '';
|
||||||
$this->domain_uuid = '';
|
$this->domain_uuid = '';
|
||||||
@@ -197,14 +222,14 @@ class subscriber {
|
|||||||
[$this->remote_ip, $this->remote_port] = self::get_remote_information_from_socket($socket);
|
[$this->remote_ip, $this->remote_port] = self::get_remote_information_from_socket($socket);
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
$this->authenticated = false;
|
$this->authenticated = false;
|
||||||
$this->permissions = [];
|
$this->permissions = [];
|
||||||
$this->services = [];
|
$this->services = [];
|
||||||
$this->enable_token_time_limit = false;
|
$this->enable_token_time_limit = false;
|
||||||
$this->subscriptions = [];
|
$this->subscriptions = [];
|
||||||
$this->service = false;
|
$this->service = false;
|
||||||
$this->service_name = '';
|
$this->service_name = '';
|
||||||
$this->user = [];
|
$this->user = [];
|
||||||
|
|
||||||
// Save the websocket frame wrapper used to communicate to this subscriber
|
// Save the websocket frame wrapper used to communicate to this subscriber
|
||||||
$this->callback = $frame_wrapper;
|
$this->callback = $frame_wrapper;
|
||||||
@@ -215,6 +240,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user array information in this subscriber
|
* Returns the user array information in this subscriber
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_user_array(): array {
|
public function get_user_array(): array {
|
||||||
@@ -222,18 +248,23 @@ class subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user information from the provided key.
|
* Retrieves a user setting by its key.
|
||||||
* @param string $key
|
*
|
||||||
* @return mixed
|
* @param string $key The name of the user setting to retrieve
|
||||||
|
* @param mixed $default_value The default value to return if the setting is not found (optional)
|
||||||
|
*
|
||||||
|
* @return mixed The value of the user setting, or the default value if it does not exist
|
||||||
*/
|
*/
|
||||||
public function get_user_setting($key, $default_value = null) {
|
public function get_user_setting($key, $default_value = null) {
|
||||||
return $this->user[$key] ?? $default_value;
|
return $this->user[$key] ?? $default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the subscribed to services
|
* Checks if this subscriber is subscribed to the given services
|
||||||
* @param array $services
|
*
|
||||||
* @return $this|array
|
* @param array $services Optional list of service names, e.g. [active.calls, inactive.calls]
|
||||||
|
*
|
||||||
|
* @return mixed This object or an array of subscribed service names
|
||||||
*/
|
*/
|
||||||
public function subscribed_to($services = []) {
|
public function subscribed_to($services = []) {
|
||||||
if (func_num_args() > 0) {
|
if (func_num_args() > 0) {
|
||||||
@@ -245,7 +276,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the service class name for this subscriber
|
* Gets or sets the service class name for this subscriber
|
||||||
* @param string $service_class
|
*
|
||||||
|
* @param ?string $service_class
|
||||||
|
*
|
||||||
* @return $this|string
|
* @return $this|string
|
||||||
*/
|
*/
|
||||||
public function service_class($service_class = null) {
|
public function service_class($service_class = null) {
|
||||||
@@ -258,7 +291,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the filter used for this subscriber
|
* Sets the filter used for this subscriber
|
||||||
|
*
|
||||||
* @param filter $filter
|
* @param filter $filter
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function set_filter(filter $filter) {
|
public function set_filter(filter $filter) {
|
||||||
@@ -268,6 +303,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the filter used for this subscriber
|
* Returns the filter used for this subscriber
|
||||||
|
*
|
||||||
* @return filter
|
* @return filter
|
||||||
*/
|
*/
|
||||||
public function get_filter() {
|
public function get_filter() {
|
||||||
@@ -284,6 +320,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects the socket resource used for this subscriber
|
* Disconnects the socket resource used for this subscriber
|
||||||
|
*
|
||||||
* @return bool true on success and false on failure
|
* @return bool true on success and false on failure
|
||||||
*/
|
*/
|
||||||
public function disconnect(): bool {
|
public function disconnect(): bool {
|
||||||
@@ -298,9 +335,11 @@ class subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the current object with another object to see if they are exactly the same object
|
* Checks if this subscriber is equal to the given object, resource or id.
|
||||||
* @param subscriber|resource $object_or_resource_or_id
|
*
|
||||||
* @return bool
|
* @param mixed $object_or_resource_or_id The object, resource or id to compare with
|
||||||
|
*
|
||||||
|
* @return bool True if the subscribers are equal, false otherwise
|
||||||
*/
|
*/
|
||||||
public function equals($object_or_resource_or_id): bool {
|
public function equals($object_or_resource_or_id): bool {
|
||||||
// Compare by resource
|
// Compare by resource
|
||||||
@@ -322,7 +361,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this object to another object or resource id.
|
* Compares this object to another object or resource id.
|
||||||
* @param type $object_or_resource
|
*
|
||||||
|
* @param $object_or_resource The object or resource to compare
|
||||||
|
*
|
||||||
* @return bool True if this object is not equal to the other object or resource. False otherwise.
|
* @return bool True if this object is not equal to the other object or resource. False otherwise.
|
||||||
* @see subscriber::equals()
|
* @see subscriber::equals()
|
||||||
*/
|
*/
|
||||||
@@ -332,9 +373,10 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow accessing <b>copies</b> of the private values to ensure the object values are immutable.
|
* Allow accessing <b>copies</b> of the private values to ensure the object values are immutable.
|
||||||
* @param string $name
|
*
|
||||||
* @return mixed
|
* @param string $name The name of the attribute to be accessed
|
||||||
* @throws \InvalidArgumentException
|
*
|
||||||
|
* @throws \InvalidArgumentException If the attribute does not exist or direct access is prohibited
|
||||||
*/
|
*/
|
||||||
public function __get(string $name) {
|
public function __get(string $name) {
|
||||||
switch ($name) {
|
switch ($name) {
|
||||||
@@ -357,6 +399,7 @@ class subscriber {
|
|||||||
/**
|
/**
|
||||||
* Returns the current ID of this subscriber.
|
* Returns the current ID of this subscriber.
|
||||||
* The ID is set in the constructor using the spl_object_id given by PHP
|
* The ID is set in the constructor using the spl_object_id given by PHP
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function id(): string {
|
public function id(): string {
|
||||||
@@ -365,7 +408,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this subscriber has the permission given in $permission
|
* Checks if this subscriber has the permission given in $permission
|
||||||
* @param string $permission
|
*
|
||||||
|
* @param string $permission The permission to check
|
||||||
|
*
|
||||||
* @return bool True when this subscriber has the permission and false otherwise
|
* @return bool True when this subscriber has the permission and false otherwise
|
||||||
*/
|
*/
|
||||||
public function has_permission(string $permission): bool {
|
public function has_permission(string $permission): bool {
|
||||||
@@ -378,6 +423,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the array of permissions this subscriber has been assigned.
|
* Returns the array of permissions this subscriber has been assigned.
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_permissions(): array {
|
public function get_permissions(): array {
|
||||||
@@ -388,6 +434,7 @@ class subscriber {
|
|||||||
* Returns the domain name used.
|
* Returns the domain name used.
|
||||||
* <p>Note:<br>
|
* <p>Note:<br>
|
||||||
* This value is not validated in the object and must be validated.</p>
|
* This value is not validated in the object and must be validated.</p>
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_domain_name(): string {
|
public function get_domain_name(): string {
|
||||||
@@ -395,8 +442,9 @@ class subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current socket resource used to communicate with this subscriber
|
* Returns the associated socket
|
||||||
* @return resource|stream Resource Id or stream used
|
*
|
||||||
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function socket() {
|
public function socket() {
|
||||||
return $this->socket;
|
return $this->socket;
|
||||||
@@ -404,6 +452,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the socket ID that was cast to an integer when the object was created.
|
* Returns the socket ID that was cast to an integer when the object was created.
|
||||||
|
*
|
||||||
* @return int The socket ID cast as an integer.
|
* @return int The socket ID cast as an integer.
|
||||||
*/
|
*/
|
||||||
public function socket_id(): int {
|
public function socket_id(): int {
|
||||||
@@ -412,7 +461,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the given token against the loaded token in the this subscriber
|
* Validates the given token against the loaded token in the this subscriber
|
||||||
|
*
|
||||||
* @param array $token Must be an associative array with name and hash as the keys.
|
* @param array $token Must be an associative array with name and hash as the keys.
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function is_valid_token(array $token): bool {
|
public function is_valid_token(array $token): bool {
|
||||||
@@ -456,7 +507,9 @@ class subscriber {
|
|||||||
* Validates the given token array against the token previously saved in the file system. When the token is valid
|
* Validates the given token array against the token previously saved in the file system. When the token is valid
|
||||||
* the token will be saved in this object and the file removed. This method should not be called a second time
|
* the token will be saved in this object and the file removed. This method should not be called a second time
|
||||||
* once a token has be authenticated.
|
* once a token has be authenticated.
|
||||||
|
*
|
||||||
* @param array $request_token
|
* @param array $request_token
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function authenticate_token(array $request_token): bool {
|
public function authenticate_token(array $request_token): bool {
|
||||||
@@ -486,9 +539,9 @@ class subscriber {
|
|||||||
$array = include($token_file);
|
$array = include($token_file);
|
||||||
|
|
||||||
// Assign to local variables to reflect local storage
|
// Assign to local variables to reflect local storage
|
||||||
$token_name = $array['token']['name'] ?? '';
|
$token_name = $array['token']['name'] ?? '';
|
||||||
$token_hash = $array['token']['hash'] ?? '';
|
$token_hash = $array['token']['hash'] ?? '';
|
||||||
$token_time = intval($array['token']['time'] ?? 0);
|
$token_time = intval($array['token']['time'] ?? 0);
|
||||||
$token_limit = intval($array['token']['limit'] ?? 0);
|
$token_limit = intval($array['token']['limit'] ?? 0);
|
||||||
|
|
||||||
// Compare the token given in the request with the one that was in local storage
|
// Compare the token given in the request with the one that was in local storage
|
||||||
@@ -504,11 +557,11 @@ class subscriber {
|
|||||||
if ($valid) {
|
if ($valid) {
|
||||||
|
|
||||||
// Store the valid token information in this object
|
// Store the valid token information in this object
|
||||||
$this->token_name = $token_name;
|
$this->token_name = $token_name;
|
||||||
$this->token_hash = $token_hash;
|
$this->token_hash = $token_hash;
|
||||||
$this->token_time = $token_time;
|
$this->token_time = $token_time;
|
||||||
$this->enable_token_time_limit = $token_limit > 0;
|
$this->enable_token_time_limit = $token_limit > 0;
|
||||||
$this->token_limit = $token_limit * 60; // convert to seconds for time() comparison
|
$this->token_limit = $token_limit * 60; // convert to seconds for time() comparison
|
||||||
|
|
||||||
// Add the domain
|
// Add the domain
|
||||||
$this->domain_name = $array['domain']['name'] ?? '';
|
$this->domain_name = $array['domain']['name'] ?? '';
|
||||||
@@ -534,7 +587,7 @@ class subscriber {
|
|||||||
//
|
//
|
||||||
// Set the service information in the object
|
// Set the service information in the object
|
||||||
//
|
//
|
||||||
$this->service_name = "" . ($array['service_name'] ?? '');
|
$this->service_name = "" . ($array['service_name'] ?? '');
|
||||||
$this->service_class = "" . ($array['service_class'] ?? '');
|
$this->service_class = "" . ($array['service_class'] ?? '');
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -565,6 +618,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not this subscriber has been authenticated.
|
* Returns whether or not this subscriber has been authenticated.
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function is_authenticated(): bool {
|
public function is_authenticated(): bool {
|
||||||
@@ -573,7 +627,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows overriding the token authentication
|
* Allows overriding the token authentication
|
||||||
|
*
|
||||||
* @param bool $authenticated
|
* @param bool $authenticated
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function set_authenticated(bool $authenticated): self {
|
public function set_authenticated(bool $authenticated): self {
|
||||||
@@ -583,12 +639,14 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the domain UUID and name
|
* Sets the domain UUID and name
|
||||||
|
*
|
||||||
* @param string $uuid
|
* @param string $uuid
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
* @throws invalid_uuid_exception
|
* @throws invalid_uuid_exception
|
||||||
* @depends is_uuid()
|
* @depends is_uuid()
|
||||||
* @see is_uuid()
|
* @see is_uuid()
|
||||||
*/
|
*/
|
||||||
public function set_domain(string $uuid, string $name): self {
|
public function set_domain(string $uuid, string $name): self {
|
||||||
if (is_uuid($uuid)) {
|
if (is_uuid($uuid)) {
|
||||||
@@ -602,6 +660,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not this subscriber is a service.
|
* Returns whether or not this subscriber is a service.
|
||||||
|
*
|
||||||
* @return bool True if this subscriber is a service and false if this subscriber is not a service.
|
* @return bool True if this subscriber is a service and false if this subscriber is not a service.
|
||||||
*/
|
*/
|
||||||
public function is_service(): bool {
|
public function is_service(): bool {
|
||||||
@@ -610,6 +669,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias of service_name without the parameters
|
* Alias of service_name without the parameters
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get_service_name(): string {
|
public function get_service_name(): string {
|
||||||
@@ -618,7 +678,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or set the service_name
|
* Get or set the service_name
|
||||||
|
*
|
||||||
* @param string|null $service_name
|
* @param string|null $service_name
|
||||||
|
*
|
||||||
* @return string|$this
|
* @return string|$this
|
||||||
*/
|
*/
|
||||||
public function service_name($service_name = null) { /* : string|self */
|
public function service_name($service_name = null) { /* : string|self */
|
||||||
@@ -631,7 +693,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the service name matches this subscriber
|
* Returns whether or not the service name matches this subscriber
|
||||||
|
*
|
||||||
* @param string $service_name Name of the service
|
* @param string $service_name Name of the service
|
||||||
|
*
|
||||||
* @return bool True if this subscriber matches the provided service name. False if this subscriber does not
|
* @return bool True if this subscriber matches the provided service name. False if this subscriber does not
|
||||||
* match or this subscriber is not a service.
|
* match or this subscriber is not a service.
|
||||||
*/
|
*/
|
||||||
@@ -641,6 +705,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the socket/stream is still open (not at EOF).
|
* Returns true if the socket/stream is still open (not at EOF).
|
||||||
|
*
|
||||||
* @return bool Returns true if connected and false if the connection has closed
|
* @return bool Returns true if connected and false if the connection has closed
|
||||||
*/
|
*/
|
||||||
public function is_connected(): bool {
|
public function is_connected(): bool {
|
||||||
@@ -649,6 +714,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the subscriber is no longer connected
|
* Returns true if the subscriber is no longer connected
|
||||||
|
*
|
||||||
* @return bool Returns true if the subscriber is no longer connected
|
* @return bool Returns true if the subscriber is no longer connected
|
||||||
*/
|
*/
|
||||||
public function is_not_connected(): bool {
|
public function is_not_connected(): bool {
|
||||||
@@ -657,7 +723,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this subscriber is subscribed to the given service name
|
* Checks if this subscriber is subscribed to the given service name
|
||||||
|
*
|
||||||
* @param string $service_name The service name ie. active.calls
|
* @param string $service_name The service name ie. active.calls
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
* @see subscriber::subscribe
|
* @see subscriber::subscribe
|
||||||
*/
|
*/
|
||||||
@@ -667,7 +735,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to a service by ensuring this subscriber has the appropriate permissions
|
* Subscribe to a service by ensuring this subscriber has the appropriate permissions
|
||||||
|
*
|
||||||
* @param string $service_name
|
* @param string $service_name
|
||||||
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function subscribe(string $service_name): self {
|
public function subscribe(string $service_name): self {
|
||||||
@@ -677,7 +747,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a response to the subscriber using the provided callback web socket wrapper in the constructor
|
* Sends a response to the subscriber using the provided callback web socket wrapper in the constructor
|
||||||
|
*
|
||||||
* @param string $json Valid JSON response to send to the connected client
|
* @param string $json Valid JSON response to send to the connected client
|
||||||
|
*
|
||||||
* @throws subscriber_token_expired_exception Thrown when the time limit set in the token has expired
|
* @throws subscriber_token_expired_exception Thrown when the time limit set in the token has expired
|
||||||
*/
|
*/
|
||||||
public function send(string $json) {
|
public function send(string $json) {
|
||||||
@@ -691,7 +763,9 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the given message through the websocket
|
* Sends the given message through the websocket
|
||||||
|
*
|
||||||
* @param websocket_message $message
|
* @param websocket_message $message
|
||||||
|
*
|
||||||
* @throws socket_disconnected_exception
|
* @throws socket_disconnected_exception
|
||||||
*/
|
*/
|
||||||
public function send_message(websocket_message $message) {
|
public function send_message(websocket_message $message) {
|
||||||
@@ -716,17 +790,21 @@ class subscriber {
|
|||||||
throw new \socket_disconnected_exception($this->id);
|
throw new \socket_disconnected_exception($this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->send((string) $message);
|
$this->send((string)$message);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The remote information is retrieved using the stream_socket_get_name function.
|
* The remote information is retrieved using the stream_socket_get_name function.
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @return array Returns a zero-based indexed array of first the IP address and then the port of the remote machine.
|
*
|
||||||
* @see stream_socket_get_name();
|
* @return array Returns a zero-based indexed array of first the IP address and then the port of the remote
|
||||||
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return information.
|
* machine.
|
||||||
|
* @see stream_socket_get_name();
|
||||||
|
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return
|
||||||
|
* information.
|
||||||
*/
|
*/
|
||||||
public static function get_remote_information_from_socket($socket): array {
|
public static function get_remote_information_from_socket($socket): array {
|
||||||
return explode(':', stream_socket_get_name($socket, true), 2);
|
return explode(':', stream_socket_get_name($socket, true), 2);
|
||||||
@@ -734,10 +812,13 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The remote information is retrieved using the stream_socket_get_name function.
|
* The remote information is retrieved using the stream_socket_get_name function.
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
* @return string Returns the IP address of the remote machine or an empty string.
|
* @return string Returns the IP address of the remote machine or an empty string.
|
||||||
* @see stream_socket_get_name();
|
* @see stream_socket_get_name();
|
||||||
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return information.
|
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return
|
||||||
|
* information.
|
||||||
*/
|
*/
|
||||||
public static function get_remote_ip_from_socket($socket): string {
|
public static function get_remote_ip_from_socket($socket): string {
|
||||||
$array = explode(':', stream_socket_get_name($socket, true), 2);
|
$array = explode(':', stream_socket_get_name($socket, true), 2);
|
||||||
@@ -746,10 +827,13 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The remote information is retrieved using the stream_socket_get_name function.
|
* The remote information is retrieved using the stream_socket_get_name function.
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
* @return string Returns the port of the remote machine as a string or an empty string.
|
* @return string Returns the port of the remote machine as a string or an empty string.
|
||||||
* @see stream_socket_get_name();
|
* @see stream_socket_get_name();
|
||||||
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return information.
|
* @link https://php.net/stream_socket_get_name PHP documentation for underlying function used to return
|
||||||
|
* information.
|
||||||
*/
|
*/
|
||||||
public static function get_remote_port_from_socket($socket): string {
|
public static function get_remote_port_from_socket($socket): string {
|
||||||
$array = explode(':', stream_socket_get_name($socket, true), 2);
|
$array = explode(':', stream_socket_get_name($socket, true), 2);
|
||||||
@@ -760,10 +844,13 @@ class subscriber {
|
|||||||
* Returns the name and path for the token.
|
* Returns the name and path for the token.
|
||||||
* Priority is given to the /dev/shm folder if it exists as this is much faster. If that is not available, then the
|
* Priority is given to the /dev/shm folder if it exists as this is much faster. If that is not available, then the
|
||||||
* sys_get_temp_dir() function is called to get a storage location.
|
* sys_get_temp_dir() function is called to get a storage location.
|
||||||
|
*
|
||||||
* @param string $token_name
|
* @param string $token_name
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @see sys_get_temp_dir()
|
* @see sys_get_temp_dir()
|
||||||
* @link https://php.net/sys_get_temp_dir PHP Documentation for the function used to get the temporary storage location.
|
* @link https://php.net/sys_get_temp_dir PHP Documentation for the function used to get the temporary storage
|
||||||
|
* location.
|
||||||
*/
|
*/
|
||||||
public static function get_token_file($token_name): string {
|
public static function get_token_file($token_name): string {
|
||||||
// Try to store in RAM first
|
// Try to store in RAM first
|
||||||
@@ -787,9 +874,10 @@ class subscriber {
|
|||||||
* the web socket service may not yet have access to the token before the
|
* the web socket service may not yet have access to the token before the
|
||||||
* web socket client requests authorization.
|
* web socket client requests authorization.
|
||||||
*
|
*
|
||||||
* @param array $token Standard token issued from the token object
|
* @param array $token Standard token issued from the token object
|
||||||
* @param array $services A simple array list of service names to subscribe to
|
* @param array $services A simple array list of service names to subscribe to
|
||||||
* @param int $time_limit_in_minutes Set a token time limit. Setting to zero will disable the time limit
|
* @param int $time_limit_in_minutes Set a token time limit. Setting to zero will disable the time limit
|
||||||
|
*
|
||||||
* @see token::create()
|
* @see token::create()
|
||||||
*/
|
*/
|
||||||
public static function save_token(array $token, array $services, int $time_limit_in_minutes = 0) {
|
public static function save_token(array $token, array $services, int $time_limit_in_minutes = 0) {
|
||||||
@@ -813,7 +901,7 @@ class subscriber {
|
|||||||
//
|
//
|
||||||
// Store the epoch time and time limit
|
// Store the epoch time and time limit
|
||||||
//
|
//
|
||||||
$array['token']['time'] = "" . time();
|
$array['token']['time'] = "" . time();
|
||||||
$array['token']['limit'] = $time_limit_in_minutes;
|
$array['token']['limit'] = $time_limit_in_minutes;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -839,6 +927,7 @@ class subscriber {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the token time stored in this subscriber
|
* Checks the token time stored in this subscriber
|
||||||
|
*
|
||||||
* @return bool True if the token has expired. False if the token is still valid
|
* @return bool True if the token has expired. False if the token is still valid
|
||||||
*/
|
*/
|
||||||
public function token_time_exceeded(): bool {
|
public function token_time_exceeded(): bool {
|
||||||
|
|||||||
@@ -33,6 +33,17 @@
|
|||||||
*/
|
*/
|
||||||
class subscriber_exception extends \Exception {
|
class subscriber_exception extends \Exception {
|
||||||
public $subscriber_id;
|
public $subscriber_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of the class.
|
||||||
|
*
|
||||||
|
* @param mixed $subscriber_id The subscriber's ID.
|
||||||
|
* @param string $message [optional] The exception message. Defaults to an empty string.
|
||||||
|
* @param int $code [optional] The user-defined errorCode integer. Defaults to 0.
|
||||||
|
* @param Throwable|null $previous [optional] The previous throwable that caused this one, or null if none. Defaults to null.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function __construct($subscriber_id, string $message = "", int $code = 0, ?\Throwable $previous = null) {
|
public function __construct($subscriber_id, string $message = "", int $code = 0, ?\Throwable $previous = null) {
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
$this->subscriber_id = $subscriber_id;
|
$this->subscriber_id = $subscriber_id;
|
||||||
|
|||||||
@@ -32,6 +32,16 @@
|
|||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
*/
|
*/
|
||||||
class subscriber_missing_permission_exception extends \subscriber_exception {
|
class subscriber_missing_permission_exception extends \subscriber_exception {
|
||||||
|
/**
|
||||||
|
* Initializes the object with subscriber id and error message.
|
||||||
|
*
|
||||||
|
* @param string|int $subscriber_id Subscriber's unique identifier
|
||||||
|
* @param string $message [optional] Custom error message. Defaults to "Subscriber is missing required permission".
|
||||||
|
* @param int $code [optional] Error code. Defaults to 0.
|
||||||
|
* @param \Throwable|null $previous [optional] The previous exception. Defaults to null.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function __construct($subscriber_id, string $message = "Subscriber is missing required permission", int $code = 0, ?\Throwable $previous = null) {
|
public function __construct($subscriber_id, string $message = "Subscriber is missing required permission", int $code = 0, ?\Throwable $previous = null) {
|
||||||
return parent::__construct($subscriber_id, $message, $code, $previous);
|
return parent::__construct($subscriber_id, $message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,14 @@
|
|||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
*/
|
*/
|
||||||
class subscriber_not_subscribed_exception extends subscriber_exception {
|
class subscriber_not_subscribed_exception extends subscriber_exception {
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of the class with the specified subscriber ID and message.
|
||||||
|
*
|
||||||
|
* @param string|int $subscriber_id The identifier for the subscriber.
|
||||||
|
* @param string $message The error message. Defaults to "Subscriber is not subscribed".
|
||||||
|
* @param int $code The HTTP status code. Defaults to 0.
|
||||||
|
* @param \Throwable|null $previous The previous exception, if any.
|
||||||
|
*/
|
||||||
public function __construct($subscriber_id, string $message = "Subscriber is not subscribed", int $code = 0, ?\Throwable $previous = null) {
|
public function __construct($subscriber_id, string $message = "Subscriber is not subscribed", int $code = 0, ?\Throwable $previous = null) {
|
||||||
parent::__construct($subscriber_id, $message, $code, $previous);
|
parent::__construct($subscriber_id, $message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,19 @@
|
|||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
*/
|
*/
|
||||||
class subscriber_token_expired_exception extends \subscriber_exception {
|
class subscriber_token_expired_exception extends \subscriber_exception {
|
||||||
|
/**
|
||||||
|
* Constructor for the class.
|
||||||
|
*
|
||||||
|
* Initializes a new instance of the class with optional subscriber ID, message,
|
||||||
|
* code, and previous exception information.
|
||||||
|
*
|
||||||
|
* @param string|null $subscriber_id Optional subscriber ID.
|
||||||
|
* @param string $message The error message. Defaults to "Subscriber token expired".
|
||||||
|
* @param int $code The HTTP status code. Defaults to 0.
|
||||||
|
* @param \Throwable|null $previous The previous exception. Defaults to null.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function __construct($subscriber_id = null, string $message = "Subscriber token expired", int $code = 0, ?\Throwable $previous = null) {
|
public function __construct($subscriber_id = null, string $message = "Subscriber token expired", int $code = 0, ?\Throwable $previous = null) {
|
||||||
return parent::__construct($subscriber_id, $message, $code, $previous);
|
return parent::__construct($subscriber_id, $message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ class websocket_client {
|
|||||||
* Connects to the WebSocket server and performs handshake.
|
* Connects to the WebSocket server and performs handshake.
|
||||||
*/
|
*/
|
||||||
public function connect(): void {
|
public function connect(): void {
|
||||||
$parts = parse_url($this->url);
|
$parts = parse_url($this->url);
|
||||||
$this->host = $parts['host'] ?? '';
|
$this->host = $parts['host'] ?? '';
|
||||||
$this->port = $parts['port'] ?? 80;
|
$this->port = $parts['port'] ?? 80;
|
||||||
$this->path = $parts['path'] ?? '/';
|
$this->path = $parts['path'] ?? '/';
|
||||||
$this->origin = ($parts['scheme'] ?? 'http') . '://' . $this->host;
|
$this->origin = ($parts['scheme'] ?? 'http') . '://' . $this->host;
|
||||||
|
|
||||||
$this->resource = stream_socket_client("tcp://{$this->host}:{$this->port}", $errno, $errstr, 5);
|
$this->resource = stream_socket_client("tcp://{$this->host}:{$this->port}", $errno, $errstr, 5);
|
||||||
@@ -100,7 +100,7 @@ class websocket_client {
|
|||||||
if (!preg_match('/Sec-WebSocket-Accept: (.*)\r\n/', $response, $m)) {
|
if (!preg_match('/Sec-WebSocket-Accept: (.*)\r\n/', $response, $m)) {
|
||||||
throw new \RuntimeException("Handshake failed: no Accept header");
|
throw new \RuntimeException("Handshake failed: no Accept header");
|
||||||
}
|
}
|
||||||
$accept = trim($m[1]);
|
$accept = trim($m[1]);
|
||||||
$expected = base64_encode(sha1($this->key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
|
$expected = base64_encode(sha1($this->key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
|
||||||
if ($accept !== $expected) {
|
if ($accept !== $expected) {
|
||||||
throw new \RuntimeException("Handshake failed: invalid Accept key");
|
throw new \RuntimeException("Handshake failed: invalid Accept key");
|
||||||
@@ -112,19 +112,47 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blocking mode of the underlying socket.
|
||||||
|
*
|
||||||
|
* @param bool $block If true, sets the socket to block on read/write operations; otherwise, sets it to non-blocking.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function set_blocking(bool $block) {
|
public function set_blocking(bool $block) {
|
||||||
if ($this->is_connected())
|
if ($this->is_connected())
|
||||||
stream_set_blocking($this->resource, $block);
|
stream_set_blocking($this->resource, $block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file descriptor to be in blocking mode.
|
||||||
|
*
|
||||||
|
* This ensures that any write operations on this socket will block until the entire data has been sent.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function block() {
|
public function block() {
|
||||||
$this->set_blocking(true);
|
$this->set_blocking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables blocking mode for this resource.
|
||||||
|
*
|
||||||
|
* This method sets the resource to non-blocking mode, allowing I/O operations to complete immediately
|
||||||
|
* without waiting for completion. If an operation is attempted while in non-blocking mode and no data
|
||||||
|
* is available, a BlockingQueueException will be raised.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function unblock() {
|
public function unblock() {
|
||||||
$this->set_blocking(false);
|
$this->set_blocking(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the underlying socket is in a non-blocking state.
|
||||||
|
*
|
||||||
|
* @return bool True if the socket is blocking, false otherwise.
|
||||||
|
*/
|
||||||
public function is_blocking(): bool {
|
public function is_blocking(): bool {
|
||||||
if ($this->is_connected()) {
|
if ($this->is_connected()) {
|
||||||
//
|
//
|
||||||
@@ -141,7 +169,9 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if socket is connected.
|
* Checks if a connection to the web socket server is established and active.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function is_connected(): bool {
|
public function is_connected(): bool {
|
||||||
return isset($this->resource) && is_resource($this->resource) && !feof($this->resource);
|
return isset($this->resource) && is_resource($this->resource) && !feof($this->resource);
|
||||||
@@ -150,7 +180,13 @@ class websocket_client {
|
|||||||
/**
|
/**
|
||||||
* Sends text to the web socket server.
|
* Sends text to the web socket server.
|
||||||
* The web socket client wraps the payload in a web frame socket before sending on the socket.
|
* The web socket client wraps the payload in a web frame socket before sending on the socket.
|
||||||
|
*
|
||||||
|
* @param $resource
|
||||||
* @param string|null $payload
|
* @param string|null $payload
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws \Random\RandomException
|
||||||
|
* @throws \socket_disconnected_exception
|
||||||
*/
|
*/
|
||||||
public static function send($resource, ?string $payload): bool {
|
public static function send($resource, ?string $payload): bool {
|
||||||
if (!is_resource($resource)) {
|
if (!is_resource($resource)) {
|
||||||
@@ -164,7 +200,7 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$frame_header = "\x81"; // FIN=1, opcode=1 (text frame)
|
$frame_header = "\x81"; // FIN=1, opcode=1 (text frame)
|
||||||
$length = strlen($payload);
|
$length = strlen($payload);
|
||||||
|
|
||||||
// Set mask bit and payload length
|
// Set mask bit and payload length
|
||||||
if ($length <= 125) {
|
if ($length <= 125) {
|
||||||
@@ -176,7 +212,7 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// must be masked when sending to the server
|
// must be masked when sending to the server
|
||||||
$mask = random_bytes(4);
|
$mask = random_bytes(4);
|
||||||
$masked_payload = '';
|
$masked_payload = '';
|
||||||
|
|
||||||
for ($i = 0; $i < $length; ++$i) {
|
for ($i = 0; $i < $length; ++$i) {
|
||||||
@@ -210,6 +246,17 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a file path for a token.
|
||||||
|
*
|
||||||
|
* Tries to store in RAM first, otherwise uses the filesystem.
|
||||||
|
*
|
||||||
|
* @param string $token_name The name of the token.
|
||||||
|
*
|
||||||
|
* @return string The file path for the token.
|
||||||
|
* @see \sys_get_temp_dir()
|
||||||
|
* @link https://php.net/sys_get_temp_dir
|
||||||
|
*/
|
||||||
public static function get_token_file($token_name): string {
|
public static function get_token_file($token_name): string {
|
||||||
// Try to store in RAM first
|
// Try to store in RAM first
|
||||||
if (is_dir('/dev/shm') && is_writable('/dev/shm')) {
|
if (is_dir('/dev/shm') && is_writable('/dev/shm')) {
|
||||||
@@ -221,8 +268,18 @@ class websocket_client {
|
|||||||
return $token_file;
|
return $token_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a control frame over the WebSocket connection.
|
||||||
|
*
|
||||||
|
* This method sends a FIN=1 (final fragment) control frame with the given opcode and payload.
|
||||||
|
*
|
||||||
|
* @param int $opcode The opcode for the control frame.
|
||||||
|
* @param string $payload The payload to send, default is an empty string.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function send_control_frame(int $opcode, string $payload = ''): void {
|
private function send_control_frame(int $opcode, string $payload = ''): void {
|
||||||
$header = chr(0x80 | $opcode); // FIN=1, control frame
|
$header = chr(0x80 | $opcode); // FIN=1, control frame
|
||||||
$payload_len = strlen($payload);
|
$payload_len = strlen($payload);
|
||||||
|
|
||||||
// Payload length
|
// Payload length
|
||||||
@@ -233,7 +290,7 @@ class websocket_client {
|
|||||||
} else {
|
} else {
|
||||||
// Control frames should never be this large; truncate to 125
|
// Control frames should never be this large; truncate to 125
|
||||||
$payload = substr($payload, 0, 125);
|
$payload = substr($payload, 0, 125);
|
||||||
$header .= chr(125);
|
$header .= chr(125);
|
||||||
}
|
}
|
||||||
|
|
||||||
@fwrite($this->resource, $header . $payload);
|
@fwrite($this->resource, $header . $payload);
|
||||||
@@ -241,7 +298,9 @@ class websocket_client {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a web socket data frame and converts it to a regular string
|
* Reads a web socket data frame and converts it to a regular string
|
||||||
* @param resource $this->resource
|
*
|
||||||
|
* @param resource $this ->resource
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function read(): ?string {
|
public function read(): ?string {
|
||||||
@@ -249,7 +308,7 @@ class websocket_client {
|
|||||||
throw new \RuntimeException("Not connected");
|
throw new \RuntimeException("Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
$final_frame = false;
|
$final_frame = false;
|
||||||
$payload_data = '';
|
$payload_data = '';
|
||||||
|
|
||||||
while (!$final_frame) {
|
while (!$final_frame) {
|
||||||
@@ -262,8 +321,8 @@ class websocket_client {
|
|||||||
$byte2 = ord($header[1]);
|
$byte2 = ord($header[1]);
|
||||||
|
|
||||||
$final_frame = ($byte1 >> 7) & 1;
|
$final_frame = ($byte1 >> 7) & 1;
|
||||||
$opcode = $byte1 & 0x0F;
|
$opcode = $byte1 & 0x0F;
|
||||||
$masked = ($byte2 >> 7) & 1;
|
$masked = ($byte2 >> 7) & 1;
|
||||||
$payload_len = $byte2 & 0x7F;
|
$payload_len = $byte2 & 0x7F;
|
||||||
|
|
||||||
// Extended payload length
|
// Extended payload length
|
||||||
@@ -335,8 +394,16 @@ class websocket_client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to fully read N bytes
|
// Helper function to fully read N bytes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads up to the specified number of bytes from the underlying resource.
|
||||||
|
*
|
||||||
|
* @param int $length The maximum number of bytes to read.
|
||||||
|
*
|
||||||
|
* @return string|null The requested data, or null on error.
|
||||||
|
*/
|
||||||
private function read_bytes(int $length): ?string {
|
private function read_bytes(int $length): ?string {
|
||||||
$data = '';
|
$data = '';
|
||||||
$max_chunk_size = stream_get_chunk_size($this->resource);
|
$max_chunk_size = stream_get_chunk_size($this->resource);
|
||||||
|
|
||||||
// 20 tries waits 200 ms total per chunk
|
// 20 tries waits 200 ms total per chunk
|
||||||
@@ -376,16 +443,26 @@ class websocket_client {
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an authentication request to the server.
|
||||||
|
*
|
||||||
|
* @param string $token_name The name of the token to authenticate with.
|
||||||
|
* @param string $token_hash The hash of the token to authenticate with.
|
||||||
|
*
|
||||||
|
* @return mixed|null The response from the server, or null on error.
|
||||||
|
*/
|
||||||
public function authenticate($token_name, $token_hash) {
|
public function authenticate($token_name, $token_hash) {
|
||||||
return self::send($this->resource, json_encode(['service' => 'authentication', 'token' => ['name' => $token_name, 'hash' => $token_hash]]));
|
return self::send($this->resource, json_encode(['service' => 'authentication', 'token' => ['name' => $token_name, 'hash' => $token_hash]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a token for a service that can broadcast a message
|
* Create a token for a service that can broadcast a message
|
||||||
|
*
|
||||||
* @param string $service_name
|
* @param string $service_name
|
||||||
* @param string $service_class
|
* @param string $service_class
|
||||||
* @param array $permissions
|
* @param array $permissions
|
||||||
* @param int $time_limit_in_minutes
|
* @param int $time_limit_in_minutes
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function create_service_token(string $service_name, string $service_class, array $permissions = [], int $time_limit_in_minutes = 0) {
|
public static function create_service_token(string $service_name, string $service_class, array $permissions = [], int $time_limit_in_minutes = 0) {
|
||||||
@@ -410,15 +487,15 @@ class websocket_client {
|
|||||||
//
|
//
|
||||||
// Store the epoch time and time limit
|
// Store the epoch time and time limit
|
||||||
//
|
//
|
||||||
$array['token']['time'] = "" . time();
|
$array['token']['time'] = "" . time();
|
||||||
$array['token']['limit'] = $time_limit_in_minutes;
|
$array['token']['limit'] = $time_limit_in_minutes;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Store the service name used by web browser to subscribe
|
// Store the service name used by web browser to subscribe
|
||||||
// and store the class name of this service
|
// and store the class name of this service
|
||||||
//
|
//
|
||||||
$array['service'] = true;
|
$array['service'] = true;
|
||||||
$array['service_name'] = $service_name;
|
$array['service_name'] = $service_name;
|
||||||
$array['service_class'] = $service_class;
|
$array['service_class'] = $service_class;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -441,6 +518,14 @@ class websocket_client {
|
|||||||
|
|
||||||
// PHP <=7.4 compatibility - Replaced in PHP 8.0+
|
// PHP <=7.4 compatibility - Replaced in PHP 8.0+
|
||||||
if (!function_exists('stream_get_chunk_size')) {
|
if (!function_exists('stream_get_chunk_size')) {
|
||||||
|
/**
|
||||||
|
* Returns the recommended chunk size for reading data from a stream.
|
||||||
|
*
|
||||||
|
* @param resource $stream The stream to retrieve the chunk size for.
|
||||||
|
*
|
||||||
|
* @return int The recommended chunk size.
|
||||||
|
* @link https://php.net/stream_get_chunk_size
|
||||||
|
*/
|
||||||
function stream_get_chunk_size($stream): int {
|
function stream_get_chunk_size($stream): int {
|
||||||
// For PHP versions lower then 8 we send the maximum size defined from https://php.net/stream_get_chunk_size
|
// For PHP versions lower then 8 we send the maximum size defined from https://php.net/stream_get_chunk_size
|
||||||
return 8192;
|
return 8192;
|
||||||
|
|||||||
@@ -29,17 +29,18 @@
|
|||||||
/**
|
/**
|
||||||
* A structured web socket message easily converted to and from a json string
|
* A structured web socket message easily converted to and from a json string
|
||||||
*
|
*
|
||||||
|
* @param string $service_name ;
|
||||||
|
* @param string $token_name ;
|
||||||
|
* @param string $token_hash ;
|
||||||
|
* @param string $status_string ;
|
||||||
|
* @param string $status_code ;
|
||||||
|
* @param string $request_id ;
|
||||||
|
* @param string $resource_id ;
|
||||||
|
* @param string $domain_uuid ;
|
||||||
|
* @param string $permissions ;
|
||||||
|
* @param string $topic ;
|
||||||
|
*
|
||||||
* @author Tim Fry <tim@fusionpbx.com>
|
* @author Tim Fry <tim@fusionpbx.com>
|
||||||
* @param string $service_name;
|
|
||||||
* @param string $token_name;
|
|
||||||
* @param string $token_hash;
|
|
||||||
* @param string $status_string;
|
|
||||||
* @param string $status_code;
|
|
||||||
* @param string $request_id;
|
|
||||||
* @param string $resource_id;
|
|
||||||
* @param string $domain_uuid;
|
|
||||||
* @param string $permissions;
|
|
||||||
* @param string $topic;
|
|
||||||
*/
|
*/
|
||||||
class websocket_message extends base_message {
|
class websocket_message extends base_message {
|
||||||
|
|
||||||
@@ -58,30 +59,39 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
public function __construct($associative_properties_array = []) {
|
public function __construct($associative_properties_array = []) {
|
||||||
// Initialize empty default values
|
// Initialize empty default values
|
||||||
$this->service_name = '';
|
$this->service_name = '';
|
||||||
$this->token_name = '';
|
$this->token_name = '';
|
||||||
$this->token_hash = '';
|
$this->token_hash = '';
|
||||||
$this->status_string = '';
|
$this->status_string = '';
|
||||||
$this->status_code = '';
|
$this->status_code = '';
|
||||||
$this->request_id = '';
|
$this->request_id = '';
|
||||||
$this->resource_id = '';
|
$this->resource_id = '';
|
||||||
$this->domain_uuid = '';
|
$this->domain_uuid = '';
|
||||||
$this->domain_name = '';
|
$this->domain_name = '';
|
||||||
$this->permissions = [];
|
$this->permissions = [];
|
||||||
$this->topic = '';
|
$this->topic = '';
|
||||||
//
|
//
|
||||||
// Send to parent (base_message) constructor
|
// Send to parent (base_message) constructor
|
||||||
//
|
//
|
||||||
parent::__construct($associative_properties_array);
|
parent::__construct($associative_properties_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a permission is granted to this service.
|
||||||
|
*
|
||||||
|
* @param string $permission_name The name of the permission to check for.
|
||||||
|
*
|
||||||
|
* @return bool True if the permission is granted, false otherwise.
|
||||||
|
*/
|
||||||
public function has_permission($permission_name) {
|
public function has_permission($permission_name) {
|
||||||
return isset($this->permissions[$permission_name]);
|
return isset($this->permissions[$permission_name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias of service_name.
|
* Alias of service_name.
|
||||||
|
*
|
||||||
* @param string $service_name
|
* @param string $service_name
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
* @see service_name
|
* @see service_name
|
||||||
*/
|
*/
|
||||||
@@ -97,7 +107,9 @@ class websocket_message extends base_message {
|
|||||||
* Gets or Sets the service name
|
* Gets or Sets the service name
|
||||||
* If no parameters are provided then the service_name is returned. If the service name is provided, then the
|
* If no parameters are provided then the service_name is returned. If the service name is provided, then the
|
||||||
* service_name is set to the value provided.
|
* service_name is set to the value provided.
|
||||||
|
*
|
||||||
* @param string $service_name
|
* @param string $service_name
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function service_name($service_name = null) {
|
public function service_name($service_name = null) {
|
||||||
@@ -110,7 +122,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the permissions array
|
* Gets or sets the permissions array
|
||||||
|
*
|
||||||
* @param array $permissions
|
* @param array $permissions
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function permissions($permissions = []) {
|
public function permissions($permissions = []) {
|
||||||
@@ -124,6 +138,7 @@ class websocket_message extends base_message {
|
|||||||
/**
|
/**
|
||||||
* Applies a filter to the payload of this message.
|
* Applies a filter to the payload of this message.
|
||||||
* When a filter returns null then the payload is set to null
|
* When a filter returns null then the payload is set to null
|
||||||
|
*
|
||||||
* @param filter $filter
|
* @param filter $filter
|
||||||
*/
|
*/
|
||||||
public function apply_filter(?filter $filter) {
|
public function apply_filter(?filter $filter) {
|
||||||
@@ -134,9 +149,8 @@ class websocket_message extends base_message {
|
|||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
$this->payload = null;
|
$this->payload = null;
|
||||||
return;
|
return;
|
||||||
}
|
} // Remove a key if filter does not pass
|
||||||
// Remove a key if filter does not pass
|
elseif (!$result) {
|
||||||
elseif(!$result) {
|
|
||||||
unset($this->payload[$key]);
|
unset($this->payload[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +159,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the domain UUID
|
* Gets or sets the domain UUID
|
||||||
|
*
|
||||||
* @param string $domain_uuid
|
* @param string $domain_uuid
|
||||||
|
*
|
||||||
* @return $this or $domain_uuid
|
* @return $this or $domain_uuid
|
||||||
*/
|
*/
|
||||||
public function domain_uuid($domain_uuid = '') {
|
public function domain_uuid($domain_uuid = '') {
|
||||||
@@ -158,7 +174,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the domain name
|
* Gets or sets the domain name
|
||||||
|
*
|
||||||
* @param string $domain_name
|
* @param string $domain_name
|
||||||
|
*
|
||||||
* @return $this or $domain_name
|
* @return $this or $domain_name
|
||||||
*/
|
*/
|
||||||
public function domain_name($domain_name = '') {
|
public function domain_name($domain_name = '') {
|
||||||
@@ -173,7 +191,9 @@ class websocket_message extends base_message {
|
|||||||
* Gets or Sets the service name
|
* Gets or Sets the service name
|
||||||
* If no parameters are provided then the service_name is returned. If the service name is provided, then the
|
* If no parameters are provided then the service_name is returned. If the service name is provided, then the
|
||||||
* topic is set to the value provided.
|
* topic is set to the value provided.
|
||||||
|
*
|
||||||
* @param string $topic
|
* @param string $topic
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function topic($topic = null) {
|
public function topic($topic = null) {
|
||||||
@@ -186,7 +206,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the token array using the key values of 'name' and 'hash'
|
* Gets or sets the token array using the key values of 'name' and 'hash'
|
||||||
|
*
|
||||||
* @param array $token_array
|
* @param array $token_array
|
||||||
|
*
|
||||||
* @return array|$this
|
* @return array|$this
|
||||||
* @see token_name
|
* @see token_name
|
||||||
* @see token_hash
|
* @see token_hash
|
||||||
@@ -201,11 +223,13 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the token name
|
* Sets the token name
|
||||||
|
*
|
||||||
* @param string $token_name
|
* @param string $token_name
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
* @see token_hash
|
* @see token_hash
|
||||||
*/
|
*/
|
||||||
public function token_name($token_name = '') {
|
public function token_name($token_name = '') {
|
||||||
if (func_num_args() > 0) {
|
if (func_num_args() > 0) {
|
||||||
$this->token_name = $token_name;
|
$this->token_name = $token_name;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -215,7 +239,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the status code of this message
|
* Gets or sets the status code of this message
|
||||||
|
*
|
||||||
* @param int $status_code
|
* @param int $status_code
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function status_code($status_code = '') {
|
public function status_code($status_code = '') {
|
||||||
@@ -228,7 +254,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the resource id
|
* Gets or sets the resource id
|
||||||
* @param type $resource_id
|
*
|
||||||
|
* @param mixed $resource_id
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function resource_id($resource_id = null) {
|
public function resource_id($resource_id = null) {
|
||||||
@@ -241,7 +269,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the request ID
|
* Gets or sets the request ID
|
||||||
* @param type $request_id
|
*
|
||||||
|
* @param string $request_id
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function request_id($request_id = null) {
|
public function request_id($request_id = null) {
|
||||||
@@ -254,10 +284,12 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the status string
|
* Gets or sets the status string
|
||||||
* @param type $status_string
|
*
|
||||||
|
* @param string $status_string
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function status_string( $status_string = null) {
|
public function status_string($status_string = null) {
|
||||||
if (func_num_args() > 0) {
|
if (func_num_args() > 0) {
|
||||||
$this->status_string = $status_string;
|
$this->status_string = $status_string;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -267,7 +299,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the token hash
|
* Gets or sets the token hash
|
||||||
* @param type $token_hash
|
*
|
||||||
|
* @param string $token_hash
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
* @see token_name
|
* @see token_name
|
||||||
*/
|
*/
|
||||||
@@ -281,8 +315,10 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the 'statusString' key that comes from javascript
|
* Convert the 'statusString' key that comes from javascript
|
||||||
* @param type $status_string
|
*
|
||||||
* @return type
|
* @param string $status_string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function statusString($status_string = '') {
|
public function statusString($status_string = '') {
|
||||||
return $this->status_string($status_string);
|
return $this->status_string($status_string);
|
||||||
@@ -290,7 +326,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the 'statusCode' key that comes from javascript
|
* Convert the 'statusCode' key that comes from javascript
|
||||||
* @param type $status_code
|
*
|
||||||
|
* @param string $status_code
|
||||||
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function statusCode($status_code = 200) {
|
public function statusCode($status_code = 200) {
|
||||||
@@ -299,7 +337,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unwrap a JSON message to an associative array
|
* Unwrap a JSON message to an associative array
|
||||||
|
*
|
||||||
* @param string $json_string
|
* @param string $json_string
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function unwrap($json_string = '') {
|
public static function unwrap($json_string = '') {
|
||||||
@@ -308,7 +348,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with a connected message
|
* Helper function to respond with a connected message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function connected($request_id = ''): string {
|
public static function connected($request_id = ''): string {
|
||||||
@@ -317,7 +359,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with a authentication message
|
* Helper function to respond with a authentication message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function request_authentication($request_id = ''): string {
|
public static function request_authentication($request_id = ''): string {
|
||||||
@@ -334,9 +378,11 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with a bad request message
|
* Helper function to respond with a bad request message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
* @param string $service
|
* @param string $service
|
||||||
* @param string $topic
|
* @param string $topic
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function request_is_bad($request_id = '', string $service = '', string $topic = ''): string {
|
public static function request_is_bad($request_id = '', string $service = '', string $topic = ''): string {
|
||||||
@@ -352,28 +398,32 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with an authenticated message
|
* Helper function to respond with an authenticated message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
* @param string $service
|
* @param string $service
|
||||||
* @param string $topic
|
* @param string $topic
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function request_authenticated($request_id = '', string $service = '', string $topic = 'authenticated'): string {
|
public static function request_authenticated($request_id = '', string $service = '', string $topic = 'authenticated'): string {
|
||||||
$class = static::class;
|
$class = static::class;
|
||||||
return (new $class())
|
return (new $class())
|
||||||
->request_id($request_id)
|
->request_id($request_id)
|
||||||
->service_name($service)
|
->service_name($service)
|
||||||
->topic($topic)
|
->topic($topic)
|
||||||
->status_code(200)
|
->status_code(200)
|
||||||
->status_string('OK')
|
->status_string('OK')
|
||||||
->__toString()
|
->__toString()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with an unauthorized request message
|
* Helper function to respond with an unauthorized request message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
* @param string $service
|
* @param string $service
|
||||||
* @param string $topic
|
* @param string $topic
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function request_unauthorized($request_id = '', string $service = '', string $topic = 'unauthorized'): string {
|
public static function request_unauthorized($request_id = '', string $service = '', string $topic = 'unauthorized'): string {
|
||||||
@@ -389,9 +439,11 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to respond with a forbidden message
|
* Helper function to respond with a forbidden message
|
||||||
|
*
|
||||||
* @param string|int $request_id
|
* @param string|int $request_id
|
||||||
* @param string $service
|
* @param string $service
|
||||||
* @param string $topic
|
* @param string $topic
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function request_forbidden($request_id = '', string $service = '', string $topic = 'forbidden'): string {
|
public static function request_forbidden($request_id = '', string $service = '', string $topic = 'forbidden'): string {
|
||||||
@@ -407,7 +459,9 @@ class websocket_message extends base_message {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a websocket_message object (or child object) using the provided JSON string or JSON array
|
* Returns a websocket_message object (or child object) using the provided JSON string or JSON array
|
||||||
|
*
|
||||||
* @param string|array $websocket_message_json JSON array or JSON string
|
* @param string|array $websocket_message_json JSON array or JSON string
|
||||||
|
*
|
||||||
* @return static|null Returns a new websocket_message object (or child object)
|
* @return static|null Returns a new websocket_message object (or child object)
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -40,94 +40,133 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Address to bind to. (Default 8080)
|
* Address to bind to. (Default 8080)
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $address;
|
protected $address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $port;
|
protected $port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks if the server is running
|
* Tracks if the server is running
|
||||||
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $running;
|
protected $running;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource or stream of the server socket binding
|
* Resource or stream of the server socket binding
|
||||||
|
*
|
||||||
* @var resource|stream
|
* @var resource|stream
|
||||||
*/
|
*/
|
||||||
protected $server_socket;
|
protected $server_socket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of connected client sockets
|
* List of connected client sockets
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $clients;
|
protected $clients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_message events
|
* Used to track on_message events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $message_callbacks;
|
private $message_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_connect events
|
* Used to track on_connect events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $connect_callbacks;
|
private $connect_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_disconnect events
|
* Used to track on_disconnect events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $disconnect_callbacks;
|
private $disconnect_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track switch listeners or other socket connection types
|
* Used to track switch listeners or other socket connection types
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $listeners;
|
private $listeners;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a websocket_server instance
|
* Creates a websocket_server instance
|
||||||
|
*
|
||||||
* @param string $address IP to bind (default 0.0.0.0)
|
* @param string $address IP to bind (default 0.0.0.0)
|
||||||
* @param int $port TCP port (default 8080)
|
* @param int $port TCP port (default 8080)
|
||||||
*/
|
*/
|
||||||
public function __construct(string $address = '127.0.0.1', int $port = 8080) {
|
public function __construct(string $address = '127.0.0.1', int $port = 8080) {
|
||||||
$this->running = false;
|
$this->running = false;
|
||||||
$this->address = $address;
|
$this->address = $address;
|
||||||
$this->port = $port;
|
$this->port = $port;
|
||||||
|
|
||||||
// Initialize arrays
|
// Initialize arrays
|
||||||
$this->listeners = [];
|
$this->listeners = [];
|
||||||
$this->clients = [];
|
$this->clients = [];
|
||||||
$this->message_callbacks = [];
|
$this->message_callbacks = [];
|
||||||
$this->connect_callbacks = [];
|
$this->connect_callbacks = [];
|
||||||
$this->disconnect_callbacks = [];
|
$this->disconnect_callbacks = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a debugging message to the log handler.
|
||||||
|
*
|
||||||
|
* @param string $message The message to be logged.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function debug(string $message) {
|
private function debug(string $message) {
|
||||||
self::log($message, LOG_DEBUG);
|
self::log($message, LOG_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a warning message to the log file.
|
||||||
|
*
|
||||||
|
* @param string $message The warning message to be logged.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function warn(string $message) {
|
private function warn(string $message) {
|
||||||
self::log($message, LOG_WARNING);
|
self::log($message, LOG_WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an error message to the log file. If the logging fails for any reason, it is silently ignored and no further action is taken.
|
||||||
|
*
|
||||||
|
* @param string $message The error message to be logged.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function error(string $message) {
|
private function error(string $message) {
|
||||||
self::log($message, LOG_ERR);
|
self::log($message, LOG_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs information level message to the log handler.
|
||||||
|
*
|
||||||
|
* @param string $message The message to be logged.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function info(string $message) {
|
private function info(string $message) {
|
||||||
self::log($message, LOG_INFO);
|
self::log($message, LOG_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts server: accepts new clients, reads frames, and broadcasts messages.
|
* Starts server: accepts new clients, reads frames, and broadcasts messages.
|
||||||
|
*
|
||||||
* @returns int A non-zero indicates an abnormal termination
|
* @returns int A non-zero indicates an abnormal termination
|
||||||
*/
|
*/
|
||||||
public function run(): int {
|
public function run(): int {
|
||||||
@@ -143,8 +182,8 @@ class websocket_server {
|
|||||||
|
|
||||||
while ($this->running) {
|
while ($this->running) {
|
||||||
$listeners = array_column($this->listeners, 0);
|
$listeners = array_column($this->listeners, 0);
|
||||||
$read = array_merge([$this->server_socket], $listeners, $this->clients);
|
$read = array_merge([$this->server_socket], $listeners, $this->clients);
|
||||||
$write = $except = [];
|
$write = $except = [];
|
||||||
// Server connection issue
|
// Server connection issue
|
||||||
if (false === stream_select($read, $write, $except, null)) {
|
if (false === stream_select($read, $write, $except, null)) {
|
||||||
$this->running = false;
|
$this->running = false;
|
||||||
@@ -194,12 +233,15 @@ class websocket_server {
|
|||||||
$this->trigger_message($client_socket, $message);
|
$this->trigger_message($client_socket, $message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a non-blocking socket to listen for traffic on
|
* Add a non-blocking socket to listen for traffic on
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @param callable $on_data_ready_callback Callable function to call when data arrives on the socket
|
* @param callable $on_data_ready_callback Callable function to call when data arrives on the socket
|
||||||
|
*
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function add_listener($socket, callable $on_data_ready_callback) {
|
public function add_listener($socket, callable $on_data_ready_callback) {
|
||||||
@@ -211,6 +253,7 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if there are connected web socket clients.
|
* Returns true if there are connected web socket clients.
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function has_clients(): bool {
|
public function has_clients(): bool {
|
||||||
@@ -220,7 +263,9 @@ class websocket_server {
|
|||||||
/**
|
/**
|
||||||
* When a web socket message is received the $on_message_callback function is called.
|
* When a web socket message is received the $on_message_callback function is called.
|
||||||
* Multiple on_message functions can be specified.
|
* Multiple on_message functions can be specified.
|
||||||
|
*
|
||||||
* @param callable $on_message_callback Callable function to call when data arrives on the socket
|
* @param callable $on_message_callback Callable function to call when data arrives on the socket
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_message(callable $on_message_callback) {
|
public function on_message(callable $on_message_callback) {
|
||||||
@@ -232,8 +277,10 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_message functions
|
* Calls all the on_message functions
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @param string $message
|
* @param string $message
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function trigger_message($socket, string $message) {
|
private function trigger_message($socket, string $message) {
|
||||||
@@ -249,7 +296,9 @@ class websocket_server {
|
|||||||
/**
|
/**
|
||||||
* When a web socket handshake has completed, the $on_connect_callback function is called.
|
* When a web socket handshake has completed, the $on_connect_callback function is called.
|
||||||
* Multiple on_connect functions can be specified.
|
* Multiple on_connect functions can be specified.
|
||||||
|
*
|
||||||
* @param callable $on_connect_callback Callable function to call when a new connection occurs.
|
* @param callable $on_connect_callback Callable function to call when a new connection occurs.
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_connect(callable $on_connect_callback) {
|
public function on_connect(callable $on_connect_callback) {
|
||||||
@@ -261,7 +310,10 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_connect functions
|
* Calls all the on_connect functions
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
|
* @throws \socket_disconnected_exception
|
||||||
*/
|
*/
|
||||||
private function trigger_connect($socket) {
|
private function trigger_connect($socket) {
|
||||||
foreach ($this->connect_callbacks as $callback) {
|
foreach ($this->connect_callbacks as $callback) {
|
||||||
@@ -275,7 +327,11 @@ class websocket_server {
|
|||||||
/**
|
/**
|
||||||
* When a web socket has disconnected, the $on_disconnect_callback function is called.
|
* When a web socket has disconnected, the $on_disconnect_callback function is called.
|
||||||
* Multiple functions can be specified with subsequent calls
|
* Multiple functions can be specified with subsequent calls
|
||||||
* @param string|callable $on_disconnect_callback Callable function to call when a socket disconnects. The function must accept a single parameter for the socket that was disconnected.
|
*
|
||||||
|
* @param string|callable $on_disconnect_callback Callable function to call when a socket disconnects. The function
|
||||||
|
* must accept a single parameter for the socket that was
|
||||||
|
* disconnected.
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_disconnect($on_disconnect_callback) {
|
public function on_disconnect($on_disconnect_callback) {
|
||||||
@@ -287,7 +343,8 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_disconnect_callback functions
|
* Calls all the on_disconnect_callback functions
|
||||||
* @param type $socket
|
*
|
||||||
|
* @param resource $socket
|
||||||
*/
|
*/
|
||||||
private function trigger_disconnect($socket) {
|
private function trigger_disconnect($socket) {
|
||||||
foreach ($this->disconnect_callbacks as $callback) {
|
foreach ($this->disconnect_callbacks as $callback) {
|
||||||
@@ -297,6 +354,7 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the socket used in the server connection
|
* Returns the socket used in the server connection
|
||||||
|
*
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function get_socket() {
|
public function get_socket() {
|
||||||
@@ -304,15 +362,19 @@ class websocket_server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a client socket on disconnect.
|
* Disconnect a client from the server.
|
||||||
* @return bool Returns true on client disconnect and false when the client is not found in the tracking array
|
*
|
||||||
|
* @param resource $resource The socket or resource id of the client to disconnect.
|
||||||
|
* @param string|null $error A custom error message to send to the client, if any.
|
||||||
|
*
|
||||||
|
* @return bool True if the client was successfully disconnected, false otherwise.
|
||||||
*/
|
*/
|
||||||
protected function disconnect_client($socket, $error = null): bool {
|
protected function disconnect_client($resource, $error = null): bool {
|
||||||
$index = array_search($resource, $this->clients, true);
|
$index = array_search($resource, $this->clients, true);
|
||||||
if ($index !== false) {
|
if ($index !== false) {
|
||||||
self::disconnect($resource);
|
self::disconnect($resource);
|
||||||
unset($this->clients[$index]);
|
unset($this->clients[$index]);
|
||||||
$this->trigger_disconnect($socket);
|
$this->trigger_disconnect($resource);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -320,7 +382,8 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a disconnect frame with no payload
|
* Sends a disconnect frame with no payload
|
||||||
* @param type $resource
|
*
|
||||||
|
* @param resource $resource
|
||||||
*/
|
*/
|
||||||
public static function disconnect($resource) {
|
public static function disconnect($resource) {
|
||||||
if (is_resource($resource)) {
|
if (is_resource($resource)) {
|
||||||
@@ -332,7 +395,8 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs web socket handshake on new connection.
|
* Performs web socket handshake on new connection.
|
||||||
* @param type $socket Socket to perform the handshake on.
|
*
|
||||||
|
* @param resource $socket Socket to perform the handshake on.
|
||||||
*/
|
*/
|
||||||
protected function handshake($socket) {
|
protected function handshake($socket) {
|
||||||
// ensure blocking to read full header
|
// ensure blocking to read full header
|
||||||
@@ -347,21 +411,23 @@ class websocket_server {
|
|||||||
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request_header, $matches)) {
|
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request_header, $matches)) {
|
||||||
throw new \invalid_handshake_exception($socket, "Invalid WebSocket handshake");
|
throw new \invalid_handshake_exception($socket, "Invalid WebSocket handshake");
|
||||||
}
|
}
|
||||||
$key = trim($matches[1]);
|
$key = trim($matches[1]);
|
||||||
$accept_key = base64_encode(
|
$accept_key = base64_encode(
|
||||||
sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)
|
sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)
|
||||||
);
|
);
|
||||||
$response_header = "HTTP/1.1 101 Switching Protocols\r\n"
|
$response_header = "HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
. "Upgrade: websocket\r\n"
|
. "Upgrade: websocket\r\n"
|
||||||
. "Connection: Upgrade\r\n"
|
. "Connection: Upgrade\r\n"
|
||||||
. "Sec-WebSocket-Accept: {$accept_key}\r\n\r\n";
|
. "Sec-WebSocket-Accept: {$accept_key}\r\n\r\n";
|
||||||
fwrite($socket, $response_header);
|
fwrite($socket, $response_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read specific number of bytes from a web socket
|
* Read specific number of bytes from a web socket
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @param int $length
|
* @param int $length
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function read_bytes($socket, int $length): string {
|
private function read_bytes($socket, int $length): string {
|
||||||
@@ -379,15 +445,17 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a web socket data frame and converts it to a regular string
|
* Reads a web socket data frame and converts it to a regular string
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @return string
|
*
|
||||||
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
private function receive_frame($socket): string {
|
private function receive_frame($socket): ?string {
|
||||||
if (!is_resource($socket)) {
|
if (!is_resource($socket)) {
|
||||||
throw new \RuntimeException("Not connected");
|
throw new \RuntimeException("Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
$final_frame = false;
|
$final_frame = false;
|
||||||
$payload_data = '';
|
$payload_data = '';
|
||||||
|
|
||||||
while (!$final_frame) {
|
while (!$final_frame) {
|
||||||
@@ -399,8 +467,8 @@ class websocket_server {
|
|||||||
$byte2 = ord($header[1]);
|
$byte2 = ord($header[1]);
|
||||||
|
|
||||||
$final_frame = ($byte1 >> 7) & 1;
|
$final_frame = ($byte1 >> 7) & 1;
|
||||||
$opcode = $byte1 & 0x0F;
|
$opcode = $byte1 & 0x0F;
|
||||||
$masked = ($byte2 >> 7) & 1;
|
$masked = ($byte2 >> 7) & 1;
|
||||||
$payload_len = $byte2 & 0x7F;
|
$payload_len = $byte2 & 0x7F;
|
||||||
|
|
||||||
// Extended payload length
|
// Extended payload length
|
||||||
@@ -480,8 +548,11 @@ class websocket_server {
|
|||||||
/**
|
/**
|
||||||
* Send text frame to client. If the socket connection is not a valid resource, the send
|
* Send text frame to client. If the socket connection is not a valid resource, the send
|
||||||
* method will fail silently and return false.
|
* method will fail silently and return false.
|
||||||
* @param resource $resource The socket or resource id to communicate on.
|
*
|
||||||
* @param string|null $payload The message to send to the clients. Sending null as the message sends a close frame packet.
|
* @param resource $resource The socket or resource id to communicate on.
|
||||||
|
* @param string|null $payload The message to send to the clients. Sending null as the message sends a close frame
|
||||||
|
* packet.
|
||||||
|
*
|
||||||
* @return bool True if message was sent on the provided resource or false if there was an error.
|
* @return bool True if message was sent on the provided resource or false if there was an error.
|
||||||
*/
|
*/
|
||||||
public static function send($resource, ?string $payload): bool {
|
public static function send($resource, ?string $payload): bool {
|
||||||
@@ -496,20 +567,20 @@ class websocket_server {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk_size = 4096; // 4 KB
|
$chunk_size = 4096; // 4 KB
|
||||||
$payload_len = strlen($payload);
|
$payload_len = strlen($payload);
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
$first = true;
|
$first = true;
|
||||||
|
|
||||||
while ($offset < $payload_len) {
|
while ($offset < $payload_len) {
|
||||||
$remaining = $payload_len - $offset;
|
$remaining = $payload_len - $offset;
|
||||||
$chunk = substr($payload, $offset, min($chunk_size, $remaining));
|
$chunk = substr($payload, $offset, min($chunk_size, $remaining));
|
||||||
$chunk_len = strlen($chunk);
|
$chunk_len = strlen($chunk);
|
||||||
|
|
||||||
// Determine FIN bit and opcode
|
// Determine FIN bit and opcode
|
||||||
$fin = ($offset + $chunk_size >= $payload_len) ? 0x80 : 0x00; // 0x80 if final
|
$fin = ($offset + $chunk_size >= $payload_len) ? 0x80 : 0x00; // 0x80 if final
|
||||||
$opcode = $first ? 0x1 : 0x0; // text for first frame, continuation for rest
|
$opcode = $first ? 0x1 : 0x0; // text for first frame, continuation for rest
|
||||||
$first = false;
|
$first = false;
|
||||||
|
|
||||||
// Build header
|
// Build header
|
||||||
$header = chr($fin | $opcode);
|
$header = chr($fin | $opcode);
|
||||||
@@ -542,7 +613,9 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IP and port of the connected remote system.
|
* Get the IP and port of the connected remote system.
|
||||||
|
*
|
||||||
* @param socket $socket The socket stream of the connection
|
* @param socket $socket The socket stream of the connection
|
||||||
|
*
|
||||||
* @return array An associative array of remote_ip and remote_port
|
* @return array An associative array of remote_ip and remote_port
|
||||||
*/
|
*/
|
||||||
public static function get_remote_info($socket): array {
|
public static function get_remote_info($socket): array {
|
||||||
@@ -552,9 +625,10 @@ class websocket_server {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Print socket information
|
* Print socket information
|
||||||
|
*
|
||||||
* @param resource $resource
|
* @param resource $resource
|
||||||
* @param bool $return If you would like to capture the output of print_r(), use the return parameter. When this
|
* @param bool $return If you would like to capture the output of print_r(), use the return parameter. When this
|
||||||
* parameter is set to true, print_r() will return the information rather than print it.
|
* parameter is set to true, print_r() will return the information rather than print it.
|
||||||
*/
|
*/
|
||||||
public static function print_stream_info($resource, $return = false) {
|
public static function print_stream_info($resource, $return = false) {
|
||||||
if (is_resource($resource)) {
|
if (is_resource($resource)) {
|
||||||
|
|||||||
@@ -35,48 +35,56 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Address to bind to. (Default 8080)
|
* Address to bind to. (Default 8080)
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $ip;
|
protected $ip;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
||||||
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $port;
|
protected $port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource or stream of the server socket binding
|
* Resource or stream of the server socket binding
|
||||||
|
*
|
||||||
* @var resource|stream
|
* @var resource|stream
|
||||||
*/
|
*/
|
||||||
protected $server_socket;
|
protected $server_socket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of connected client sockets
|
* List of connected client sockets
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $clients;
|
protected $clients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_message events
|
* Used to track on_message events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $message_callbacks;
|
protected $message_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_connect events
|
* Used to track on_connect events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $connect_callbacks;
|
protected $connect_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track on_disconnect events
|
* Used to track on_disconnect events
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $disconnect_callbacks;
|
protected $disconnect_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to track switch listeners or other socket connection types
|
* Used to track switch listeners or other socket connection types
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $listeners;
|
protected $listeners;
|
||||||
@@ -84,12 +92,14 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscriber Objects
|
* Subscriber Objects
|
||||||
|
*
|
||||||
* @var subscriber
|
* @var subscriber
|
||||||
*/
|
*/
|
||||||
protected $subscribers;
|
protected $subscribers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of registered services
|
* Array of registered services
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $services;
|
private $services;
|
||||||
@@ -100,18 +110,19 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload settings
|
* Reload settings
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected function reload_settings(): void {
|
protected function reload_settings(): void {
|
||||||
// Initialize tracking arrays
|
// Initialize tracking arrays
|
||||||
$this->listeners = [];
|
$this->listeners = [];
|
||||||
$this->clients = [];
|
$this->clients = [];
|
||||||
$this->message_callbacks = [];
|
$this->message_callbacks = [];
|
||||||
$this->connect_callbacks = [];
|
$this->connect_callbacks = [];
|
||||||
$this->disconnect_callbacks = [];
|
$this->disconnect_callbacks = [];
|
||||||
$this->subscribers = [];
|
$this->subscribers = [];
|
||||||
|
|
||||||
$settings = new settings(['database' => database::new(['config' => config::load()])]);
|
$settings = new settings(['database' => database::new(['config' => config::load()])]);
|
||||||
|
|
||||||
@@ -134,6 +145,7 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the version on the console
|
* Display the version on the console
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
@@ -143,6 +155,7 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set extra command options from the command line
|
* Set extra command options from the command line
|
||||||
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected static function set_command_options() {
|
protected static function set_command_options() {
|
||||||
@@ -170,6 +183,13 @@ class websocket_service extends service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a subscriber object from the given socket ID.
|
||||||
|
*
|
||||||
|
* @param mixed $socket The socket ID to search for
|
||||||
|
*
|
||||||
|
* @return subscriber|null The matching subscriber, or null if not found
|
||||||
|
*/
|
||||||
private function get_subscriber_from_socket_id($socket): ?subscriber {
|
private function get_subscriber_from_socket_id($socket): ?subscriber {
|
||||||
$subscriber = null;
|
$subscriber = null;
|
||||||
// Get the subscriber based on their socket ID
|
// Get the subscriber based on their socket ID
|
||||||
@@ -182,6 +202,16 @@ class websocket_service extends service {
|
|||||||
return $subscriber;
|
return $subscriber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate a subscriber based on the provided token and message.
|
||||||
|
*
|
||||||
|
* @param subscriber $subscriber The subscriber to authenticate.
|
||||||
|
* @param websocket_message $message The message containing the authentication token.
|
||||||
|
*
|
||||||
|
* @return bool Whether the authentication was successful or not.
|
||||||
|
* @throws \socket_disconnected_exception
|
||||||
|
* @throws \subscriber_token_expired_exception
|
||||||
|
*/
|
||||||
private function authenticate_subscriber(subscriber $subscriber, websocket_message $message) {
|
private function authenticate_subscriber(subscriber $subscriber, websocket_message $message) {
|
||||||
$this->info("Authenticating client: $subscriber->id");
|
$this->info("Authenticating client: $subscriber->id");
|
||||||
|
|
||||||
@@ -204,7 +234,7 @@ class websocket_service extends service {
|
|||||||
foreach ($subscriptions as $subscribed_to) {
|
foreach ($subscriptions as $subscribed_to) {
|
||||||
if (isset($this->services[$subscribed_to])) {
|
if (isset($this->services[$subscribed_to])) {
|
||||||
$subscriber_service = $this->services[$subscribed_to];
|
$subscriber_service = $this->services[$subscribed_to];
|
||||||
$class_name = $subscriber_service->service_class();
|
$class_name = $subscriber_service->service_class();
|
||||||
// Make sure we can call the 'create_filter_chain_for' method
|
// Make sure we can call the 'create_filter_chain_for' method
|
||||||
if (is_a($class_name, 'websocket_service_interface', true)) {
|
if (is_a($class_name, 'websocket_service_interface', true)) {
|
||||||
// Call the service class method to validate the subscriber
|
// Call the service class method to validate the subscriber
|
||||||
@@ -227,6 +257,14 @@ class websocket_service extends service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast a message to all subscribers except the specified broadcaster.
|
||||||
|
*
|
||||||
|
* @param subscriber $broadcaster The subscriber that is broadcasting the message.
|
||||||
|
* @param websocket_message|null $message The message being broadcasted. If null, do nothing.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function broadcast_service_message(subscriber $broadcaster, ?websocket_message $message = null) {
|
private function broadcast_service_message(subscriber $broadcaster, ?websocket_message $message = null) {
|
||||||
|
|
||||||
$this->debug("Processing Broadcast");
|
$this->debug("Processing Broadcast");
|
||||||
@@ -268,8 +306,7 @@ class websocket_service extends service {
|
|||||||
$this->handle_disconnect($subscriber->socket_id());
|
$this->handle_disconnect($subscriber->socket_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // Route a specific request from a service back to a subscriber
|
||||||
// Route a specific request from a service back to a subscriber
|
|
||||||
else {
|
else {
|
||||||
// Get the subscriber object hash
|
// Get the subscriber object hash
|
||||||
$object_id = $message->resource_id;
|
$object_id = $message->resource_id;
|
||||||
@@ -288,9 +325,11 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters subscribers based on the service name given
|
* Filters subscribers based on the service name given
|
||||||
* @param array $subscribers
|
*
|
||||||
|
* @param array $subscribers
|
||||||
* @param websocket_message $message
|
* @param websocket_message $message
|
||||||
* @param string $service_name
|
* @param string $service_name
|
||||||
|
*
|
||||||
* @return array List of subscriber objects or an empty array if there are no subscribers to that service name
|
* @return array List of subscriber objects or an empty array if there are no subscribers to that service name
|
||||||
*/
|
*/
|
||||||
private function filter_subscribers(array $subscribers, websocket_message $message, string $service_name): array {
|
private function filter_subscribers(array $subscribers, websocket_message $message, string $service_name): array {
|
||||||
@@ -299,7 +338,7 @@ class websocket_service extends service {
|
|||||||
foreach ($subscribers as $subscriber) {
|
foreach ($subscribers as $subscriber) {
|
||||||
$caller_context = strtolower($message->caller_context ?? '');
|
$caller_context = strtolower($message->caller_context ?? '');
|
||||||
if (!empty($caller_context) && $subscriber->has_subscribed_to($service_name) && ($subscriber->show_all || $caller_context === $subscriber->domain_name || $caller_context === 'public' || $caller_context === 'default'
|
if (!empty($caller_context) && $subscriber->has_subscribed_to($service_name) && ($subscriber->show_all || $caller_context === $subscriber->domain_name || $caller_context === 'public' || $caller_context === 'default'
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$filtered[] = $subscriber;
|
$filtered[] = $subscriber;
|
||||||
} else {
|
} else {
|
||||||
@@ -313,13 +352,15 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a subscriber for each connection
|
* Create a subscriber for each connection
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function handle_connect($socket) {
|
private function handle_connect($socket) {
|
||||||
// We catch only the socket disconnection exception as there is a general try/catch already
|
// We catch only the socket disconnection exception as there is a general try/catch already
|
||||||
try {
|
try {
|
||||||
$subscriber = new subscriber($socket, [websocket_service::class, 'send']);
|
$subscriber = new subscriber($socket, [websocket_service::class, 'send']);
|
||||||
$this->subscribers[$subscriber->id] = $subscriber;
|
$this->subscribers[$subscriber->id] = $subscriber;
|
||||||
$subscriber->send(websocket_message::connected());
|
$subscriber->send(websocket_message::connected());
|
||||||
} catch (\socket_disconnected_exception $sde) {
|
} catch (\socket_disconnected_exception $sde) {
|
||||||
@@ -332,6 +373,7 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Web socket client disconnected from the server or this service has requested a disconnect from the subscriber
|
* Web socket client disconnected from the server or this service has requested a disconnect from the subscriber
|
||||||
|
*
|
||||||
* @param subscriber|resource|int|string $object_or_resource_or_id
|
* @param subscriber|resource|int|string $object_or_resource_or_id
|
||||||
*/
|
*/
|
||||||
private function handle_disconnect($object_or_resource_or_id) {
|
private function handle_disconnect($object_or_resource_or_id) {
|
||||||
@@ -377,8 +419,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* When a message event occurs, send to all the subscribers
|
* When a message event occurs, send to all the subscribers
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
*/
|
*/
|
||||||
private function handle_message($socket, $data) {
|
private function handle_message($socket, $data) {
|
||||||
$subscriber = $this->get_subscriber_from_socket_id($socket);
|
$subscriber = $this->get_subscriber_from_socket_id($socket);
|
||||||
@@ -436,6 +479,14 @@ class websocket_service extends service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a client message by routing it to its intended service.
|
||||||
|
*
|
||||||
|
* @param subscriber $subscriber The client subscriber instance associated with the incoming message.
|
||||||
|
* @param websocket_message $message The incoming WebSocket message containing details about the request.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
private function handle_client_message(subscriber $subscriber, websocket_message $message) {
|
private function handle_client_message(subscriber $subscriber, websocket_message $message) {
|
||||||
//find the service with that name
|
//find the service with that name
|
||||||
foreach ($this->subscribers as $service) {
|
foreach ($this->subscribers as $service) {
|
||||||
@@ -454,7 +505,7 @@ class websocket_service extends service {
|
|||||||
$message->resource_id = $subscriber->id;
|
$message->resource_id = $subscriber->id;
|
||||||
|
|
||||||
//send the modified web socket message to the service
|
//send the modified web socket message to the service
|
||||||
$service->send((string) $message);
|
$service->send((string)$message);
|
||||||
|
|
||||||
//continue searching for service providers
|
//continue searching for service providers
|
||||||
continue;
|
continue;
|
||||||
@@ -465,6 +516,7 @@ class websocket_service extends service {
|
|||||||
/**
|
/**
|
||||||
* Runs the web socket server binding to the ip and port set in default settings
|
* Runs the web socket server binding to the ip and port set in default settings
|
||||||
* The run method will stop if the SIG_TERM or SIG_HUP signal is processed in the parent
|
* The run method will stop if the SIG_TERM or SIG_HUP signal is processed in the parent
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @throws socket_exception
|
* @throws socket_exception
|
||||||
@@ -494,7 +546,7 @@ class websocket_service extends service {
|
|||||||
//
|
//
|
||||||
// Merge all sockets to a single array
|
// Merge all sockets to a single array
|
||||||
//
|
//
|
||||||
$read = array_merge([$this->server_socket], $this->clients);
|
$read = array_merge([$this->server_socket], $this->clients);
|
||||||
$write = $except = [];
|
$write = $except = [];
|
||||||
|
|
||||||
//$this->debug("Waiting on event. Connected Clients: (".count($this->clients).")", LOG_DEBUG);
|
//$this->debug("Waiting on event. Connected Clients: (".count($this->clients).")", LOG_DEBUG);
|
||||||
@@ -577,10 +629,10 @@ class websocket_service extends service {
|
|||||||
// Get the error details
|
// Get the error details
|
||||||
//
|
//
|
||||||
$subscriber_id = $se->getSubscriberId();
|
$subscriber_id = $se->getSubscriberId();
|
||||||
$message = $se->getMessage();
|
$message = $se->getMessage();
|
||||||
$code = $se->getCode();
|
$code = $se->getCode();
|
||||||
$file = $se->getFile();
|
$file = $se->getFile();
|
||||||
$line = $se->getLine();
|
$line = $se->getLine();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dump the details in the log
|
// Dump the details in the log
|
||||||
@@ -595,10 +647,12 @@ class websocket_service extends service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the parent class to shutdown all sockets
|
* Overrides the parent class to shutdown all sockets
|
||||||
|
*
|
||||||
* @override service
|
* @override service
|
||||||
*/
|
*/
|
||||||
public function __destruct() {
|
public function __destruct() {
|
||||||
@@ -610,12 +664,18 @@ class websocket_service extends service {
|
|||||||
parent::__destruct();
|
parent::__destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an array of open sockets.
|
||||||
|
*
|
||||||
|
* @return array An array containing open socket connections.
|
||||||
|
*/
|
||||||
public function get_open_sockets(): array {
|
public function get_open_sockets(): array {
|
||||||
return $this->clients;
|
return $this->clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if there are connected web socket clients.
|
* Returns true if there are connected web socket clients.
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function has_clients(): bool {
|
public function has_clients(): bool {
|
||||||
@@ -625,7 +685,9 @@ class websocket_service extends service {
|
|||||||
/**
|
/**
|
||||||
* When a web socket message is received the $on_message_callback function is called.
|
* When a web socket message is received the $on_message_callback function is called.
|
||||||
* Multiple on_message functions can be specified.
|
* Multiple on_message functions can be specified.
|
||||||
|
*
|
||||||
* @param callable $on_message_callback
|
* @param callable $on_message_callback
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_message(callable $on_message_callback) {
|
public function on_message(callable $on_message_callback) {
|
||||||
@@ -637,8 +699,10 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_message functions
|
* Calls all the on_message functions
|
||||||
|
*
|
||||||
* @param resource $resource
|
* @param resource $resource
|
||||||
* @param string $message
|
* @param string $message
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
@@ -652,7 +716,9 @@ class websocket_service extends service {
|
|||||||
/**
|
/**
|
||||||
* When a web socket handshake has completed, the $on_connect_callback function is called.
|
* When a web socket handshake has completed, the $on_connect_callback function is called.
|
||||||
* Multiple on_connect functions can be specified.
|
* Multiple on_connect functions can be specified.
|
||||||
|
*
|
||||||
* @param callable $on_connect_callback
|
* @param callable $on_connect_callback
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_connect(callable $on_connect_callback) {
|
public function on_connect(callable $on_connect_callback) {
|
||||||
@@ -664,7 +730,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_connect functions
|
* Calls all the on_connect functions
|
||||||
|
*
|
||||||
* @param resource $resource
|
* @param resource $resource
|
||||||
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected function trigger_connect($resource) {
|
protected function trigger_connect($resource) {
|
||||||
@@ -676,7 +744,9 @@ class websocket_service extends service {
|
|||||||
/**
|
/**
|
||||||
* When a web socket has disconnected, the $on_disconnect_callback function is called.
|
* When a web socket has disconnected, the $on_disconnect_callback function is called.
|
||||||
* Multiple functions can be specified with subsequent calls
|
* Multiple functions can be specified with subsequent calls
|
||||||
|
*
|
||||||
* @param string|callable $on_disconnect_callback
|
* @param string|callable $on_disconnect_callback
|
||||||
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function on_disconnect($on_disconnect_callback) {
|
public function on_disconnect($on_disconnect_callback) {
|
||||||
@@ -688,7 +758,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls all the on_disconnect_callback functions
|
* Calls all the on_disconnect_callback functions
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected function trigger_disconnect($socket) {
|
protected function trigger_disconnect($socket) {
|
||||||
@@ -699,6 +771,7 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the socket used in the server connection
|
* Returns the socket used in the server connection
|
||||||
|
*
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function get_socket() {
|
public function get_socket() {
|
||||||
@@ -707,7 +780,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a client socket on disconnect.
|
* Remove a client socket on disconnect.
|
||||||
|
*
|
||||||
* @param resource $resource Resource for the socket connection
|
* @param resource $resource Resource for the socket connection
|
||||||
|
*
|
||||||
* @return bool Returns true on client disconnect and false when the client is not found in the tracking array
|
* @return bool Returns true on client disconnect and false when the client is not found in the tracking array
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
@@ -750,6 +825,8 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs web socket handshake on new connection.
|
* Performs web socket handshake on new connection.
|
||||||
|
*
|
||||||
|
* @param resource $resource
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected function handshake($resource): void {
|
protected function handshake($resource): void {
|
||||||
@@ -765,21 +842,23 @@ class websocket_service extends service {
|
|||||||
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/i", $request_header, $matches)) {
|
if (!preg_match("/Sec-WebSocket-Key: (.*)\r\n/i", $request_header, $matches)) {
|
||||||
throw new invalid_handshake_exception($resource, "Invalid WebSocket handshake");
|
throw new invalid_handshake_exception($resource, "Invalid WebSocket handshake");
|
||||||
}
|
}
|
||||||
$key = trim($matches[1]);
|
$key = trim($matches[1]);
|
||||||
$accept_key = base64_encode(
|
$accept_key = base64_encode(
|
||||||
sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)
|
sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)
|
||||||
);
|
);
|
||||||
$response_header = "HTTP/1.1 101 Switching Protocols\r\n"
|
$response_header = "HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
. "Upgrade: websocket\r\n"
|
. "Upgrade: websocket\r\n"
|
||||||
. "Connection: Upgrade\r\n"
|
. "Connection: Upgrade\r\n"
|
||||||
. "Sec-WebSocket-Accept: {$accept_key}\r\n\r\n";
|
. "Sec-WebSocket-Accept: {$accept_key}\r\n\r\n";
|
||||||
fwrite($resource, $response_header);
|
fwrite($resource, $response_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read specific number of bytes from a websocket
|
* Read specific number of bytes from a websocket
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
* @param int $length
|
* @param int $length
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function read_bytes($socket, int $length): string {
|
private function read_bytes($socket, int $length): string {
|
||||||
@@ -797,7 +876,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a websocket data frame and converts it to a regular string
|
* Reads a websocket data frame and converts it to a regular string
|
||||||
|
*
|
||||||
* @param resource $socket
|
* @param resource $socket
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function receive_frame($socket): string {
|
private function receive_frame($socket): string {
|
||||||
@@ -810,8 +891,8 @@ class websocket_service extends service {
|
|||||||
$this->update_connected_clients();
|
$this->update_connected_clients();
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$bytes = unpack('Cfirst/Csecond', $hdr);
|
$bytes = unpack('Cfirst/Csecond', $hdr);
|
||||||
$fin = ($bytes['first'] >> 7) & 0x1;
|
$fin = ($bytes['first'] >> 7) & 0x1;
|
||||||
$opcode = $bytes['first'] & 0x0F;
|
$opcode = $bytes['first'] & 0x0F;
|
||||||
$masked = ($bytes['second'] >> 7) & 0x1;
|
$masked = ($bytes['second'] >> 7) & 0x1;
|
||||||
$length = $bytes['second'] & 0x7F;
|
$length = $bytes['second'] & 0x7F;
|
||||||
@@ -829,7 +910,7 @@ class websocket_service extends service {
|
|||||||
if (strlen($ext) < 8)
|
if (strlen($ext) < 8)
|
||||||
return '';
|
return '';
|
||||||
// unpack 64-bit BE; PHP 7.0+: use J, else fallback
|
// unpack 64-bit BE; PHP 7.0+: use J, else fallback
|
||||||
$arr = unpack('J', $ext);
|
$arr = unpack('J', $ext);
|
||||||
$length = $arr[1];
|
$length = $arr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,8 +944,10 @@ class websocket_service extends service {
|
|||||||
/**
|
/**
|
||||||
* Send text frame to client. If the socket connection is not a valid resource, the send
|
* Send text frame to client. If the socket connection is not a valid resource, the send
|
||||||
* method will fail silently and return false.
|
* method will fail silently and return false.
|
||||||
* @param resource $resource The socket or resource id to communicate on.
|
*
|
||||||
* @param string|null $payload The string to wrap in a web socket frame to send to the clients
|
* @param resource $resource The socket or resource id to communicate on.
|
||||||
|
* @param string|null $payload The string to wrap in a web socket frame to send to the clients
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function send($resource, ?string $payload): bool {
|
public static function send($resource, ?string $payload): bool {
|
||||||
@@ -878,7 +961,7 @@ class websocket_service extends service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$payload_length = strlen($payload);
|
$payload_length = strlen($payload);
|
||||||
$frame_header = "\x81"; // FIN = 1, text frame
|
$frame_header = "\x81"; // FIN = 1, text frame
|
||||||
// Create frame header
|
// Create frame header
|
||||||
if ($payload_length <= 125) {
|
if ($payload_length <= 125) {
|
||||||
$frame_header .= chr($payload_length);
|
$frame_header .= chr($payload_length);
|
||||||
@@ -893,7 +976,7 @@ class websocket_service extends service {
|
|||||||
// Attempt to write full frame
|
// Attempt to write full frame
|
||||||
$written = @fwrite($resource, $frame);
|
$written = @fwrite($resource, $frame);
|
||||||
if ($written === false) {
|
if ($written === false) {
|
||||||
self::log("fwrite() failed for socket " . (int) $resource, LOG_ERR);
|
self::log("fwrite() failed for socket " . (int)$resource, LOG_ERR);
|
||||||
throw new socket_disconnected_exception($resource);
|
throw new socket_disconnected_exception($resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,7 +990,9 @@ class websocket_service extends service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IP and port of the connected remote system.
|
* Get the IP and port of the connected remote system.
|
||||||
|
*
|
||||||
* @param resource $resource The resource or stream of the connection
|
* @param resource $resource The resource or stream of the connection
|
||||||
|
*
|
||||||
* @return array An associative array of remote_ip and remote_port
|
* @return array An associative array of remote_ip and remote_port
|
||||||
*/
|
*/
|
||||||
public static function get_remote_info($resource): array {
|
public static function get_remote_info($resource): array {
|
||||||
|
|||||||
Reference in New Issue
Block a user