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
|
||||
*
|
||||
* @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 {
|
||||
|
||||
@@ -71,6 +69,7 @@ class authentication {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function validate() {
|
||||
@@ -189,8 +188,7 @@ class authentication {
|
||||
$plugin_name = $row['plugin'];
|
||||
if ($row["authorized"]) {
|
||||
$authorized = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$authorized = false;
|
||||
$failed_login_message = "Authentication plugin '$plugin_name' blocked login attempt";
|
||||
break;
|
||||
@@ -228,11 +226,15 @@ class authentication {
|
||||
* Creates a valid user session in the superglobal $_SESSION.
|
||||
* <p>The $result must be a validated user with the appropriate variables set.<br>
|
||||
* The associative array
|
||||
* @global database $database
|
||||
* @global string $conf
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
* @param settings $settings From the settings object
|
||||
*
|
||||
* @return void
|
||||
* @global string $conf
|
||||
* @global database $database
|
||||
*/
|
||||
public static function create_user_session($result = [], $settings = null): void {
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class plugin_database {
|
||||
|
||||
/**
|
||||
* database checks the local database to authenticate the user or key
|
||||
*
|
||||
* @return array [authorized] => true or false
|
||||
*/
|
||||
function database(authentication $auth, settings $settings) {
|
||||
@@ -234,8 +235,7 @@ class plugin_database {
|
||||
if (isset($this->key) && strlen($this->key) > 30) {
|
||||
$sql .= "and u.api_key = :api_key ";
|
||||
$parameters['api_key'] = $this->key;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$sql .= "and (\n";
|
||||
$sql .= " lower(u.username) = lower(:username)\n";
|
||||
$sql .= " or lower(u.user_email) = lower(:username)\n";
|
||||
@@ -244,8 +244,7 @@ class plugin_database {
|
||||
}
|
||||
if ($users_unique === "global") {
|
||||
//unique username - global (example: email address)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//unique username - per domain
|
||||
$sql .= "and u.domain_uuid = :domain_uuid ";
|
||||
$parameters['domain_uuid'] = $this->domain_uuid;
|
||||
@@ -258,15 +257,13 @@ class plugin_database {
|
||||
$valid_password = false;
|
||||
if (isset($this->key) && strlen($this->key) > 30 && $this->key === $row["api_key"]) {
|
||||
$valid_password = true;
|
||||
}
|
||||
else if (substr($row["password"], 0, 1) === '$') {
|
||||
} elseif (substr($row["password"], 0, 1) === '$') {
|
||||
if (isset($this->password) && !empty($this->password)) {
|
||||
if (password_verify($this->password, $row["password"])) {
|
||||
$valid_password = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} 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'] . '$');
|
||||
@@ -335,7 +332,7 @@ class plugin_database {
|
||||
//check to to see if the the password hash needs to be updated
|
||||
if ($valid_password) {
|
||||
//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
|
||||
if (password_needs_rehash($row["password"], PASSWORD_DEFAULT, $options)) {
|
||||
@@ -395,7 +392,6 @@ class plugin_database {
|
||||
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ class plugin_email {
|
||||
|
||||
/**
|
||||
* time based one time password with email
|
||||
*
|
||||
* @return array [authorized] => true or false
|
||||
*/
|
||||
function email(authentication $auth, settings $settings) {
|
||||
@@ -181,9 +182,7 @@ class plugin_email {
|
||||
|
||||
//retun the array
|
||||
return $result;
|
||||
}
|
||||
|
||||
//user email not found
|
||||
} //user email not found
|
||||
elseif (empty($row["user_email"])) {
|
||||
//clear submitted usernames
|
||||
unset($this->username, $_SESSION['username'], $_REQUEST['username'], $_POST['username']);
|
||||
@@ -301,8 +300,7 @@ class plugin_email {
|
||||
//remove the temporary permission
|
||||
$p->delete("email_queue_add", 'temp');
|
||||
$p->delete("email_queue_edit", 'temp');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//send email - direct
|
||||
$email = new email;
|
||||
$email->recipients = $_SESSION["user_email"];
|
||||
@@ -410,8 +408,7 @@ class plugin_email {
|
||||
//validate the code
|
||||
if (!empty($_SESSION["user"]) && $_SESSION["user"]["authentication"]["email"]["code"] === $_POST['authentication_code']) {
|
||||
$auth_valid = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$auth_valid = false;
|
||||
}
|
||||
|
||||
@@ -457,8 +454,7 @@ class plugin_email {
|
||||
//$_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 {
|
||||
} else {
|
||||
// //destroy session
|
||||
// session_unset();
|
||||
// session_destroy();
|
||||
|
||||
@@ -27,6 +27,7 @@ class plugin_ldap {
|
||||
*/
|
||||
private $database;
|
||||
|
||||
|
||||
/**
|
||||
* Called when the object is created
|
||||
*/
|
||||
|
||||
@@ -65,6 +65,7 @@ class plugin_totp {
|
||||
|
||||
/**
|
||||
* time based one time password aka totp
|
||||
*
|
||||
* @return array [authorized] => true or false
|
||||
*/
|
||||
function totp(authentication $auth, settings $settings) {
|
||||
@@ -238,7 +239,7 @@ class plugin_totp {
|
||||
if (!empty($_SESSION['authentication']['plugin']['database']['authorized']) && empty($this->user_totp_secret)) {
|
||||
|
||||
//create the totp secret
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
|
||||
$base32 = new base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', false, true, true);
|
||||
$user_totp_secret = $base32->encode(generate_password(20, 3));
|
||||
$this->user_totp_secret = $user_totp_secret;
|
||||
|
||||
@@ -277,8 +278,7 @@ class plugin_totp {
|
||||
$img->draw();
|
||||
$image = $img->getImage();
|
||||
$img->finish();
|
||||
}
|
||||
catch (Exception $error) {
|
||||
} catch (Exception $error) {
|
||||
echo $error;
|
||||
}
|
||||
|
||||
@@ -295,8 +295,7 @@ class plugin_totp {
|
||||
|
||||
//render the template
|
||||
$content = $view->render('totp_secret.htm');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//assign values to the template
|
||||
$view->assign("button_verify", $text['label-verify']);
|
||||
$view->assign("message_delay", $theme_message_delay);
|
||||
@@ -340,8 +339,7 @@ class plugin_totp {
|
||||
//validate the code
|
||||
if ($totp->checkCode($this->user_totp_secret, $_POST['authentication_code'])) {
|
||||
$auth_valid = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$auth_valid = false;
|
||||
}
|
||||
|
||||
@@ -382,8 +380,7 @@ class plugin_totp {
|
||||
$parameters['user_uuid'] = $_SESSION["user_uuid"];
|
||||
$row = $this->database->select($sql, $parameters, 'row');
|
||||
unset($parameters);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// //destroy session
|
||||
// session_unset();
|
||||
// session_destroy();
|
||||
|
||||
@@ -38,18 +38,6 @@
|
||||
$language = new text;
|
||||
$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
|
||||
ini_set('max_execution_time', 7200);
|
||||
|
||||
@@ -252,6 +240,14 @@
|
||||
}
|
||||
|
||||
//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) {
|
||||
foreach ($schema as $row) {
|
||||
if ($row['table'] == $table_name) {
|
||||
|
||||
@@ -581,6 +581,13 @@ require_once "resources/footer.php";
|
||||
|
||||
|
||||
// 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) {
|
||||
$curl = curl_init();
|
||||
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
|
||||
|
||||
@@ -35,18 +35,22 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
@@ -65,8 +69,13 @@
|
||||
*/
|
||||
public $contact_uuid;
|
||||
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -94,7 +103,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete 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')) {
|
||||
@@ -152,6 +167,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_properties($records) {
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
@@ -195,6 +219,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_';
|
||||
@@ -239,6 +272,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_';
|
||||
|
||||
@@ -49,7 +49,11 @@
|
||||
private $uuid_prefix;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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 objects
|
||||
@@ -67,7 +71,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete rows from the database
|
||||
* 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) {
|
||||
//assign the variables
|
||||
@@ -129,7 +139,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle a field between two values
|
||||
* 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) {
|
||||
//assign the variables
|
||||
@@ -197,7 +213,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy rows from the database
|
||||
* 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) {
|
||||
//assign the variables
|
||||
@@ -323,6 +345,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or multiple dashboard widgets.
|
||||
*
|
||||
* This method deletes the specified dashboard widgets based on their UUIDs and user permissions.
|
||||
*
|
||||
* @param array $records An array of records to delete, where each record contains a 'dashboard_widget_uuid' key.
|
||||
*/
|
||||
public function delete_widgets($records) {
|
||||
//assign the variables
|
||||
$this->name = 'dashboard_widget';
|
||||
@@ -373,6 +402,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the enabled state of dashboard widgets.
|
||||
*
|
||||
* This method updates the database with new toggle states for the specified records.
|
||||
*
|
||||
* @param array $records An array of records to update.
|
||||
*/
|
||||
public function toggle_widgets($records) {
|
||||
//assign the variables
|
||||
$this->name = 'dashboard_widget';
|
||||
@@ -441,6 +477,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign dashboard widgets.
|
||||
*
|
||||
* This method assigns multiple records to a group in the database.
|
||||
*
|
||||
* @param array $records The list of dashboard widget records to assign.
|
||||
* @param string $dashboard_uuid The UUID of the dashboard.
|
||||
* @param string $group_uuid The UUID of the group.
|
||||
*/
|
||||
public function assign_widgets($records, $dashboard_uuid, $group_uuid) {
|
||||
//assign the variables
|
||||
$this->name = 'dashboard_widget';
|
||||
@@ -520,6 +565,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign widgets from a dashboard.
|
||||
*
|
||||
* This method removes the specified widgets from the dashboard and its groups.
|
||||
*
|
||||
* @param array $records An array of records to unassign, where each record contains
|
||||
* the 'dashboard_widget_uuid' key.
|
||||
* @param string $dashboard_uuid The UUID of the dashboard from which to unassign the widgets.
|
||||
* @param string $group_uuid The UUID of the group from which to unassign the widgets.
|
||||
*/
|
||||
public function unassign_widgets($records, $dashboard_uuid, $group_uuid) {
|
||||
//assign the variables
|
||||
$this->name = 'dashboard_widget';
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
private $uuid_prefix;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* Initializes the object by setting default values and connecting to the database.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
@@ -62,7 +62,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete 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')) {
|
||||
@@ -105,7 +111,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy 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')) {
|
||||
|
||||
@@ -230,6 +230,16 @@
|
||||
}
|
||||
|
||||
//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') {
|
||||
foreach($search_array as $row) {
|
||||
if ($row[$field] == $value) {
|
||||
|
||||
@@ -36,19 +36,23 @@
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $domain_uuid;
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
private $settings;
|
||||
@@ -63,7 +67,11 @@
|
||||
private $location;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -81,7 +89,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete rows from the database
|
||||
* 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->name . '_delete')) {
|
||||
@@ -127,7 +141,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle a field between two values
|
||||
* 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')) {
|
||||
@@ -191,7 +211,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy rows from the database
|
||||
* 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')) {
|
||||
@@ -296,9 +322,7 @@
|
||||
$settings_copied++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//duplicate default setting
|
||||
} //duplicate default setting
|
||||
else {
|
||||
|
||||
//populate and adjust array
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $domain_name;
|
||||
@@ -47,12 +49,14 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
private $settings;
|
||||
@@ -68,7 +72,11 @@
|
||||
private $toggle_values;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -87,7 +95,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete 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')) {
|
||||
@@ -131,7 +145,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle 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')) {
|
||||
@@ -199,7 +219,14 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy 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.
|
||||
* @throws \Random\RandomException
|
||||
*/
|
||||
public function copy($records) {
|
||||
if (permission_exists($this->permission_prefix . 'add') && permission_exists('domain_select') && count($_SESSION['domains']) > 1) {
|
||||
@@ -271,8 +298,7 @@
|
||||
|
||||
$action = is_uuid($target_domain_setting_uuid) ? 'update' : 'add';
|
||||
unset($sql, $parameters);
|
||||
}
|
||||
//target is same domain, duplicate
|
||||
} //target is same domain, duplicate
|
||||
else {
|
||||
$action = 'add';
|
||||
}
|
||||
|
||||
@@ -35,18 +35,22 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
@@ -62,7 +66,11 @@
|
||||
private $toggle_values;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -81,7 +89,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete 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')) {
|
||||
@@ -124,7 +138,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle 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')) {
|
||||
@@ -190,7 +210,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy 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')) {
|
||||
|
||||
@@ -41,7 +41,11 @@
|
||||
private $database_group_permissions;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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 objects
|
||||
@@ -49,6 +53,14 @@
|
||||
}
|
||||
|
||||
//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
|
||||
@@ -60,7 +72,7 @@
|
||||
}
|
||||
|
||||
//initialize array
|
||||
$group_name_array = array();
|
||||
$group_name_array = [];
|
||||
|
||||
//restore default permissions
|
||||
$x = 0;
|
||||
@@ -127,6 +139,17 @@
|
||||
}
|
||||
|
||||
//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
|
||||
|
||||
@@ -26,10 +26,9 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Used to create the config.conf file.</p>
|
||||
* <p>BSD /usr/local/etc/fusionpbx</p>
|
||||
* <p>Linux /etc/fusionpbx</p>
|
||||
* @return boolean
|
||||
* Used to create the config.conf file using paths based on the operating system.
|
||||
*
|
||||
* @return boolean true if the configuration file is successfully created, false otherwise.
|
||||
*/
|
||||
public function config() {
|
||||
|
||||
@@ -157,15 +156,16 @@
|
||||
|
||||
//write the config file
|
||||
$file_handle = fopen($config_file, "w");
|
||||
if(!$file_handle) { return; }
|
||||
if (!$file_handle) {
|
||||
return;
|
||||
}
|
||||
fwrite($file_handle, $conf);
|
||||
fclose($file_handle);
|
||||
|
||||
//if the config.conf file was saved return true
|
||||
if (file_exists($config_file)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,15 @@
|
||||
$tmp_menu_item_order = 0;
|
||||
|
||||
//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) {
|
||||
global $settings, $menu_uuid, $list_row_edit_button;
|
||||
global $tmp_menu_item_order, $v_link_label_edit, $v_link_label_delete;
|
||||
|
||||
@@ -6,14 +6,23 @@
|
||||
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() {
|
||||
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() {
|
||||
$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) {
|
||||
|
||||
@@ -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) {
|
||||
//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) {
|
||||
//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) {
|
||||
//echo ($text['description-restart_services'] ?? "")."\n";
|
||||
@@ -687,8 +711,11 @@ function restart_services($text, settings $settings) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service name
|
||||
* @param string $file
|
||||
* Finds the service name in an INI file from a given 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) {
|
||||
$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 {
|
||||
return posix_getuid() === 0;
|
||||
|
||||
@@ -52,9 +52,18 @@ $display_type = 'text';
|
||||
show_upgrade_menu();
|
||||
|
||||
/**
|
||||
* Show upgrade menu
|
||||
* @global type $text
|
||||
* @global type $software_name
|
||||
* Display the upgrade menu to the user.
|
||||
*
|
||||
* 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() {
|
||||
//set the global variables
|
||||
@@ -90,7 +99,7 @@ function show_upgrade_menu() {
|
||||
|
||||
//show the command menu
|
||||
echo "Options:\n";
|
||||
foreach ($options as list($key, $label, $description)) {
|
||||
foreach ($options as [$key, $label, $description]) {
|
||||
if (!is_numeric($key)) { echo " "; }
|
||||
echo " $key) $label" . ((!empty($option) && $option == 'h') ? " - " . $description : "") . "\n";
|
||||
}
|
||||
@@ -172,8 +181,12 @@ function show_upgrade_menu() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the cache file
|
||||
* @global type $text
|
||||
* Upgrade auto loader by removing temporary files and updating it.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @global text $text
|
||||
* @global auto_loader $autoload
|
||||
*/
|
||||
function do_upgrade_auto_loader() {
|
||||
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) {
|
||||
|
||||
@@ -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 {
|
||||
return posix_getpwuid(posix_getuid())['name'] ?? null;
|
||||
}
|
||||
|
||||
//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 {
|
||||
return software::version() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the source folder
|
||||
* @return type
|
||||
* Upgrade code by pulling the latest changes from version control.
|
||||
*
|
||||
* 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() {
|
||||
//assume failed
|
||||
@@ -284,8 +315,7 @@ function do_upgrade_code() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade any of the git submodules
|
||||
* @global type $text
|
||||
* Upgrade code submodules by pulling the latest changes from Git repositories.
|
||||
*/
|
||||
function do_upgrade_code_submodules() {
|
||||
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() {
|
||||
$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) {
|
||||
//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() {
|
||||
//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() {
|
||||
//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() {
|
||||
//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) {
|
||||
echo ($text['description-upgrade_services'] ?? "")."\n";
|
||||
@@ -423,8 +471,11 @@ function do_upgrade_services($text, settings $settings) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service name
|
||||
* @param string $file
|
||||
* Retrieves the name of a service from an .ini 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) {
|
||||
$parsed = parse_ini_file($file);
|
||||
@@ -438,19 +489,22 @@ function get_service_name(string $file) {
|
||||
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 {
|
||||
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) {
|
||||
echo ($text['description-restart_services'] ?? "")."\n";
|
||||
@@ -465,8 +519,13 @@ function do_restart_services($text, settings $settings) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the old config.php file
|
||||
* @return type
|
||||
* Loads configuration from a PHP file and writes it to a new configuration file.
|
||||
*
|
||||
* 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() {
|
||||
//if the config file doesn't exist and the config.php does exist use it to write a new config file
|
||||
|
||||
@@ -37,18 +37,22 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
@@ -62,9 +66,12 @@
|
||||
private $toggle_values;
|
||||
private $location;
|
||||
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -82,7 +89,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* add user_logs
|
||||
* Adds a new log entry to the database.
|
||||
*
|
||||
* This method creates a database object, prepares an array of data for insertion,
|
||||
* saves the data, and removes any temporary permissions created during the process.
|
||||
*
|
||||
* @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 = '') {
|
||||
|
||||
@@ -103,8 +116,7 @@
|
||||
$array['user_logs'][0]["type"] = 'login';
|
||||
if ($result["authorized"]) {
|
||||
$array['user_logs'][0]["result"] = 'success';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$array['user_logs'][0]["result"] = 'failure';
|
||||
$array['user_logs'][0]["detail"] = $details;
|
||||
}
|
||||
@@ -122,7 +134,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete rows from the database
|
||||
* 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->name . '_delete')) {
|
||||
|
||||
@@ -35,18 +35,22 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
@@ -67,7 +71,11 @@
|
||||
public $user_uuid;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -86,7 +94,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete 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')) {
|
||||
@@ -130,7 +144,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle 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')) {
|
||||
|
||||
@@ -37,18 +37,22 @@
|
||||
|
||||
/**
|
||||
* Set in the constructor. Must be a database object and cannot be null.
|
||||
*
|
||||
* @var database Database Object
|
||||
*/
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Settings object set in the constructor. Must be a settings object and cannot be null.
|
||||
*
|
||||
* @var settings Settings Object
|
||||
*/
|
||||
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
|
||||
* in the session global array
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain_uuid;
|
||||
@@ -63,7 +67,11 @@
|
||||
private $location;
|
||||
|
||||
/**
|
||||
* called when the object is created
|
||||
* 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
|
||||
@@ -81,7 +89,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* delete rows from the database
|
||||
* 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->name . '_delete')) {
|
||||
@@ -115,8 +129,7 @@
|
||||
$parameters['user_uuid'] = $user_uuid;
|
||||
$domain_uuid = $this->database->select($sql, $parameters, 'column');
|
||||
unset($sql, $parameters);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$domain_uuid = $this->domain_uuid;
|
||||
}
|
||||
|
||||
@@ -170,7 +183,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle a field between two values
|
||||
* 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')) {
|
||||
@@ -234,7 +253,13 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* copy rows from the database
|
||||
* 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')) {
|
||||
@@ -307,7 +332,9 @@
|
||||
|
||||
/**
|
||||
* Remove old user log entries. Called the maintenance service application.
|
||||
*
|
||||
* @param settings $settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function database_maintenance(settings $settings): void {
|
||||
|
||||
@@ -38,18 +38,6 @@
|
||||
$language = new text;
|
||||
$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
|
||||
$action = $_POST["action"] ?? '';
|
||||
$from_row = $_POST["from_row"] ?? '';
|
||||
@@ -220,6 +208,14 @@
|
||||
}
|
||||
|
||||
//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) {
|
||||
foreach ($schema as $row) {
|
||||
if ($row['table'] == $table_name) {
|
||||
|
||||
@@ -29,19 +29,22 @@
|
||||
/**
|
||||
* A base message for communication
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
* @param string $payload ;
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class base_message {
|
||||
|
||||
/**
|
||||
* The id is contained to the base_message class. Subclasses or child classes should not adjust this value
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Payload can be any value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $payload;
|
||||
@@ -51,6 +54,7 @@ class base_message {
|
||||
* 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
|
||||
* for the value of the property in the object.
|
||||
*
|
||||
* @param array $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 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.
|
||||
*
|
||||
* @param string $name Name of the property
|
||||
*
|
||||
* @return mixed
|
||||
* @throws InvalidProperty
|
||||
*/
|
||||
@@ -90,8 +96,10 @@ class base_message {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
@@ -124,6 +132,7 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Provides a method that PHP will call if the object is echoed or printed.
|
||||
*
|
||||
* @return string JSON string representing the object
|
||||
* @depends to_json
|
||||
*/
|
||||
@@ -133,6 +142,7 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Returns this object ID given by PHP
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id(): int {
|
||||
@@ -141,7 +151,9 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Sets the message payload to be delivered
|
||||
*
|
||||
* @param mixed $payload Payload for the message to carry
|
||||
*
|
||||
* @return $this Returns this object for chaining
|
||||
*/
|
||||
public function set_payload($payload) {
|
||||
@@ -151,6 +163,7 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Returns the payload contained in this message
|
||||
*
|
||||
* @return mixed Payload in the message
|
||||
*/
|
||||
public function get_payload() {
|
||||
@@ -164,8 +177,11 @@ class base_message {
|
||||
* the method is called with no parameters given, the payload is
|
||||
* returned to the caller.
|
||||
* Payload the message object is delivering
|
||||
*
|
||||
* @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 get_payload
|
||||
*/
|
||||
@@ -178,7 +194,9 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Recursively convert this object or child object to an array.
|
||||
*
|
||||
* @param mixed $iterate Private value to be set while iterating over the object properties
|
||||
*
|
||||
* @return array Array representing the properties of this object
|
||||
*/
|
||||
public function to_array($iterate = null): array {
|
||||
@@ -201,6 +219,7 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Returns a json string
|
||||
*
|
||||
* @return string
|
||||
* @depends to_array
|
||||
*/
|
||||
@@ -210,6 +229,7 @@ class base_message {
|
||||
|
||||
/**
|
||||
* Returns an array representing this object or child object.
|
||||
*
|
||||
* @return array Array of object properties
|
||||
*/
|
||||
public function __toArray(): array {
|
||||
|
||||
@@ -12,12 +12,14 @@ abstract class base_websocket_system_service extends service implements websocke
|
||||
|
||||
/**
|
||||
* Sets a time to fire the on_timer function
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $timer_expire_time = null;
|
||||
|
||||
/**
|
||||
* Websocket client
|
||||
*
|
||||
* @var websocket_client $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
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $topics;
|
||||
@@ -35,17 +38,25 @@ 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,
|
||||
* 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.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listeners;
|
||||
|
||||
/**
|
||||
* Outputs the version of the Service.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function display_version(): void {
|
||||
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
|
||||
*
|
||||
* @param int $seconds
|
||||
*
|
||||
* @return void
|
||||
* @see on_timer
|
||||
*/
|
||||
@@ -53,6 +64,11 @@ abstract class base_websocket_system_service extends service implements websocke
|
||||
$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() {
|
||||
parent::append_command_option(
|
||||
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 {
|
||||
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 {
|
||||
self::$websocket_host = $host;
|
||||
}
|
||||
@@ -87,12 +113,18 @@ abstract class base_websocket_system_service extends service implements websocke
|
||||
*
|
||||
* @param $socket
|
||||
* @param callable $callback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function add_listener($socket, callable $callback): void {
|
||||
$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 {
|
||||
// set the timers property as an array
|
||||
$this->timers = [];
|
||||
@@ -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
|
||||
*
|
||||
* @return bool True if connected and False if not able to connect
|
||||
*/
|
||||
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
|
||||
* @param resource $ws_client
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function handle_websocket_event() {
|
||||
@@ -257,6 +290,7 @@ abstract class base_websocket_system_service extends service implements websocke
|
||||
|
||||
/**
|
||||
* Call each of the registered events for the websocket topic that has arrived
|
||||
*
|
||||
* @param string $topic
|
||||
* @param 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) {
|
||||
$this->info("Authenticating with websocket server");
|
||||
// Create a service token
|
||||
@@ -283,6 +322,7 @@ 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
|
||||
*
|
||||
* @param string $topic
|
||||
* @param callable $callable
|
||||
*/
|
||||
@@ -293,9 +333,19 @@ abstract class base_websocket_system_service extends service implements websocke
|
||||
$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 {
|
||||
websocket_client::send($this->ws_client->socket(), $websocket_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register topics and associated callbacks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function register_topics(): void;
|
||||
}
|
||||
|
||||
@@ -36,11 +36,25 @@ class permission_filter implements filter {
|
||||
private $field_map;
|
||||
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 = []) {
|
||||
$this->field_map = $event_field_key_to_permission_map;
|
||||
$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 {
|
||||
$permission = $this->field_map[$key] ?? null;
|
||||
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
|
||||
*/
|
||||
public function add_permissions(array $permissions) {
|
||||
@@ -62,6 +78,7 @@ class permission_filter implements filter {
|
||||
|
||||
/**
|
||||
* Adds a single permission
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function add_permission(string $key) {
|
||||
@@ -70,7 +87,9 @@ class permission_filter implements filter {
|
||||
|
||||
/**
|
||||
* Checks if the filter has a permission
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_permission(string $key): bool {
|
||||
|
||||
@@ -33,6 +33,17 @@
|
||||
*/
|
||||
class socket_exception extends \Exception {
|
||||
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) {
|
||||
$this->id = $id;
|
||||
return parent::__construct($message, $code, $previous);
|
||||
|
||||
@@ -30,12 +30,14 @@ declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Description of subscriber
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class subscriber {
|
||||
|
||||
/**
|
||||
* The ID of the object given by PHP
|
||||
*
|
||||
* @var spl_object_id
|
||||
*/
|
||||
private $id;
|
||||
@@ -51,128 +53,151 @@ class subscriber {
|
||||
* 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
|
||||
* method to test for equality.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $socket_id;
|
||||
|
||||
/**
|
||||
* Remote IP of the socket resource connection
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $remote_ip;
|
||||
|
||||
/**
|
||||
* Remote port of the socket resource connection
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $remote_port;
|
||||
|
||||
/**
|
||||
* Services the subscriber has subscribed to
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $services;
|
||||
|
||||
/**
|
||||
* Permissions array of the subscriber
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $permissions;
|
||||
|
||||
/**
|
||||
* Domain name the subscriber belongs to
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $domain_name;
|
||||
|
||||
/**
|
||||
* Domain UUID the subscriber belongs to
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $domain_uuid;
|
||||
|
||||
/**
|
||||
* Token hash used to validate this subscriber
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $token_hash;
|
||||
|
||||
/**
|
||||
* Token name used to validate this subscriber
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $token_name;
|
||||
|
||||
/**
|
||||
* Epoch time the token was issued
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $token_time;
|
||||
|
||||
/**
|
||||
* Time limit in seconds
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $token_limit;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private $enable_token_time_limit;
|
||||
|
||||
/**
|
||||
* Whether the subscriber is able to broadcast messages as a service
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $service;
|
||||
|
||||
/**
|
||||
* The name of the service class object to handle callbacks
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $service_class;
|
||||
|
||||
/**
|
||||
* If the subscriber is a service the service name used
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $service_name;
|
||||
|
||||
/**
|
||||
* The filter used to send web socket messages
|
||||
*
|
||||
* @var filter
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* Function or method name to call when sending information through the socket
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
private $callback;
|
||||
|
||||
/**
|
||||
* Subscriptions to services
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $subscriptions;
|
||||
|
||||
/**
|
||||
* Whether or not this subscriber has been authenticated
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $authenticated;
|
||||
|
||||
/**
|
||||
* User information
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* 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 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 \InvalidArgumentException Thrown when the $callback is not a valid callback
|
||||
*/
|
||||
@@ -215,6 +240,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Returns the user array information in this subscriber
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_user_array(): array {
|
||||
@@ -222,18 +248,23 @@ class subscriber {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user information from the provided key.
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
* Retrieves a user setting by its key.
|
||||
*
|
||||
* @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) {
|
||||
return $this->user[$key] ?? $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the subscribed to services
|
||||
* @param array $services
|
||||
* @return $this|array
|
||||
* Checks if this subscriber is subscribed to the given services
|
||||
*
|
||||
* @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 = []) {
|
||||
if (func_num_args() > 0) {
|
||||
@@ -245,7 +276,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Gets or sets the service class name for this subscriber
|
||||
* @param string $service_class
|
||||
*
|
||||
* @param ?string $service_class
|
||||
*
|
||||
* @return $this|string
|
||||
*/
|
||||
public function service_class($service_class = null) {
|
||||
@@ -258,7 +291,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Sets the filter used for this subscriber
|
||||
*
|
||||
* @param filter $filter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_filter(filter $filter) {
|
||||
@@ -268,6 +303,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Returns the filter used for this subscriber
|
||||
*
|
||||
* @return filter
|
||||
*/
|
||||
public function get_filter() {
|
||||
@@ -284,6 +320,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Disconnects the socket resource used for this subscriber
|
||||
*
|
||||
* @return bool true on success and false on failure
|
||||
*/
|
||||
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
|
||||
* @param subscriber|resource $object_or_resource_or_id
|
||||
* @return bool
|
||||
* Checks if this subscriber is equal to the given object, resource or id.
|
||||
*
|
||||
* @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 {
|
||||
// Compare by resource
|
||||
@@ -322,7 +361,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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.
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @param string $name The name of the attribute to be accessed
|
||||
*
|
||||
* @throws \InvalidArgumentException If the attribute does not exist or direct access is prohibited
|
||||
*/
|
||||
public function __get(string $name) {
|
||||
switch ($name) {
|
||||
@@ -357,6 +399,7 @@ class subscriber {
|
||||
/**
|
||||
* Returns the current ID of this subscriber.
|
||||
* The ID is set in the constructor using the spl_object_id given by PHP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id(): string {
|
||||
@@ -365,7 +408,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function has_permission(string $permission): bool {
|
||||
@@ -378,6 +423,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Returns the array of permissions this subscriber has been assigned.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_permissions(): array {
|
||||
@@ -388,6 +434,7 @@ class subscriber {
|
||||
* Returns the domain name used.
|
||||
* <p>Note:<br>
|
||||
* This value is not validated in the object and must be validated.</p>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_domain_name(): string {
|
||||
@@ -395,8 +442,9 @@ class subscriber {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current socket resource used to communicate with this subscriber
|
||||
* @return resource|stream Resource Id or stream used
|
||||
* Returns the associated socket
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function 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.
|
||||
*
|
||||
* @return int The socket ID cast as an integer.
|
||||
*/
|
||||
public function socket_id(): int {
|
||||
@@ -412,7 +461,9 @@ class 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.
|
||||
*
|
||||
* @return 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
|
||||
* 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.
|
||||
*
|
||||
* @param array $request_token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate_token(array $request_token): bool {
|
||||
@@ -565,6 +618,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Returns whether or not this subscriber has been authenticated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_authenticated(): bool {
|
||||
@@ -573,7 +627,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Allows overriding the token authentication
|
||||
*
|
||||
* @param bool $authenticated
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function set_authenticated(bool $authenticated): self {
|
||||
@@ -583,8 +639,10 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Sets the domain UUID and name
|
||||
*
|
||||
* @param string $uuid
|
||||
* @param string $name
|
||||
*
|
||||
* @return self
|
||||
* @throws invalid_uuid_exception
|
||||
* @depends is_uuid()
|
||||
@@ -602,6 +660,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function is_service(): bool {
|
||||
@@ -610,6 +669,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Alias of service_name without the parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_service_name(): string {
|
||||
@@ -618,7 +678,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Get or set the service_name
|
||||
*
|
||||
* @param string|null $service_name
|
||||
*
|
||||
* @return string|$this
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @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
|
||||
* 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).
|
||||
*
|
||||
* @return bool Returns true if connected and false if the connection has closed
|
||||
*/
|
||||
public function is_connected(): bool {
|
||||
@@ -649,6 +714,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
@@ -657,7 +723,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Checks if this subscriber is subscribed to the given service name
|
||||
*
|
||||
* @param string $service_name The service name ie. active.calls
|
||||
*
|
||||
* @return bool
|
||||
* @see subscriber::subscribe
|
||||
*/
|
||||
@@ -667,7 +735,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Subscribe to a service by ensuring this subscriber has the appropriate permissions
|
||||
*
|
||||
* @param string $service_name
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function send(string $json) {
|
||||
@@ -691,7 +763,9 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Sends the given message through the websocket
|
||||
*
|
||||
* @param websocket_message $message
|
||||
*
|
||||
* @throws socket_disconnected_exception
|
||||
*/
|
||||
public function send_message(websocket_message $message) {
|
||||
@@ -723,10 +797,14 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* The remote information is retrieved using the stream_socket_get_name function.
|
||||
*
|
||||
* @param resource $socket
|
||||
* @return array Returns a zero-based indexed array of first the IP address and then the port of the remote machine.
|
||||
*
|
||||
* @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();
|
||||
* @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_information_from_socket($socket): array {
|
||||
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.
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @return string Returns the IP address of the remote machine or an empty string.
|
||||
* @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 {
|
||||
$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.
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @return string Returns the port of the remote machine as a string or an empty string.
|
||||
* @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 {
|
||||
$array = explode(':', stream_socket_get_name($socket, true), 2);
|
||||
@@ -760,10 +844,13 @@ class subscriber {
|
||||
* 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
|
||||
* sys_get_temp_dir() function is called to get a storage location.
|
||||
*
|
||||
* @param string $token_name
|
||||
*
|
||||
* @return string
|
||||
* @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 {
|
||||
// Try to store in RAM first
|
||||
@@ -790,6 +877,7 @@ class subscriber {
|
||||
* @param array $token Standard token issued from the token object
|
||||
* @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
|
||||
*
|
||||
* @see token::create()
|
||||
*/
|
||||
public static function save_token(array $token, array $services, int $time_limit_in_minutes = 0) {
|
||||
@@ -839,6 +927,7 @@ class subscriber {
|
||||
|
||||
/**
|
||||
* Checks the token time stored in this subscriber
|
||||
*
|
||||
* @return bool True if the token has expired. False if the token is still valid
|
||||
*/
|
||||
public function token_time_exceeded(): bool {
|
||||
|
||||
@@ -33,6 +33,17 @@
|
||||
*/
|
||||
class subscriber_exception extends \Exception {
|
||||
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) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->subscriber_id = $subscriber_id;
|
||||
|
||||
@@ -32,6 +32,16 @@
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
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) {
|
||||
return parent::__construct($subscriber_id, $message, $code, $previous);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
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) {
|
||||
parent::__construct($subscriber_id, $message, $code, $previous);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,19 @@
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
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) {
|
||||
return parent::__construct($subscriber_id, $message, $code, $previous);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
if ($this->is_connected())
|
||||
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() {
|
||||
$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() {
|
||||
$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 {
|
||||
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 {
|
||||
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.
|
||||
* The web socket client wraps the payload in a web frame socket before sending on the socket.
|
||||
*
|
||||
* @param $resource
|
||||
* @param string|null $payload
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Random\RandomException
|
||||
* @throws \socket_disconnected_exception
|
||||
*/
|
||||
public static function send($resource, ?string $payload): bool {
|
||||
if (!is_resource($resource)) {
|
||||
@@ -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 {
|
||||
// Try to store in RAM first
|
||||
if (is_dir('/dev/shm') && is_writable('/dev/shm')) {
|
||||
@@ -221,6 +268,16 @@ class websocket_client {
|
||||
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 {
|
||||
$header = chr(0x80 | $opcode); // FIN=1, control frame
|
||||
$payload_len = strlen($payload);
|
||||
@@ -241,7 +298,9 @@ class websocket_client {
|
||||
|
||||
/**
|
||||
* Reads a web socket data frame and converts it to a regular string
|
||||
*
|
||||
* @param resource $this ->resource
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read(): ?string {
|
||||
@@ -335,6 +394,14 @@ class websocket_client {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
$data = '';
|
||||
$max_chunk_size = stream_get_chunk_size($this->resource);
|
||||
@@ -376,16 +443,26 @@ class websocket_client {
|
||||
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) {
|
||||
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
|
||||
*
|
||||
* @param string $service_name
|
||||
* @param string $service_class
|
||||
* @param array $permissions
|
||||
* @param int $time_limit_in_minutes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function create_service_token(string $service_name, string $service_class, array $permissions = [], int $time_limit_in_minutes = 0) {
|
||||
@@ -441,6 +518,14 @@ class websocket_client {
|
||||
|
||||
// PHP <=7.4 compatibility - Replaced in PHP 8.0+
|
||||
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 {
|
||||
// For PHP versions lower then 8 we send the maximum size defined from https://php.net/stream_get_chunk_size
|
||||
return 8192;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
/**
|
||||
* A structured web socket message easily converted to and from a json string
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
* @param string $service_name ;
|
||||
* @param string $token_name ;
|
||||
* @param string $token_hash ;
|
||||
@@ -40,6 +39,8 @@
|
||||
* @param string $domain_uuid ;
|
||||
* @param string $permissions ;
|
||||
* @param string $topic ;
|
||||
*
|
||||
* @author Tim Fry <tim@fusionpbx.com>
|
||||
*/
|
||||
class websocket_message extends base_message {
|
||||
|
||||
@@ -75,13 +76,22 @@ class websocket_message extends base_message {
|
||||
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) {
|
||||
return isset($this->permissions[$permission_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of service_name.
|
||||
*
|
||||
* @param string $service_name
|
||||
*
|
||||
* @return $this
|
||||
* @see service_name
|
||||
*/
|
||||
@@ -97,7 +107,9 @@ class websocket_message extends base_message {
|
||||
* 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
|
||||
* service_name is set to the value provided.
|
||||
*
|
||||
* @param string $service_name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function service_name($service_name = null) {
|
||||
@@ -110,7 +122,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the permissions array
|
||||
*
|
||||
* @param array $permissions
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function permissions($permissions = []) {
|
||||
@@ -124,6 +138,7 @@ class websocket_message extends base_message {
|
||||
/**
|
||||
* Applies a filter to the payload of this message.
|
||||
* When a filter returns null then the payload is set to null
|
||||
*
|
||||
* @param filter $filter
|
||||
*/
|
||||
public function apply_filter(?filter $filter) {
|
||||
@@ -134,8 +149,7 @@ class websocket_message extends base_message {
|
||||
if ($result === null) {
|
||||
$this->payload = null;
|
||||
return;
|
||||
}
|
||||
// Remove a key if filter does not pass
|
||||
} // Remove a key if filter does not pass
|
||||
elseif (!$result) {
|
||||
unset($this->payload[$key]);
|
||||
}
|
||||
@@ -145,7 +159,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the domain UUID
|
||||
*
|
||||
* @param string $domain_uuid
|
||||
*
|
||||
* @return $this or $domain_uuid
|
||||
*/
|
||||
public function domain_uuid($domain_uuid = '') {
|
||||
@@ -158,7 +174,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the domain name
|
||||
*
|
||||
* @param string $domain_name
|
||||
*
|
||||
* @return $this or $domain_name
|
||||
*/
|
||||
public function domain_name($domain_name = '') {
|
||||
@@ -173,7 +191,9 @@ class websocket_message extends base_message {
|
||||
* 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
|
||||
* topic is set to the value provided.
|
||||
*
|
||||
* @param string $topic
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
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'
|
||||
*
|
||||
* @param array $token_array
|
||||
*
|
||||
* @return array|$this
|
||||
* @see token_name
|
||||
* @see token_hash
|
||||
@@ -201,7 +223,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Sets the token name
|
||||
*
|
||||
* @param string $token_name
|
||||
*
|
||||
* @return $this
|
||||
* @see token_hash
|
||||
*/
|
||||
@@ -215,7 +239,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the status code of this message
|
||||
*
|
||||
* @param int $status_code
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function status_code($status_code = '') {
|
||||
@@ -228,7 +254,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the resource id
|
||||
* @param type $resource_id
|
||||
*
|
||||
* @param mixed $resource_id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resource_id($resource_id = null) {
|
||||
@@ -241,7 +269,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the request ID
|
||||
* @param type $request_id
|
||||
*
|
||||
* @param string $request_id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function request_id($request_id = null) {
|
||||
@@ -254,7 +284,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the status string
|
||||
* @param type $status_string
|
||||
*
|
||||
* @param string $status_string
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function status_string($status_string = null) {
|
||||
@@ -267,7 +299,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Gets or sets the token hash
|
||||
* @param type $token_hash
|
||||
*
|
||||
* @param string $token_hash
|
||||
*
|
||||
* @return $this
|
||||
* @see token_name
|
||||
*/
|
||||
@@ -281,8 +315,10 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* 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 = '') {
|
||||
return $this->status_string($status_string);
|
||||
@@ -290,7 +326,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Convert the 'statusCode' key that comes from javascript
|
||||
* @param type $status_code
|
||||
*
|
||||
* @param string $status_code
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function statusCode($status_code = 200) {
|
||||
@@ -299,7 +337,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Unwrap a JSON message to an associative array
|
||||
*
|
||||
* @param string $json_string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function unwrap($json_string = '') {
|
||||
@@ -308,7 +348,9 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Helper function to respond with a connected message
|
||||
*
|
||||
* @param string|int $request_id
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @param string|int $request_id
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @param string|int $request_id
|
||||
* @param string $service
|
||||
* @param string $topic
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function request_is_bad($request_id = '', string $service = '', string $topic = ''): string {
|
||||
@@ -352,9 +398,11 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Helper function to respond with an authenticated message
|
||||
*
|
||||
* @param string|int $request_id
|
||||
* @param string $service
|
||||
* @param string $topic
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function request_authenticated($request_id = '', string $service = '', string $topic = 'authenticated'): string {
|
||||
@@ -371,9 +419,11 @@ class websocket_message extends base_message {
|
||||
|
||||
/**
|
||||
* Helper function to respond with an unauthorized request message
|
||||
*
|
||||
* @param string|int $request_id
|
||||
* @param string $service
|
||||
* @param string $topic
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @param string|int $request_id
|
||||
* @param string $service
|
||||
* @param string $topic
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @param string|array $websocket_message_json JSON array or JSON string
|
||||
*
|
||||
* @return static|null Returns a new websocket_message object (or child object)
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
||||
@@ -40,60 +40,70 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Address to bind to. (Default 8080)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $address;
|
||||
|
||||
/**
|
||||
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* Tracks if the server is running
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $running;
|
||||
|
||||
/**
|
||||
* Resource or stream of the server socket binding
|
||||
*
|
||||
* @var resource|stream
|
||||
*/
|
||||
protected $server_socket;
|
||||
|
||||
/**
|
||||
* List of connected client sockets
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $clients;
|
||||
|
||||
/**
|
||||
* Used to track on_message events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $message_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track on_connect events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $connect_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track on_disconnect events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $disconnect_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track switch listeners or other socket connection types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $listeners;
|
||||
|
||||
/**
|
||||
* Creates a websocket_server instance
|
||||
*
|
||||
* @param string $address IP to bind (default 0.0.0.0)
|
||||
* @param int $port TCP port (default 8080)
|
||||
*/
|
||||
@@ -110,24 +120,53 @@ class websocket_server {
|
||||
$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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
self::log($message, LOG_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts server: accepts new clients, reads frames, and broadcasts messages.
|
||||
*
|
||||
* @returns int A non-zero indicates an abnormal termination
|
||||
*/
|
||||
public function run(): int {
|
||||
@@ -194,12 +233,15 @@ class websocket_server {
|
||||
$this->trigger_message($client_socket, $message);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a non-blocking socket to listen for traffic on
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param callable $on_data_ready_callback Callable function to call when data arrives on the socket
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @return 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.
|
||||
* Multiple on_message functions can be specified.
|
||||
*
|
||||
* @param callable $on_message_callback Callable function to call when data arrives on the socket
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function on_message(callable $on_message_callback) {
|
||||
@@ -232,8 +277,10 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Calls all the on_message functions
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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.
|
||||
* Multiple on_connect functions can be specified.
|
||||
*
|
||||
* @param callable $on_connect_callback Callable function to call when a new connection occurs.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function on_connect(callable $on_connect_callback) {
|
||||
@@ -261,7 +310,10 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Calls all the on_connect functions
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @throws \socket_disconnected_exception
|
||||
*/
|
||||
private function trigger_connect($socket) {
|
||||
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.
|
||||
* 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
|
||||
*/
|
||||
public function on_disconnect($on_disconnect_callback) {
|
||||
@@ -287,7 +343,8 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Calls all the on_disconnect_callback functions
|
||||
* @param type $socket
|
||||
*
|
||||
* @param resource $socket
|
||||
*/
|
||||
private function trigger_disconnect($socket) {
|
||||
foreach ($this->disconnect_callbacks as $callback) {
|
||||
@@ -297,6 +354,7 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Returns the socket used in the server connection
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function get_socket() {
|
||||
@@ -304,15 +362,19 @@ class websocket_server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a client socket on disconnect.
|
||||
* @return bool Returns true on client disconnect and false when the client is not found in the tracking array
|
||||
* Disconnect a client from the server.
|
||||
*
|
||||
* @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);
|
||||
if ($index !== false) {
|
||||
self::disconnect($resource);
|
||||
unset($this->clients[$index]);
|
||||
$this->trigger_disconnect($socket);
|
||||
$this->trigger_disconnect($resource);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -320,7 +382,8 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Sends a disconnect frame with no payload
|
||||
* @param type $resource
|
||||
*
|
||||
* @param resource $resource
|
||||
*/
|
||||
public static function disconnect($resource) {
|
||||
if (is_resource($resource)) {
|
||||
@@ -332,7 +395,8 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
// ensure blocking to read full header
|
||||
@@ -360,8 +424,10 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Read specific number of bytes from a web socket
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function read_bytes($socket, int $length): string {
|
||||
@@ -379,10 +445,12 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Reads a web socket data frame and converts it to a regular string
|
||||
*
|
||||
* @param resource $socket
|
||||
* @return string
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function receive_frame($socket): string {
|
||||
private function receive_frame($socket): ?string {
|
||||
if (!is_resource($socket)) {
|
||||
throw new \RuntimeException("Not connected");
|
||||
}
|
||||
@@ -480,8 +548,11 @@ class websocket_server {
|
||||
/**
|
||||
* Send text frame to client. If the socket connection is not a valid resource, the send
|
||||
* 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 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.
|
||||
*/
|
||||
public static function send($resource, ?string $payload): bool {
|
||||
@@ -542,7 +613,9 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Get the IP and port of the connected remote system.
|
||||
*
|
||||
* @param socket $socket The socket stream of the connection
|
||||
*
|
||||
* @return array An associative array of remote_ip and remote_port
|
||||
*/
|
||||
public static function get_remote_info($socket): array {
|
||||
@@ -552,6 +625,7 @@ class websocket_server {
|
||||
|
||||
/**
|
||||
* Print socket information
|
||||
*
|
||||
* @param resource $resource
|
||||
* @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.
|
||||
|
||||
@@ -35,48 +35,56 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Address to bind to. (Default 8080)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $ip;
|
||||
|
||||
/**
|
||||
* Port to bind to. (Default 0.0.0.0 - all PHP detected IP addresses of the system)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* Resource or stream of the server socket binding
|
||||
*
|
||||
* @var resource|stream
|
||||
*/
|
||||
protected $server_socket;
|
||||
|
||||
/**
|
||||
* List of connected client sockets
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $clients;
|
||||
|
||||
/**
|
||||
* Used to track on_message events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $message_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track on_connect events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $connect_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track on_disconnect events
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $disconnect_callbacks;
|
||||
|
||||
/**
|
||||
* Used to track switch listeners or other socket connection types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listeners;
|
||||
@@ -84,12 +92,14 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Subscriber Objects
|
||||
*
|
||||
* @var subscriber
|
||||
*/
|
||||
protected $subscribers;
|
||||
|
||||
/**
|
||||
* Array of registered services
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $services;
|
||||
@@ -100,6 +110,7 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Reload settings
|
||||
*
|
||||
* @return void
|
||||
* @throws \RuntimeException
|
||||
* @access protected
|
||||
@@ -134,6 +145,7 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Display the version on the console
|
||||
*
|
||||
* @return void
|
||||
* @access protected
|
||||
*/
|
||||
@@ -143,6 +155,7 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Set extra command options from the command line
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
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 {
|
||||
$subscriber = null;
|
||||
// Get the subscriber based on their socket ID
|
||||
@@ -182,6 +202,16 @@ class websocket_service extends service {
|
||||
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) {
|
||||
$this->info("Authenticating client: $subscriber->id");
|
||||
|
||||
@@ -227,6 +257,14 @@ class websocket_service extends service {
|
||||
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) {
|
||||
|
||||
$this->debug("Processing Broadcast");
|
||||
@@ -268,8 +306,7 @@ class websocket_service extends service {
|
||||
$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 {
|
||||
// Get the subscriber object hash
|
||||
$object_id = $message->resource_id;
|
||||
@@ -288,9 +325,11 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Filters subscribers based on the service name given
|
||||
*
|
||||
* @param array $subscribers
|
||||
* @param websocket_message $message
|
||||
* @param string $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 {
|
||||
@@ -313,7 +352,9 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Create a subscriber for each connection
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function handle_connect($socket) {
|
||||
@@ -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
|
||||
*
|
||||
* @param subscriber|resource|int|string $object_or_resource_or_id
|
||||
*/
|
||||
private function handle_disconnect($object_or_resource_or_id) {
|
||||
@@ -377,6 +419,7 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* When a message event occurs, send to all the subscribers
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param mixed $data
|
||||
*/
|
||||
@@ -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) {
|
||||
//find the service with that name
|
||||
foreach ($this->subscribers as $service) {
|
||||
@@ -465,6 +516,7 @@ class websocket_service extends service {
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return int
|
||||
* @throws \RuntimeException
|
||||
* @throws socket_exception
|
||||
@@ -595,10 +647,12 @@ class websocket_service extends service {
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the parent class to shutdown all sockets
|
||||
*
|
||||
* @override service
|
||||
*/
|
||||
public function __destruct() {
|
||||
@@ -610,12 +664,18 @@ class websocket_service extends service {
|
||||
parent::__destruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array of open sockets.
|
||||
*
|
||||
* @return array An array containing open socket connections.
|
||||
*/
|
||||
public function get_open_sockets(): array {
|
||||
return $this->clients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are connected web socket clients.
|
||||
*
|
||||
* @return 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.
|
||||
* Multiple on_message functions can be specified.
|
||||
*
|
||||
* @param callable $on_message_callback
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function on_message(callable $on_message_callback) {
|
||||
@@ -637,8 +699,10 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Calls all the on_message functions
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
* @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.
|
||||
* Multiple on_connect functions can be specified.
|
||||
*
|
||||
* @param callable $on_connect_callback
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function on_connect(callable $on_connect_callback) {
|
||||
@@ -664,7 +730,9 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Calls all the on_connect functions
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
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.
|
||||
* Multiple functions can be specified with subsequent calls
|
||||
*
|
||||
* @param string|callable $on_disconnect_callback
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function on_disconnect($on_disconnect_callback) {
|
||||
@@ -688,7 +758,9 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Calls all the on_disconnect_callback functions
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function trigger_disconnect($socket) {
|
||||
@@ -699,6 +771,7 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Returns the socket used in the server connection
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function get_socket() {
|
||||
@@ -707,7 +780,9 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Remove a client socket on disconnect.
|
||||
*
|
||||
* @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
|
||||
* @access protected
|
||||
*/
|
||||
@@ -750,6 +825,8 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Performs web socket handshake on new connection.
|
||||
*
|
||||
* @param resource $resource
|
||||
* @access protected
|
||||
*/
|
||||
protected function handshake($resource): void {
|
||||
@@ -778,8 +855,10 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Read specific number of bytes from a websocket
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param int $length
|
||||
*
|
||||
* @return 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
|
||||
*
|
||||
* @param resource $socket
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function receive_frame($socket): string {
|
||||
@@ -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
|
||||
* 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
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function send($resource, ?string $payload): bool {
|
||||
@@ -907,7 +990,9 @@ class websocket_service extends service {
|
||||
|
||||
/**
|
||||
* Get the IP and port of the connected remote system.
|
||||
*
|
||||
* @param resource $resource The resource or stream of the connection
|
||||
*
|
||||
* @return array An associative array of remote_ip and remote_port
|
||||
*/
|
||||
public static function get_remote_info($resource): array {
|
||||
|
||||
Reference in New Issue
Block a user